Checking if an SSH tunnel is up and running
Solution 1
Use netcat -- often nc
on Linux systems:
nc -dvzw10 ${HOSTNAME} 23
Works for me, with a response like:
Connection to ${HOSTNAME} 23 port [tcp/telnet] succeeded!
It also returns 0 on success, and is happy with a simple connection after which it goes away.
- -d means not to read anything from the keyboard side
- -v means to be verbose (turn this off in a script)
- -z means to disconnect after making the connection
- -w10 means to wait up to 10 seconds, otherwise give up
Solution 2
You can integrate a ping to your ssh server and if it works fine the ssh tunnel is up
# only a ping sample :-D
if ! ping -c 1 192.168.101.9
then
echo ":-("
else
echo ":-)"
fi
Related videos on Youtube
Comments
-
Jarmund almost 2 years
I have a perl script which, when destilled a bit, looks like this:
my $randport = int(10000 + rand(1000)); # Random port as other scripts like this run at the same time my $localip = '192.168.100.' . ($port - 4000); # Don't ask... backwards compatibility system("ssh -NL $randport:$localip:23 root\@$ip -o ConnectTimeout=60 -i somekey &"); # create the tunnel in the background sleep 10; # Give the tunnel some time to come up # Create the telnet object my $telnet = new Net::Telnet( Timeout => 10, Host => 'localhost', Port => $randport, Telnetmode => 0, Errmode => \&fail, ); # SNIPPED... a bunch of parsing data from $telnet
The thing is that the target $ip is on a link with very unpredictable bandwidth, so the tunnel might come up right away, it might take a while, it might not come up at all. So a sleep is necessary to give the tunnel some time to get up and running.
So the question is: How can i test if the tunnel is up and running? 10 seconds is a really undesirable delay if the tunnel comes up straight away. Ideally, i would like to check if it's up and continue with creating the telnet object once it is, to a maximum of, say, 30 seconds.
Edit: Ping doesn't help me mouch, as the remote end of the tunnel is generally up, but with a very high amount of packetloss
Solved: Extrapolating from the tip suggested by mikebabcock,
sleep 10
has been replaced with this block which works like a charm:my $starttime = time(); while (1) { # Check for success if (system("nc -dzw10 localhost $randport > /dev/null") == 0) { last } # Check for timeout if (time() > $starttime + 30) { &fail() } # 250ms delay before recheck select (undef, undef, undef, 0.25); }
-
Jarmund over 11 yearsping doesn't help me much, as it generally has ~50% packetloss (this is tested beforehand, and believe it or not, it's acceptable down to 50%)
-
OkieOth over 11 yearsbut it exit with success if the tunnel is up. The quality is a part of other communication levels
-
OkieOth over 11 yearsIf you want a better quality to wait you can parse the ping output. But will you disconnect if the quality is to bad?