Cannot change hostname on raspberry pi - linux

Error writting /ect/hostname: no such file or directory
I am currently getting that error when I follow How to change raspberry pi hostname
When I type sudo nano /etc/hosts I get a blank file, and when I type sudo nano /etc/hostname I also get a blank file. I have tried to save the new hostname in /ect/hostname but I get the error above. I am not a linux user normally so I don't know what else to do.

According to raspi-config you need to do these 3 steps
Replace /etc/hostname with you new hostname
Edit /etc/hosts to replace 127.0.1.1 $CURRENT_HOSTNAME 127.0.1.1 $NEW_HOSTNAME
MUST reboot to see effect
This can be done quickly via below:
sudo raspi-config nonint do_hostname ${NEW_HOSTNAME}
sudo reboot # Must reboot to see change
This is since raspi-config is a bash script and has a noninteractive mode you can use. Of which as of now, this is what we are trying to trigger below:
do_hostname() {
if [ "$INTERACTIVE" = True ]; then
whiptail --msgbox "\
Please note: RFCs mandate that a hostname's labels \
may contain only the ASCII letters 'a' through 'z' (case-insensitive),
the digits '0' through '9', and the hyphen.
Hostname labels cannot begin or end with a hyphen.
No other symbols, punctuation characters, or blank spaces are permitted.\
" 20 70 1
fi
CURRENT_HOSTNAME=`cat /etc/hostname | tr -d " \t\n\r"`
if [ "$INTERACTIVE" = True ]; then
NEW_HOSTNAME=$(whiptail --inputbox "Please enter a hostname" 20 60 "$CURRENT_HOSTNAME" 3>&1 1>&2 2>&3)
else
NEW_HOSTNAME=$1
true
fi
if [ $? -eq 0 ]; then
echo $NEW_HOSTNAME > /etc/hostname
sed -i "s/127.0.1.1.*$CURRENT_HOSTNAME/127.0.1.1\t$NEW_HOSTNAME/g" /etc/hosts
ASK_TO_REBOOT=1
fi
}

Related

CRON on Rpi simply will not run

I am using a Raspberry pi.
I need to turn on a LED whenever I'm connected to the net and turn off the LED if the connection ever fails. I want to use a cron job running once per minute to do this.
I wrote and compiled two programs in 'C' (ledon, ledoff) that handles the GPIO pin. Those programs work.
I am logged in as 'pi'.
I used crontab -e to write the following:
*/1 * * * * /home/pi/cron_scripts/nettest
I was informed by someone that the first asterisk must have '/1' in order to run properly at the once-per-minute rate that I want. There is no space to the left of the first '/1' and one space after the '1' and each '*' thereafter.
FOR TESTING ONLY, The contents of /home/pi/cron_scripts/nettest is -
#!/bin/bash
ping -c 1 -q 8.8.8.8
if [ "$?" -eq 0 ]; then
printf "%s\n\n" "SUCCESS\n"
else
printf "%s\n\n" "FAIL\n"
fi
exit 0
I used sudo chmod +x /home/pi/cron_scripts/nettest
to make the script executable.
I will replace the printf lines with "ledon" and "ledoff" for the final version.
BUT IT WILL NOT RUN!
echo $(ping -c 1 -q 8.8.8.8)
etc.

Server not reachable within a VPN (SNX) out of a Docker container

I am working with the latest Manjaro with the kernel: x86_64 Linux 5.10.15-1-MANJARO.
I am connected to my company network via VPN.
For this I use SNX with the build version 800010003.
When I start a Docker container (Docker version 20.10.3, build 48d30b5b32) which should connect to a machine from the company network, I get the following message.
[maurice#laptop ~]$ docker run --rm alpine ping company-server
ping: bad address 'company-server'
Also using the IP from the 'company-server' doesn't work.
A ping outside the container works, no matter using the name or IP.
The resolv.conf looks correct to me.
[maurice#laptop ~]$ docker run --rm alpine cat /etc/resolv.conf
# Generated by NetworkManager
search lan
nameserver 10.1.0.250
nameserver 10.1.0.253
nameserver 192.168.86.1
What I have found out so far.
If I downgrade packages glibc and lib32-glibc to version 2.32-5, the ping out of the container works again. Because of dependencies I have also to downgrade gcc, gcc-libs and lib32-gcc-libs to version 10.2.0-4.
I tried the whole thing with a fresh Pop OS 20.10 installation, same problem.
I also did a test with another VPN (OpenVPN) which worked fine. However, this was only a test scenario and cannot be used as an alternative.
I have been looking for a solution for several days but have not found anything. It would be really nice if someone could help me with this.
TL;DR:
on kernel >5.8 the tunsnx interface is no longer created with global scope and need to be recreated. small script to the rescure https://gist.github.com/Fahl-Design/ec1e066ec2ef8160d101dff96a9b56e8
Longer version:
Here are my findings and the solution to (temp) fix it:
Steps to reproduce:
connect your snx tunnel
see ping fails to server behind tunnel
docker run --rm -ti --net=company_net busybox /bin/sh -c "ping 192.168.210.210"
run this command to check ip and scope of the "tunsnx" interface
ip -o address show "tunsnx" | awk -F ' +' '{print $4 " " $6 " " $8}'
if you get something like
192.168.210.XXX 192.168.210.30/32 247
or (Thx Timz)
192.168.210.XXX 192.168.210.30/32 nowhere
the scope is not set to "global" and no connection can be established
to fix this, like "ronan lanore" suggested, you need to change the scope to global
this can be done with a little helper script like this one:
#!/usr/bin/env bash
#
# Usage: [dry_run=1] [debug=1] [interface=tunsnx] docker-fix-snx
#
# Credits to: https://github.com/docker/for-linwux/issues/288#issuecomment-825580160
#
# Env Variables:
# interface - Defaults to tunsnx
# dry_run - Set to 1 to have a dry run, just printing out the iptables command
# debug - Set to 1 to see bash substitutions
set -eu
_log_stderr() {
echo "$*" >&2
}
if [ "${debug:=0}" = 1 ]; then
set -x
dry_run=${dry_run:=1}
fi
: ${dry_run:=0}
: ${interface:=tunsnx}
data=($(ip -o address show "$interface" | awk -F ' +' '{print $4 " " $6 " " $8}'))
LOCAL_ADDRESS_INDEX=0
PEER_ADDRESS_INDEX=1
SCOPE_INDEX=2
if [ "$dry_run" = 1 ]; then
echo "[-] DRY-RUN MODE"
fi
if [ "${data[$SCOPE_INDEX]}" == "global" ]; then
echo "[+] Interface ${interface} is already set to global scope. Skip!"
exit 0
else
echo "[+] Interface ${interface} is set to scope ${data[$SCOPE_INDEX]}."
tmpfile=$(mktemp --suffix=snxwrapper-routes)
echo "[+] Saving current IP routing table..."
if [ "$dry_run" = 0 ]; then
sudo ip route save >$tmpfile
fi
echo "[+] Deleting current interface ${interface}..."
if [ "$dry_run" = 0 ]; then
sudo ip address del ${data[$LOCAL_ADDRESS_INDEX]} peer ${data[$PEER_ADDRESS_INDEX]} dev ${interface}
fi
echo "[+] Recreating interface ${interface} with global scope..."
if [ "$dry_run" = 0 ]; then
sudo ip address add ${data[$LOCAL_ADDRESS_INDEX]} dev ${interface} peer ${data[$PEER_ADDRESS_INDEX]} scope global
fi
echo "[+] Restoring routing table..."
if [ "$dry_run" = 0 ]; then
sudo ip route restore <$tmpfile 2>/dev/null
fi
echo "[+] Cleaning temporary files..."
rm $tmpfile
echo "[+] Interface ${interface} is set to global scope. Done!"
if [ "$dry_run" = 0 ]; then
echo "[+] Result:"
ip -o address show "tunsnx" | awk -F ' +' '{print $4 " " $6 " " $8}'
fi
exit 0
fi
[ "$debug" = 1 ] && set +x
Same problem for me now. Nothing big change but tunsnx interface scope change from global to 247. Delete it and re create with global scope.
Just for collection of possible solutions. I had the same problem but found that "tunsnx" interface was configured properly with "global" keyword. In my case the problem was that snx was started after docker daemon and restarting docker service docker restart helped.

NTP permission issue

I gave everyone in my team a copy of a centos 7 virtual machine. The time can get out of sync. I found that I can manually update the time by using the command below:
[no_sudo#rolling ~]$ ntpdate pool.ntp.org
26 Apr 18:10:11 ntpdate[25928]: bind() fails: Permission denied
[no_sudo#rolling ~]$
However I can only update it as sudo. One of the commands I made for the team runs some automated testing, and uses the date.time as a name.
How can I ether automate the updating of time on the virtual machine, or alter the permissions of that service, so anyone can run it regardless or permissions.
Thanks!
"How can I ether automate the updating of time on the virtual machine"
The ntp daemon, ntpd, should take care of this. Sure it's running?
# start the ntp daemon
/etc/init.d/ntpd start
You could also add a daily or hourly entry in root's crontab that updates the time:
# To edit root's crontab
sudo crontab -e
# Add this line to run the command every day at noon (change as needed):
* 12 * * * /usr/sbin/ntpdate
"alter the permissions of that service, so anyone can run it"
This undermines the security model. However, if the users are allowed to use sudo already, you could allow password-less execution of that single executable so it won't block your script:
# To edit the sudoers file:
sudo visudo
# Then add something like this depending on the location of ntpdate:
username ALL= NOPASSWD: /usr/sbin/ntpdate
You should configure and use ntpd instead of ntpdate.
\#!/bin/sh
\#script to set the time using google - my ISP is blocking access to ntp server! major bummer!! :(
HOST="www.google.co.ke"
ping -q -c 2 $HOST > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "----\`date\`---------------------FAILURE----------------------------------"
echo "Failure: \`date\` -- $HOST is is DOWN! >>> better luck next time!"
else
echo "****\`date\`*********************BEGIN: SUCCESS*********************************"
mydateold="\`date\`"
echo "Success: \`date\` -- $HOST is UP >>> set the time!"
date -s "$(date -d "\`curl http://www.google.co.ke -v 2>&1 | grep "Date: " | awk '{ print $3 " " $5 " " $4 " " $7 " " $6 " GMT"}'\`")"
mynewdate="\`date\`"
echo "Success: \`date\` >>> Date updated: OLD DATETIME: $mydateold and NEW DATETIME:
$mynewdate"
echo "****\`date\`*********************END: SUCCESS***********************************"
fi
\#EOF
\#Powered By Slackware Linux :)

Having an issue passing variables to subshell

So here is my problem, I have this script I wrote where I'm exporting two variables however they're not making it into the subshell.
The point of this script is to change a users password and clear out their pam_tally for CentOS and Ubuntu hosts.
A little background is that this environment's users are managed by puppet but the passwords are all local, ssh keys are not allowed either (this is set in stone and can't be changed so I have to work with what I got) and the reason is that every log in has to be manual (even number of sessions are limited to two so you can't even user csshX effectively).
Here is my script
#!/bin/bash
echo "Please enter user whose password you want to change"
read NEWUSER
echo "Please enter new password for user"
read -s -p "Temp Password:" TEMPPASSWORD
PASSWORD=$TEMPPASSWORD
export PASSWORD
NEWUSER2=$NEWUSER
export NEWUSER2
for i in HOST{cluster1,cluster2,cluster3}0{1..9}
do
ping -c 2 $i && (echo $i ; ssh -t $i '
sudo pam_tally2 --user=$NEWUSER2 --reset
echo -e "$PASSWORD\n$PASSWORD" | sudo passwd $NEWUSER2
sudo chage -d 0 $NEWUSER2
')
done
You are using ssh to connect to a remote host and run a script on that host. ssh does not export the local environment to the remote session but instead performs a login on the remote host which sets the environment according to the remote user's configuration on the remote host.
I suggest you pass all needed values via the command you want to execute. This could be done like this:
ssh -t $i '
sudo pam_tally2 --user='"$NEWUSER2"' --reset
echo -e "'"$PASSWORD"'\n'"$PASSWORD"'" | sudo passwd '"$NEWUSER2"'
sudo chage -d 0 '"$NEWUSER2"
Watch closely how this uses quotes. At each occasion where you used a variable, I terminate the single-quoted string (using '), then add a double-quoted use of the variable (e. g. "$PASSWORD") and then start the single-quoted string again (using ' again). This way, the shell executing the ssh command will expand the variables already, so you have no need to pass them into the remote shell.
But be aware that special characters in the password (like " or ' or or maybe a bunch of other characters) can mean trouble using this simple mechanism. To be safe against this as well, you would need to use the %q format specifier of the printf command to quote your values before passing them:
ssh -t "$i" "$(printf '
sudo pam_tally2 --user=%q --reset
{ echo %q; echo %q; } | sudo passwd %q
sudo chage -d 0 %q' \
"$NEWUSER2" "$PASSWORD" "$PASSWORD" "$NEWUSER2" "$NEWUSER2")"

ssh script returns 255 error

In my code I have the following to run a remote script.
ssh root#host.domain.com "sh /home/user/backup_mysql.sh"
For some reason it keeps 255'ing on me. Any ideas?
I can SSH into the box just fine (passless keys setup)
REMOTE SCRIPT:
MUSER='root'
MPASS='123123'
MHOST="127.0.0.1"
VERBOSE=0
### Set bins path ###
GZIP=/bin/gzip
MYSQL=/usr/bin/mysql
MYSQLDUMP=/usr/bin/mysqldump
RM=/bin/rm
MKDIR=/bin/mkdir
MYSQLADMIN=/usr/bin/mysqladmin
GREP=/bin/grep
### Setup dump directory ###
BAKRSNROOT=/.snapshots/tmp
#####################################
### ----[ No Editing below ]------###
#####################################
### Default time format ###
TIME_FORMAT='%H_%M_%S%P'
### Make a backup ###
backup_mysql_rsnapshot(){
local DBS="$($MYSQL -u $MUSER -h $MHOST -p$MPASS -Bse 'show databases')"
local db="";
[ ! -d $BAKRSNROOT ] && ${MKDIR} -p $BAKRSNROOT
${RM} -f $BAKRSNROOT/* >/dev/null 2>&1
# [ $VERBOSE -eq 1 ] && echo "*** Dumping MySQL Database ***"
# [ $VERBOSE -eq 1 ] && echo -n "Database> "
for db in $DBS
do
local tTime=$(date +"${TIME_FORMAT}")
local FILE="${BAKRSNROOT}/${db}.${tTime}.gz"
# [ $VERBOSE -eq 1 ] && echo -n "$db.."
${MYSQLDUMP} --single-transaction -u ${MUSER} -h ${MHOST} -p${MPASS} $db | ${GZIP} -9 > $FILE
done
# [ $VERBOSE -eq 1 ] && echo ""
# [ $VERBOSE -eq 1 ] && echo "*** Backup done [ files wrote to $BAKRSNROOT] ***"
}
### Die on demand with message ###
die(){
echo "$#"
exit 999
}
### Make sure bins exists.. else die
verify_bins(){
[ ! -x $GZIP ] && die "File $GZIP does not exists. Make sure correct path is set in $0."
[ ! -x $MYSQL ] && die "File $MYSQL does not exists. Make sure correct path is set in $0."
[ ! -x $MYSQLDUMP ] && die "File $MYSQLDUMP does not exists. Make sure correct path is set in $0."
[ ! -x $RM ] && die "File $RM does not exists. Make sure correct path is set in $0."
[ ! -x $MKDIR ] && die "File $MKDIR does not exists. Make sure correct path is set in $0."
[ ! -x $MYSQLADMIN ] && die "File $MYSQLADMIN does not exists. Make sure correct path is set in $0."
[ ! -x $GREP ] && die "File $GREP does not exists. Make sure correct path is set in $0."
}
### Make sure we can connect to server ... else die
verify_mysql_connection(){
$MYSQLADMIN -u $MUSER -h $MHOST -p$MPASS ping | $GREP 'alive'>/dev/null
[ $? -eq 0 ] || die "Error: Cannot connect to MySQL Server. Make sure username and password are set correctly in $0"
}
### main ####
verify_bins
verify_mysql_connection
backup_mysql_rsnapshot
This is usually happens when the remote is down/unavailable; or the remote machine doesn't have ssh installed; or a firewall doesn't allow a connection to be established to the remote host.
ssh returns 255 when an error occurred or 255 is returned by the remote script:
EXIT STATUS
ssh exits with the exit status of the remote command or
with 255 if an error occurred.
Usually you would an error message something similar to:
ssh: connect to host host.domain.com port 22: No route to host
Or
ssh: connect to host HOSTNAME port 22: Connection refused
Check-list:
What happens if you run the ssh command directly from the command line?
Are you able to ping that machine?
Does the remote has ssh installed?
If installed, then is the ssh service running?
This error will also occur when using pdsh to hosts which are not contained in your "known_hosts" file.
I was able to correct this by SSH'ing into each host manually and accepting the question "Do you want to add this to known hosts".
If there's a problem with authentication or connection, such as not being able to read a password from the terminal, ssh will exit with 255 without being able to run your actual script. Verify to make sure you can run 'true' instead, to see if the ssh connection is established successfully.
Isn't the problem in the lines:
### Die on demand with message ###
die(){
echo "$#"
exit 999
}
Correct me if I'm wrong but I believe exit 999 is out of range for an exit code and results in a exit status of 255.
I was stumped by this. Once I got passed the 255 problem... I ended up with a mysterious error code 1. This is the foo to get that resolved:
pssh -x '-tt' -h HOSTFILELIST -P "sudo yum -y install glibc"
-P means write the output out as you go and is optional. But the -x '-tt' trick is what forces a psuedo tty to be allocated.
You can get a clue what the error code 1 means this if you try:
ssh AHOST "sudo yum -y install glibc"
You may see:
[slc#bastion-ci ~]$ ssh MYHOST "sudo yum -y install glibc"
sudo: sorry, you must have a tty to run sudo
[slc#bastion-ci ~]$ echo $?
1
Notice the return code for this is 1, which is what pssh is reporting to you.
I found this -x -tt trick here. Also note that turning on verbose mode (pssh --verbose) for these cases does nothing to help you.
It can very much be an ssh-agent issue.
Check whether there is an ssh-agent PID currently running with eval "$(ssh-agent -s)"
Check whether your identity is added with ssh-add -l and if not, add it with ssh-add <pathToYourRSAKey>.
Then try again your ssh command (or any other command that spawns ssh daemons, like autossh for example) that returned 255.
If above didn't help: check if locale is valid on client and server:
https://www.linuxbabe.com/linux-server/fix-ssh-locale-environment-variable-error
How do not pass locale through ssh
### Die on demand with message ###
die(){
echo "$#"
exit 999
}
I don't have the rep to comment on Alex's answer but the exit 999 line returns code 231 on my WSL Ubuntu 20.04.4 box. Not quite sure why that is returned but I understand that it's out of range.

Resources