If you run a command like this from host1:
$ ssh -N user@host2 -R 12201:localhost:22 \
-o ServerAliveInterval=10 -o ServerAliveCountMax=2
you can then, from host2, run:
$ ssh -p 12201 user@localhost
to connect back to host1.
The options ServerAliveInterval and ServerAliveCountMax are for noticing if the connection has gone down, and can be set to whatever makes sense. By putting this in a loop, then it can automatically reconnect if the connection is lost. (Just remember to sleep in the loop in case there's no internet or DNS. Also, I've seen it fail to bind the 12201 port if it tries to reconnect too quickly.)
More information in man ssh and man ssh_config.
I wrote a script I named reverse-ssh:
#!/bin/sh
REMOTE_HOST="$1"
FW_PORT="$2"
[ -n "$REMOTE_SSH_PORT" ] || REMOTE_SSH_PORT=22
[ -n "$LOCAL_SSH_PORT" ] || LOCAL_SSH_PORT=22
[ -n "$SSH_LOGIN" ] || SSH_LOGIN=revsshserver
while :
do
ssh -nNTC -o ServerAliveInterval=60 \
-R $FW_PORT:localhost:$LOCAL_SSH_PORT \
-p $REMOTE_SSH_PORT $REMOTE_HOST -l $SSH_LOGIN
sleep 10
done
and put it on host1. (As I understand it, autossh does more or less the same thing, in probably a better way. I didn't know about that program when I set everything up.) I added the *_SSH_PORT options because I had been using nonstandard SSH ports. I then created the following accounts:
revsshclient@host1- with a key pair in
~/.ssh/
- with a key pair in
revsshserver@host2- with login shell disabled (set to
/bin/falsein/etc/passwd) - with
revsshclient@host1's public key in~/.ssh/authorized_keys
- with login shell disabled (set to
and on host1, ran the reverse-ssh script on startup as the user revsshclient. In my case this was done quickly by adding to /etc/rc.local something like
su - revsshclient -c "REMOTE_SSH_PORT=54321 setsid reverse-ssh host2 12345"
Now, from host2 you can connect to host1 with
ssh -p 12345 myusername@localhost
I usually run a command like this to connect from my work computer:
ssh -p 54321 host2 -t -- ssh -p 12345 myusername@localhost
which will do both connections, from my computer to host2, and from host2 to host1. I have my work computer's SSH key on host2's ~/.ssh/authorized_keys, so that I don't have to type a password for that first connection.
By forwarding port 5900:
ssh -p 54321 host2 -L 5900:localhost:5900 -t -- \
ssh -L 5900:localhost:5900 -p 12345 myusername@localhost
I can run x11vnc to get graphical access with a command like:
sudo x11vnc -nopw -localhost -display :0 \
-auth /var/lib/mdm/:0.Xauth