SSH Reverse Tunneling

· 2 min read

Your target device (device you want to access) will establish an ssh connection to your proxy server (any server accessible from the internet will do).

Now if you want to access target device you just go to your proxy server and use the connection opened and kept alive by the target device.

Why would you need that? Remote access to devices in firewalled networks and emergency access, e.g. because an IP address changed.

Proxy Server

You need a proxy / jump server. Create a new user on it. Add this to your /etc/ssh/sshd_config:

# settings for reverse tunnels
ClientAliveInterval 30
ClientAliveCountMax 99999
GatewayPorts yes
AllowTcpForwarding yes
Match User tunnel
AllowTcpForwarding yes
X11Forwarding no
AllowAgentForwarding no
ForceCommand /bin/false

This will make sure that the tunnel user can not execute any code on your server (which would suck if you are building a reverse tunnel to an untrusted device). Then restart sshd. (yes you can do that without loosing connection)

On the target device

On the target device create a service ssh-reverse.service:

[Unit]
Description=Reverse SSH connection
After=network.target
[Service]
Type=simple
User=admin
Group=admin
ExecStart=/usr/bin/ssh -v -g -N -T -o "ServerAliveInterval 10" -o "ExitOnForwardFailure yes" -R 22221:localhost:22 tunnel@[yourproxyhost]
Restart=always
RestartSec=5s
[Install]
WantedBy=default.target

Then enable and start the service with systemctl daemon-reload && systemctl enable --now ssh-reverse

This service starts ssh in reverse mode by connecting to the proxy server and binding to the port 22221 (you can use any big port here). User=admin runs it as an unprivileged user and the other options are for recovery and logging.

Generate a new keypair on the target and add the pubkey to the proxy server. (this is only for the reverse connection authorization, you will still need an auth method to the target)

Done.

You should now have a working reverse tunnel. If you want to access it directly from your machine without sshing into your proxy server, add this to your local ssh config:

Host how-you-want-to-call-the-thing
HostName localhost # this refers to the host on the proxy
User admin # user on the target
Port 22221
ProxyJump [yourproxyhost]

now the thing is entirely transparent and all you need to do to get in your target device is ssh [how-you-want-to-call-the-thing].

You can of course also go to the proxy server and ssh to localhost and the port.