Establishing a VNC connection to a remote host behind NAT or firewalls is challenging because the target machine cannot initiate inbound connections. A reverse SSH tunnel solves this by having the remote host push a port forward back to your local machine, creating a secure channel for VNC traffic without exposing ports publicly. This method ensures encrypted access while bypassing restrictive network configurations that block direct VNC protocols.
Understanding the Reverse Tunnel Concept
Standard SSH forwarding typically allows you to connect from your local machine to a remote server's port. However, when the VNC server resides on a device that does not have a public IP address or is behind a strict firewall, it cannot listen for incoming connections from your client. The solution involves reversing the direction of the tunnel. You configure the remote host (the one with the VNC server) to open an SSH connection to your local machine and forward a specific port on its end to the VNC service.
This approach requires that your local machine has a public IP address or is accessible via DNS, and that your SSH daemon allows remote port forwarding. By establishing this pipeline, any traffic sent to the local forwarded port is securely tunneled through SSH to the remote VNC server. This eliminates the need for complex port forwarding rules on routers or configuring static IPs for every remote endpoint.
Prerequisites and Configuration
Before setting up the tunnel, ensure both machines meet specific requirements. Your local machine must be running an SSH server that permits remote port forwarding. On modern Linux distributions, this is often disabled by default in
/etc/ssh/sshd_config. You must add or uncomment the line
GatewayPorts yes and restart the SSH service. Without this setting, the tunnel will only bind to localhost on the remote side, making it inaccessible from your local client if you are connecting from a different interface or if the routing is not explicitly handled.
On the remote host, you need the VNC server installed and running. Ensure the VNC server is configured to listen on a specific port, typically 5900 for the first display (
:0). It is crucial to note that VNC traffic is rarely encrypted natively, which is why wrapping it in an SSH tunnel is essential for security. If you are using a commercial VNC solution like RealVNC or TigerVNC, verify that the configuration allows TCP connections on the desired port.
For those experiencing issues with basic connectivity, refer to our guide on
Troubleshooting: Can't connect to a VNC server to ensure the VNC daemon itself is functioning correctly before adding tunnel complexity.
Executing the Reverse SSH Command
The core of this setup is the SSH command executed on the remote host. The syntax uses the
-R flag to specify remote port forwarding. The general structure is:
ssh -N -R [bind_address:]remote_port:localhost:vnc_port user@local_host
Let us break down these parameters. The
-N flag tells SSH not to execute a remote command; it is used solely for forwarding ports. The
-R flag defines the forwarding rule. For example, if you want to expose the VNC port 5900 on the remote host to port 6000 on your local machine, you would use:
ssh -N -R 6000:localhost:5900 user@your_public_ip
In this example,
6000 is the port on your local machine that will receive the traffic.
localhost:5900 refers to the VNC server on the remote host itself.
user@your_public_ip is your local SSH server's credentials. Once connected, your local machine listens on port 6000. When you connect your VNC client to
localhost:6000, the traffic travels through the SSH tunnel to the remote host and reaches the VNC server on port 5900.
If you encounter authentication errors during this step, check your SSH key permissions or password settings. For assistance with command-line authentication, see
Pass pw for remote user in bash line when ssh from linux to windows.
Maintaining the Connection with Autossh
A standard SSH session will terminate if the network drops, breaking the VNC tunnel. To maintain a persistent connection, use
autossh. This utility monitors the SSH session and automatically restarts it if it fails. Install
autossh on the remote host and run a similar command:
autossh -M 0 -N -R 6000:localhost:5900 user@your_public_ip
The
-M 0 option disables autossh's own monitoring port, relying instead on SSH's built-in keepalive mechanisms, which is often more reliable in constrained environments. You can also add
-o ServerAliveInterval=60 to send keepalive packets every 60 seconds to prevent timeout disconnections.
For deeper troubleshooting regarding tunnel failures and exit codes, consult
Troubleshooting Autossh/Ssh Failure Setting Tunnel with ExitOnForwardFailure.
Connecting the VNC Client
With the tunnel active, open your VNC client on the local machine. Configure the connection to point to
localhost on the port you specified in the SSH command (e.g., 6000). Do not enter the remote host's IP address. The VNC client will establish a connection to your local SSH server, which then forwards the data through the encrypted tunnel to the remote VNC server.
Verify the connection by checking for latency and visual stability. If the connection fails, ensure that no local firewall on your machine is blocking the inbound port. Additionally, confirm that the remote host's SSH daemon is accepting the remote forwarding request. If you see encryption-related errors, such as key exchange failures, review
Troubleshooting kex_exchange_identification Error in Linux SSH Connection for protocol mismatch solutions.
Frequently Asked Questions
Why can't I connect to the remote VNC port directly?
Direct connections fail because the remote host is likely behind NAT or a firewall that blocks inbound traffic on VNC ports. A reverse tunnel creates an outbound connection from the remote host, which most firewalls allow, thereby bypassing these restrictions securely.
Is it safe to use VNC over SSH?
Yes, this is highly recommended. Standard VNC transmits data in plaintext, including passwords. Wrapping it in an SSH tunnel encrypts all traffic, protecting against eavesdropping and man-in-the-middle attacks on untrusted networks.
What happens if my internet connection drops?
The SSH tunnel will disconnect, and the VNC session will terminate immediately. Using tools like
autossh helps mitigate this by automatically restarting the tunnel when connectivity is restored, minimizing downtime.
Can I forward multiple VNC displays?
Yes, you can create multiple reverse tunnels for different displays. Each display requires a unique local port mapping. For example, you can map local port 6000 to remote :0 and local port 6001 to remote :1 simultaneously.
How do I debug tunnel connection issues?
Start by verifying that your local SSH server allows
GatewayPorts. Then, test the SSH connection manually with verbose output (
-v) to identify authentication or port binding errors. Check firewall logs on both ends to ensure ports are not being blocked.