In virtualized environments, it’s common to have a VM running behind NAT, especially when using tools like QEMU, VirtualBox, or cloud labs. This setup means the VM can reach the host, but the host cannot directly initiate connections to the VM — including to web services like the Proxmox web GUI running on port 8006
.
Fortunately, this limitation is easy to bypass using reverse SSH tunneling.
🧠 Objective
We want to:
- Access a web service running on port 8006 of a VM that is behind NAT.
- Reach it from the host without any port forwarding or special NAT rules.
🧱 Environment
- VM OS: Linux (SSH server running, root access)
- Host user:
rohan
- VM user:
root
- Web service: Running on VM at
http://localhost:8006
(e.g., Proxmox)
🔁 Step 1: Create a Reverse SSH Tunnel from the VM
On the VM, run the following command:
ssh -R 8006:localhost:8006 rohan@host
This command does the following:
- Tells the host to open port
8006
on its ownlocalhost
. - Forwards any traffic coming to that port to the VM’s port
8006
.
🔐 You may be prompted for
rohan
’s password on the host. Use SSH keys for automation.
🌐 Step 2: Access the Web Service on the Host
Now, from the host machine, open your browser and visit:
http://localhost:8006
🎉 You’ll see the web interface of the VM’s service, tunneled securely and directly to the host.
🔁 Making the Tunnel Persistent
To ensure the tunnel stays up even after reboots or disconnects, use one of the following methods.
Option A: autossh
(Simple and Robust)
Install autossh
on the VM:
sudo apt install autossh
Then run:
autossh -f -N -R 8006:localhost:8006 rohan@host
Option B: systemd
Service (Clean Boot-Time Setup)
Create a systemd
service on the VM:
File: /etc/systemd/system/reverse-ssh-tunnel.service
[Unit]
Description=Reverse SSH Tunnel to Host (Port 8006)
After=network.target
[Service]
User=root
ExecStart=/usr/bin/ssh -N -R 8006:localhost:8006 rohan@host -o "ServerAliveInterval=60" -o "ExitOnForwardFailure=yes"
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Then run:
systemctl daemon-reexec
systemctl enable --now reverse-ssh-tunnel.service
🔒 Security Notes
- This tunnel binds only to
localhost
on the host, making it accessible only from the host machine — not over the network. - Avoid binding to
0.0.0.0
unless you configure a firewall and authentication.
✅ Summary
By using reverse SSH tunneling, we’ve:
- Enabled access to a web service on port
8006
running in a NAT’d VM - Avoided complex NAT or router configurations
- Created a secure and optionally persistent setup
This method works for any port — not just 8006 — making it a great general-purpose tool for working with NAT’d machines.
Need help with tunnels for multiple ports, or setting up proxies for internet access? Drop a comment or reach out!