SSH is a very versatile protocol, and one useful feature is the ability to create a reverse connection tunnel to access resources on remote server.
This can be useful in many cases, such as accessing a server from inside a remote network without the need to setup port forwarding.
Requirements
- A server with a public IP address (accessible from the internet)
- An internal server with a private IP address (not accessible from the internet)
Diagram
The internal server connects to the public server using a SSH reverse tunnel.
fig 1
Internal server ---> Internet ---> Public server (SSH server)
The internal server can now be accessed from the public server as if it was locally available.
fig 2
SSH Client ---> Internet ---> Public server (SSH server) ---> Internal server
Internal server configuration
I recommend creating a systemd service to keep the reverse tunnel alive. (fig 1)
/etc/systemd/system/ssh-reverse-tunnel.service
[Unit]
Description=SSH reverse tunnel to jump server
After=network.target
[Service]
User=localuser
ExecStart=/usr/bin/ssh -R 2222:localhost:22 [email protected] -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o StrictHostKeyChecking=no
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
make sure to replace the User with your local user
sudo systemctl enable ssh-reverse-tunnel.service --now
External server
A localhost:2222
SSH listener will be created on the public server, which will automatically forward to the internal server.
Local machine
You can now configure your local machine to use the public server as a jump host for the internal server. (fig 2)
For example, you can add the following to your ~/.ssh/config
(note the ProxyJump
directive):
Host internal.host
Hostname localhost
Port 2222
User localuser
ProxyJump public.server.com
Now you can connect to the internal server using the public server as a jump host:
ssh internal.host