Starting sshd automatically if it is down/failed - linux

I am trying to create a Bash .sh script for a cronjob that starts the OpenSSH server if it is down or failed.
Last night the SSH server was down and when I tried to access it today (from work) the connection was refused ofc.
No traces in the /var/log/messages for the failure.
So the question is - how to determine is sshd running so if it is not to "sudo service ssh start" it?
Thanks in advance!

Fellas, I believe that I have managed to do the task:
#!/bin/bash
service="ssh"
if (( ! $(sudo service ssh status | cut -d" " -f 3 | cut -d"." -f 1) == "running" ))
then
sudo /etc/init.d/ssh restart
fi
I have changed the LogLevel to Verbose, I hope the next time I will track more clues regarding the failure of the sshd.

I'm implementing the following:
[ $(sudo service ssh status | grep running | grep -v grep | wc -l) == 0 ] && sudo /etc/init.d/ssh restart

as other people said It's Incorrect to start it without finding what caused this problem, but I wrote some help for the script you want
first you should check the status of your openssh server for example:
ps -aux | grep ssh
then write an if to check if it is down or not
you can check it with the result of previous step.
if that was down, start it
sudo service ssh start

Related

Retrieving the result of a bash command run from ssh into a variable

The following command runs well when i run it localy on the dsired machine:
app_name=*some_proccess_name*
pid=`pgrep $app_name | tail -n 1`
But when i run it in the following way, from a remote pc using ssh it dosn't work:
pid=$(ssh $USER_NAME#$HOST_NAME "echo `pgrep $app_name | tail -n 1`")
The value of pid afterwards is just blank. I am not sure what's wrong (just to clarify i have tried several processes names that are all running on the target pc- that's not the problem ).
P.S when i run the command without echo, like that, i just get stuck inside the remote pc and have to use exit in order to get unstuck and return to my local pc:
pid=$(ssh tester#mir1 "`pgrep indicator-apple | tail -n 1`")
Less is more
pid=$(ssh tester#mir1 pgrep indicator-apple \| tail -n 1)

How to get the status of any service in a sh script on centos 7?

I am trying to get the service status (for a /bin/sh script) and start it if is not running.
I found some scripts, but does not work for centos 7.
There are, as usual, multiples ways to do this. Just one example, that check if postfix is running:
#!/bin/sh
PID=`cat /var/spool/postfix/pid/master.pid`
# echo $PID
PS=`/bin/ps axu | grep $PID | grep -v grep`
# echo $PS
if [ "$PS" = "" ]
then
/sbin/service postfix restart
fi
You could use "pid" file, or try to detect if process is running (parsing output of "ps axu |grep process_name"), or parse output of "service process status" command, etc, etc.

How to check if Neo4J is running on the server?

Is there any way to check whether Neo4J is running using pidof command? I tried doing
pidof /path/to/neo4j/bin/neo4j
But it didn't seem to work.
I need it to set up a script that I will then launch with cron to make sure that if the database crashes I can restart it again.
Thank you!
bin/neo4j status is the command you are looking for.
For a more general use, checking whether neo4dj is running or not, use the following command:
service neo4j-service status
In Ubuntu 16 04 I can execute the following:
sudo service neo4j status
That won't work since neo4j is being run by java command.
Here's a workaround if you want to do something by yourself:
if test -z "$(ps -A | grep neo4j)"
then
echo "no neo4j instance running"
else
echo "neo4j up and running"
fi
But since, as you may probably know, noe4j launcher already does something like that, we may just look at how it's done there:
detectrunning() {
if [ $DIST_OS = "solaris" ] ; then
## SmartOS has a different lsof command line arguments
newpid=$(lsof -o $NEO4J_SERVER_PORT | grep '::' | head -n1 | cut -d ' ' -f 1)
else
## This could be achieved with filtering using -sTCP:LISTEN but this option is not available
## on lsof v4.78 which is the one bundled with some distros. So we have to do this grep below
newpid=$(lsof -i :$NEO4J_SERVER_PORT -F T -Ts | grep -i "TST=LISTEN" -B1 | head -n1)
newpid=${newpid:1}
fi
}
This is an excerpt from the bin/neo4j script inside neo4j distribution directory.
You can use these following ways to get neo4j service status in Windows:
Powershell:
Get-Service neo4j
CMD/Powershell:
service neo4j

Is it possible to run a script which loops through hosts with rsh/ssh

I have tried to run following csh script which ssh to all computers on our network with the purpose of yum installing software passed as arguments. However, the script fails to continue once I have rsh to another host. Is there a way around this problem?
if ($1 == "")then
echo -n "Please enter a package to install\n"
set package=$<
else set package = $#argv
endif
set numlines = `cat $NM_HOME/sh_local/nc_network2.txt | grep -v "^#" | fgrep "%" | wc -l`
while ($numlines>0)
set line = `cat $NM_HOME/sh_local/nc_network2.txt | grep -v "^#" | fgrep "%" | tail -$numlines | head -1`
set host2 = `echo $line | cut -f 1 -d %`
set where = `echo $line | cut -f 2 -d %`
if ($host2 == $this_machine) then
echo "This is $host2....skipping rsh to this machine"
echo ""
goto yum
endif
echo ""
echo "logging into $host2 $where"
echo ""
sleep 1
rsh $host2
yum:
echo ""
echo "Preparing to install $package on $host2"
sudo yum -y install $package
if ($host2 == $this_machine) then
goto decrement
else
logout
goto decrement
endif
decrement:
# numlines--
end
ssh/rsh-ing to another host does not magically continue the execution of your script on that host. Executing ssh hostname in a script has the exact same effect as executing ssh hostname in your shell — it connects to that machine, runs an interactive shell there, and leaves you in that shell. Your script execution will only continue after you close the ssh/rsh connection yourself.
In order to perform some action on that host, you need to provide an explicit command you want to run on that host, like this:
rsh $host2 sudo yum -y install $package
Note that this is only a naive example for illustration purposes; it likely won't be enough to fix the entire logic of your script, but should point you in the right direction.
YES. My answer is provided below only by reading your "Question" and not what you have put up in the code that you posted.
I have been doing this for many years as below.
create a list of hosts with onehost on each line.
enable SSH key based authentication upfront. This can be done manually but I had done it in the past using perl and expect.
run a for loop as below to perform action onall the servers:
for i in cat hosts_list; do ssh $i dmidecode | grep -m 1 'Serial Number:'; done
Above oneliner will give me the serial numbers of all the servers wic are mentioned in the host_list. This a shot example of pulling serial number. however, you can write a full fledged bash script following the exact same logic.
for more advanced requirement, consider using perl and the ssh modules that are available on CPAN

How to set up an automatic (re)start of a background ssh tunnel

I am a beginner user of linux, and also quite newbie at ssh and tunnels.
Anyway, my goal is to maintain a ssh tunnel open in background.
In order to do that, I wrote the following batch that I then added into crontab (the batch is automatically processed every 5 minutes during workdays and from 8am to 9pm).
I read in some other thread in stackoverflow that one should use autossh that will ensure the ssh will always be ok through a recurrent check. So did I....
#!/bin/bash
LOGFILE="/root/Tunnel/logBatchRestart.log"
NOW="$(date +%d/%m/%Y' - '%H:%M)" # date & time of log
if ! ps ax | grep ssh | grep tunnelToto &> /dev/null
then
echo "[$NOW] ssh tunnel not running : restarting it" >> $LOGFILE
autossh -f -N -L pppp:tunnelToto:nnnnn nom-prenom#193.xxx.yyy.zzz -p qqqq
if ! ps ax | grep ssh | grep toto &> /dev/null
then
echo "[$NOW] failed starting tunnel" >> $LOGFILE
else
echo "[$NOW] restart successfull" >> $LOGFILE
fi
fi
My problem is that sometimes the tunnel stops working, although every thing looks ok (ps ax | grep ssh > the result shows the two expected tasks : autossh main task and the ssh tunnel itself). I actually know about the problem cause the tunnel is used by a third party software that triggers an error as soon as the tunnel is no more responding.
SO I am wondering how I should improve my batch in order It will be able to check the tunnel and restart it if it happens to be dead. I saw some ideas in there, but it was concluded by the "autossh" hint... which I already use. Thus, I am out of ideas... If any of you have, I'd gladly have a look at them!
Thanks for taking interest in my question, and for your (maybe) suggestions!
Instead of checking the ssh process with ps you can do the following trick
create script, that does the following and add it to your crontab via crontab -e
#!/bin/sh
REMOTEUSER=username
REMOTEHOST=remotehost
SSH_REMOTEPORT=22
SSH_LOCALPORT=10022
TUNNEL_REMOTEPORT=8080
TUNNEL_LOCALPORT=8080
createTunnel() {
/usr/bin/ssh -f -N -L$SSH_LOCALPORT:$REMOTEHOST:SSH_REMOTEPORT -L$TUNNEL_LOCALPORT:$REMOTEHOST:TUNNEL_REMOTEPORT $REMOTEUSER#$REMOTEHOST
if [[ $? -eq 0 ]]; then
echo Tunnel to $REMOTEHOST created successfully
else
echo An error occurred creating a tunnel to $REMOTEHOST RC was $?
fi
}
## Run the 'ls' command remotely. If it returns non-zero, then create a new connection
/usr/bin/ssh -p $SSH_LOCALPORT $REMOTEUSER#localhost ls >/dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo Creating new tunnel connection
createTunnel
fi
In fact, this script will open two ports
port 22 which will be used to check if the tunnel is still alive
port 8080 which is the port you might want to use
Please check and send me further questions via comments
(I add this as an answer since there is not enough room for it un a comment)
Ok, I managed to make the batch run to launch the ssh tunnel (I had to specify my hostname instead of localhost in order it could be triggered) :
#!/bin/bash
LOGFILE="/root/Tunnel/logBatchRedemarrage.log"
NOW="$(date +%d/%m/%Y' - '%H:%M)" # date et heure du log
REMOTEUSER=username
REMOTEHOST=remoteHost
SSH_REMOTEPORT=22
SSH_LOCALPORT=10022
TUNNEL_REMOTEPORT=12081
TUNNEL_SPECIFIC_REMOTE_PORT=22223
TUNNEL_LOCALPORT=8082
createTunnel() {
/usr/bin/ssh -f -N -L$SSH_LOCALPORT:$REMOTEHOST:$SSH_REMOTEPORT -L$TUNNEL_LOCALPORT:$REMOTEHOST:$TUNNEL_REMOTEPORT $REMOTEUSER#193.abc.def.ghi -p $TUNNEL_SPECIFIC_REMOTE_PORT
if [[ $? -eq 0 ]]; then
echo [$NOW] Tunnel to $REMOTEHOST created successfully >> $LOGFILE
else
echo [$NOW] An error occurred creating a tunnel to $REMOTEHOST RC was $? >> $LOGFILE
fi
}
## Run the 'ls' command remotely. If it returns non-zero, then create a new connection
/usr/bin/ssh -p $SSH_LOCALPORT $REMOTEUSER#193.abc.def.ghi ls >/dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo [$NOW] Creating new tunnel connection >> $LOGFILE
createTunnel
fi
However, I got some immediate message (below) when the tunnel is running and when cron tries to lauch the batch again... sounds like it cannot listen to it. Also since I need some time to get a proof , I can't say yet it will successfully restart if the tunnel is out.
Here's the response to the second start of the batch.
bind: Address already in use channel_setup_fwd_listener: cannot listen
to port: 10022 bind: Address already in use
channel_setup_fwd_listener: cannot listen to port: 8082 Could not
request local forwarding.

Resources