How to create a bash script to check the SSH connection?
BashSshConnectionBash Problem Overview
I am in the process of creating a bash script that would log into the remote machines and create private and public keys.
My problem is that the remote machines are not very reliable, and they are not always up. I need a bash script that would check if the SSH connection is up. Before actually creating the keys for future use.
Bash Solutions
Solution 1 - Bash
You can check this with the return-value ssh gives you:
$ ssh -q user@downhost exit
$ echo $?
255
$ ssh -q user@uphost exit
$ echo $?
0
EDIT: Another approach would be to use nmap (you won't need to have keys or login-stuff):
$ a=`nmap uphost -PN -p ssh | grep open`
$ b=`nmap downhost -PN -p ssh | grep open`
$ echo $a
22/tcp open ssh
$ echo $b
(empty string)
But you'll have to grep the message (nmap does not use the return-value to show if a port was filtered, closed or open).
EDIT2:
If you're interested in the actual state of the ssh-port, you can substitute grep open
with egrep 'open|closed|filtered'
:
$ nmap host -PN -p ssh | egrep 'open|closed|filtered'
Just to be complete.
Solution 2 - Bash
You can use something like this
$(ssh -o BatchMode=yes -o ConnectTimeout=5 user@host echo ok 2>&1)
This will output "ok" if ssh connection is ok
Solution 3 - Bash
ssh -q -o "BatchMode=yes" -i /home/sicmapp/.ssh/id_rsa <ID>@<Servername>.<domain> "echo 2>&1" && echo $host SSH_OK || echo $host SSH_NOK
Solution 4 - Bash
Complementing the response of @AdriĆ Cidre
you can do:
status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 user@host echo ok 2>&1)
if [[ $status == ok ]] ; then
echo auth ok, do something
elif [[ $status == "Permission denied"* ]] ; then
echo no_auth
else
echo other_error
fi
Solution 5 - Bash
Below ssh
command should have an exit code of 0
on a successful connection and a non-zero value otherwise.
ssh -q -o BatchMode=yes [email protected] exit
if [ $? != "0" ]; then
echo "Connection failed"
fi
Solution 6 - Bash
Try:
echo quit | telnet IP 22 2>/dev/null | grep Connected
Solution 7 - Bash
Following @user156676, to check a range of ips:
#!/bin/sh
IP='192.168.0.'
PWD='your_password'
USR='your_usr'
for i in $(seq 229 255);do
sshpass -p $PWD ssh -q -o ConnectTimeout=3 ${USR}@${IP}${i} exit
let ret=$?
if [ $ret -eq 5 ]; then
echo $IP$i "Refused!" $ret
elif [ $ret -eq 255 ] ; then
echo $IP$i "Server Down!" $ret
elif [ $ret -eq 0 ] ; then
echo $IP$i "Connnected!" $ret
else
echo $IP$i "Unknown return code!" $ret
fi
done
Solution 8 - Bash
To connect to a server with multiple interfaces
ssh -o ConnectTimeout=1 -q Necktwi@192.168.1.61;[ $? = 1 ] || ssh -o ConnectTimeout=1 -q Necktwi@192.168.1.51
Solution 9 - Bash
Just in case someone only wishes to check if port 22 is open on a remote machine, this simple netcat command is useful. I used it because nmap and telnet were not available for me. Moreover, my ssh configuration uses keyboard password auth.
It is a variant of the solution proposed by GUESSWHOz.
nc -q 0 -w 1 "${remote_ip}" 22 < /dev/null &> /dev/null && echo "Port is reachable" || echo "Port is unreachable"
Solution 10 - Bash
If you would like to check a remote folder exists, or any other file-test really:
if [ -n "$(ssh "${user}@${server}" [ -d "$folder" ] && echo 1; exit)" ]; then
# exists
else
# doesn't exist
fi
Do not forget the quotes in "$(ssh ...)"
.
Solution 11 - Bash
Example Using BASH 4+ script:
# -- ip/host and res which is result of nmap (note must have nmap installed)
ip="192.168.0.1"
res=$(nmap ${ip} -PN -p ssh | grep open)
# -- if result contains open, we can reach ssh else assume failure) --
if [[ "${res}" =~ "open" ]] ;then
echo "It's Open! Let's SSH to it.."
else
echo "The host ${ip} is not accessible!"
fi
Solution 12 - Bash
https://onpyth.blogspot.com/2019/08/check-ping-connectivity-to-multiple-host.html
Above link is to create Python script for checking connectivity. You can use similar method and use:
ping -w 1 -c 1 "IP Address"
Command to create bash script.
Solution 13 - Bash
I wrote this script to check both netcat and SSH connectivity to all hosts in my servers /etc/hosts
reads /etc/hosts line by line and then tries netcat port 22, and then ssh as "sshuttle" user
quick way to check network sanity
script uses a "sshuttle" user, this is an account that has pub/priv keys on all my hosts and can ssh anywhere (non root account), we use this acct to spin up sshuttle VPN tunnels, but you can add any account that has SSH access to servers
https://gist.github.com/perfecto25/8687d563716ba4923c77162be724beda
output,
./conncheck.sh
netcat is installed, proceeding..
--------------------------------------
tm-us1 (127.0.0.1): ssh OK | nc OK
--------------------------------------
localhost (127.0.0.1): ssh OK | nc OK
--------------------------------------
atlas (192.168.142.21): ssh ERROR | nc OK
--------------------------------------
hydra (192.168.142.22): ssh OK | nc OK
--------------------------------------
nemesis (192.168.140.23): ssh OK | nc OK
--------------------------------------
vulcan (192.168.140.24): ssh OK | nc OK
--------------------------------------
athena (192.168.140.27): ssh OK | nc OK
--------------------------------------
nas1 (192.168.100.101): ssh ERROR | nc OK
--------------------------------------
tm-dev (192.10.23.71): ssh ERROR | nc ERROR
--------------------------------------
WARNING: Your password has expired.
Password change required but no TTY available.
infra01 (192.10.23.186): ssh ERROR | nc OK
--------------------------------------
ns-us1 (192.10.23.252): ssh ERROR | nc OK
--------------------------------------
ns-us2 (192.10.23.182): ssh ERROR | nc OK
--------------------------------------
proxy-us1 (192.10.23.120): ssh OK | nc OK
--------------------------------------
simtm-us1 (192.10.23.236): ssh OK | nc OK
--------------------------------------
tm-us1 (192.10.23.104): ssh OK | nc OK
--------------------------------------
tm-us2 (192.10.23.215): ssh OK | nc OK
--------------------------------------
tm-dev (192.10.23.77): ssh OK | nc OK
--------------------------------------
WARNING: Your password has expired.
Password change required but no TTY available.
tm-uat (192.10.23.225): ssh ERROR | nc OK
--------------------------------------
vpn-us1 (192.10.23.193): ssh OK | nc OK
--------------------------------------
Solution 14 - Bash
I feel like you're trying to solve the wrong problem here. Shouldn't you be trying to make the ssh daemons more stable? Try running something like monit, which will check to see if the daemon is running and restart it if it isn't (giving you time to find the root problem behind sshd shutting down on you). Or is the network service troublesome? Try looking at man ifup
. Does the Whole Damn Thing just like to shut down on you? Well, that's a bigger problem ... try looking at your logs (start with syslog) to find hardware failures or services that are shutting your boxen down (maybe a temperature monitor?).
Making your scripts fault tolerant is great, but you might also want to make your boxen fault tolerant.