Reverse SSH tunnel

Access Linux SSH server behind NAT via reverse SSH tunnel on relay server

• You have your Linux server running at home behind a NAT router without public IP address.
• You want to SSH to the home server from outside Internet.
• SSH port forwarding is not an option in this case.
• You don’t have your own public IP and you share some IP address with other users behind NAT.

The solution is reverse SSH tunneling.
• You need another relay host outside your network (for example VPS), which you can connect to via SSH.
• Then you set up a persistent SSH tunnel from the server in your home network to the public relay host.
• With this settings, you can connect back to your home server via the relay host.

Linux SSH server behind NAT: root@home-server
Relay SSH host (VPS): (public IP:
Your SSH client: username@laptop

Allow SSH daemon to port forward from external network interface (not only loopback) on SSH relay host.
[ ~]# vi /etc/ssh/sshd_config

GatewayPorts clientspecified

Restart SSH daemon.
[ ~]# /etc/init.d/ssh restart

Allow incoming port range on SSH relay host and autossh monitoring ports:
[ ~]# ufw allow 20001:20010/tcp
[ ~]# ufw allow 21001:21010/tcp

Create user account on relay server for SSH connection.
[ ~]# useradd -m -c "Name Surname" relay_username

Exchange the public key, the SSH connection works passwordless.
[root@home-server: ~]# ssh-copy-id

If you don’t have SSH keys generated yet, create them.
[root@home-server: ~]# ssh-keygen

Connect from your Linux server behind NAT using SSH relay host IP address and credentials (for example on VPS).
[root@home-server: ~]# ssh -N -R

On SSH relay host check if SSH tunnel is established successfully.
[ ~]# netstat -nap | grep 20001

Now, from your client laptop, you can access your home server behind NAT.
[username@laptop: ~]$ ssh -p 20001

Locate testing session on relay server.
[ ~]# netstat -nap | grep 20001

tcp        0      0*               LISTEN      24823/sshd: relay_username

Kill testing session identified by PID, in our example 24823.
[ ~]# kill 24823

Configure persistent reverse SSH tunnel by installing AutoSSH.
[root@home-server: ~]# apt-get install autossh

Test the connection with AutoSSH.
[root@home-server: ~]# autossh -M 21001 -N -T -q -o "PubkeyAuthentication=yes" -o "StrictHostKeyChecking=false" -o "PasswordAuthentication=no" -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R

“-M 20001” heartbeat port on relayserver to monitor SSH session
“-N” open the connection and do nothing (not interactive)
“-T” disable pseudo-terminal allocation
“-q” quiet mode
“PubkeyAuthentication” use key authentication
“StrictHostKeyChecking” does not accept unknown SSH host keys automatically
“ServerAliveInterval” exchange keep-alive messages every 60 seconds
“ServerAliveCountMax” send 3 keep-alive messages without receiving any response back

Start AutoSSH during boot with systemd:

Description=AutoSSH tunnel service

ExecStart=/usr/bin/autossh -M 21001 -N -T -q -o "PubkeyAuthentication=yes" -o "StrictHostKeyChecking=false" -o "PasswordAuthentication=no" -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R


Reload systemd and start AutoSSH daemon:
[root@home-server: ~]# systemctl daemon-reload && systemctl start autossh.service

Check AutoSSH the status.
[root@home-server: ~]# systemctl status autossh

Enable AutoSSH start during boot.
[root@home-server: ~]# systemctl enable autossh.service