checking ssh tunnels: best practices?
Hi, all.
I've got a laptop (yes, I'm on this list, duh). I take it
to a jobsite with me, I take it home, I take it to the
office. Some places I can connect to the mailserver
directly, but at other places I have to ssh through a leased
line back to the office.
I've got ssh set up with tunnels for one smtp port,
three POP ports, a VNC session, etc. I set up exim
to send its mail through the tunnel smtp, and set up
fetchmail to fetch through the tunnel.
The problem is that sometimes these programs don't work
right and hassle ensues if I start them up without starting
up my ssh session first, or if the ssh session has dropped
someplace along the way. A lot of the time I'm working
locally, so I might not notice that the tunnel went away,
and exim will tell me that the message couldn't be
delivered, etc.
The hack I've done is to make a little script,
port_is_connected, so I can have my mutt-starter script
abort with a line like this:
port_is_connected $MAIL1SMTP localhost || exit 1
...or less tersely...
if ! port_is_connected $MAIL1SMTP localhost
then
echo "check the ssh tunnel, dammit!"
exit 1
fi
Does this approach make sense, overall?
It took me a while to figure out how to do port_is_connected, but
eventually I located nmap. This does the job pretty well
and is pretty fast:
nmap -p $MAIL1SMTP localhost | grep -q open
I had been using something like this...
ps -ef | grep "ssh.*$MAIL1SMTP"
... but I don't like that much for a variety of reasons.
So this is what I came up with for port_is_connected:
#!/bin/sh
port=""
host=""
err=""
while [ -n "$1" ]
do
case "$1" in
-*)
err="$err\nunexpected opt"
;;
*)
if [ -z "$port" ]
then
case "$1" in
[0-9]*)
port="$1"
;;
*)
err="$err\nhuh? [$1]"
;;
esac
elif [ -z "$host" ]
then
host="$1"
else
err="$err\ntoo many args [$1]"
fi
;;
esac
shift
done
if [ -n "$err" ]; then printf "ERR$err\n"; exit 2; fi
if [ -z "$port" ]; then err="$err\nno port specified"; fi
if [ -n "$err" ]; then printf "ERR$err\n"; exit 2; fi
if [ -z "$host" ]; then
host=localhost
printf "no host given; assuming host[$host]\n" >&2
fi
if nmap -p $port $host | grep -q open
then
printf "port $host:$port is open: exit 0\n" >&2
exit 0
else
printf "port $host:$port is closed: exit 1\n" >&2
exit 1
fi
So, comments please. Is this a good way to do it, or am I
missing a better, obvious way? Comments on style are also
welcome.
Tony
Reply to: