Ssh – Keeping an SSH Tunnel open, and running a remote command

networkingsshssh-tunneltunneling

A computer behind a firewall (at a remote location) connects to my server to open a tunnel… the intention is that from the server I can connect to the computer over SSH.

The computer makes the connection with:

while true; do
    PORT=$(((RANDOM %= 1000) + 2000));
    ssh -R $PORT:localhost:22 -o ServerAliveInterval=30 "server" "record_port.sh '$PORT';";
    sleep 5;
done

The "record_port.sh" shell script on the server contains:

echo "$PORT" > "/tmp/tunnel.port";
while true; do
    sleep 300;
done

I can then connect to the server with:

function computer {
  ssh -p `cat /tmp/tunnel.port` -o NoHostAuthenticationForLocalhost=yes localhost
}

The server also has a "ClientAliveInterval 30" in /etc/ssh/sshd_config… and uses things like rbash and dss keys.

I use a random port as I have found that on occasion the port is already being used, with the intention that if I kill the connection on the server, the computer will re-connect 5 seconds later with a new port.

And because it is a random port, I need the shell script to record the port being used (not had any luck with lsof).

But the problem is that if the internet connection is lost and the tunnel closes, the computer will happily re-connect a new tunnel on a different port number, but the original process (record_port.sh) continues:

ps ax | grep "report_port"
 4166 ? Ss 0:00 /bin/bash /home/tunnel/bin/report_port.sh 2833
 6863 ? Ss 0:00 /bin/bash /home/tunnel/bin/report_port.sh 2605
20109 ? Ss 0:00 /bin/bash /home/tunnel/bin/report_port.sh 2023

pstree
init(1)─┬─...
        ├─sshd(28187)─┬─sshd(6860)───sshd(6862)───tunnel.port.sh(6863)───sleep(15533)
        │             ├─sshd... (my current shell)
        ├─tunnel.port.sh(4166)───sleep(15232)
        ├─tunnel.port.sh(20109)───sleep(15318)

Best Answer

autossh http://www.harding.motd.ca/autossh/ / http://packages.debian.org/squeeze/autossh can monitor the health of existing connections (by passing traffic around a local and remote port forward loop) and reconnect failed/failing ones (by re-running ssh).

netstat -tlp will give you the process id opening the remote port which might help in tracking down the new random port being used.