You can access a remote desktop on a virtual machine by configuring an SSH tunnel through PuTTY. This method securely forwards the RDP traffic over your encrypted connection, allowing you to manage the VM without exposing the remote desktop port directly to the public internet.
Understanding the Security Model
Remote Desktop Protocol (RDP) typically operates on port 3389. By default, this port is often blocked by firewalls or left unsecured if exposed directly. Using an SSH tunnel leverages the security of the Secure Shell protocol to encapsulate the RDP session. When you connect via SSH, your local machine establishes a secure channel to the remote host. From there, the traffic destined for the local loopback interface is forwarded to the VM's internal network where the RDP server is listening. This approach ensures that even if the VM is not directly accessible from the external network, you can still reach its graphical interface as long as you have valid SSH credentials.
Configuring the SSH Tunnel in PuTTY
To begin, launch PuTTY and enter the hostname or IP address of your virtual machine in the "Host Name" field. Ensure the connection type is set to SSH. Before connecting, navigate to the
Connection menu on the left sidebar, then expand it to select
SSH and finally click on
Tunnels. In the "Send private keys" section, ensure your authentication method is configured correctly. If you are using key-based authentication, you may need to load your private key file under the
Auth category before setting up the tunnel.
In the Tunnels configuration window, locate the "Add new forwarded port" section. You will see four fields: Source port, Destination, Type, and Selected. Enter
3389 in the
Source port field. This is the port on your local machine that will listen for incoming RDP connections. In the
Destination field, enter
localhost:3389 or the specific IP of the VM's RDP service if it differs. Select the
Local radio button to indicate that traffic originating from your local machine should be forwarded. Click the
Add button. You should now see
L3389 localhost:3389 listed in the "Forwarded ports" area. This configuration tells PuTTY to capture any traffic sent to port 3389 on your PC and route it through the SSH connection to the destination.
Establishing the Connection
Once the tunnel is added, return to the
Session category at the top of the left-hand tree. Click
Save to store these settings for future use, ensuring you do not lose the tunnel configuration. Then, click
Open to initiate the SSH session. You will be prompted for your username and password. Upon successful authentication, the SSH client will establish a background listener on your local port 3389. The terminal window may appear blank or show a login prompt depending on the OS of the VM, but the tunnel remains active in the background. Do not close this window while you are trying to access the desktop, as closing it terminates the tunnel.
Connecting the Remote Desktop Client
With the tunnel active, open the Microsoft Remote Desktop Connection application on your Windows machine. In the "Computer" field, enter
localhost:3389. This directs the client to look for the RDP service on your own machine rather than the remote VM directly. The client will detect that port 3389 is occupied by the SSH tunnel and automatically route the handshake through that secure channel. Click
Connect. You may receive a certificate warning because the RDP server is likely using a self-signed certificate. Verify that the connection details match your VM and accept the certificate to proceed. You should now see the graphical desktop of your virtual machine.
For more information on managing X11 forwarding alongside other SSH features, you might find
Using IBus with SSH X11 Forwarding Enabled: A Comprehensive Guide helpful for understanding how different protocols interact over SSH tunnels. Additionally, if you encounter connection issues during setup, checking for common errors like those described in
Troubleshooting kex_exchange_identification Error in Linux SSH Connection can help resolve authentication failures early.
Troubleshooting Common Issues
If the connection fails, first verify that the SSH server on the VM is running and accepting connections. Use a command line tool to ping the VM or attempt a basic SSH connection without the tunnel to rule out network connectivity problems. If the SSH connection succeeds but the RDP client hangs, check the firewall settings on the VM. The VM must allow inbound traffic on port 3389 from the loopback interface or the SSH user account. On Linux VMs, ensure that the RDP daemon, such as xrdp, is installed and actively listening. You can verify this by running
netstat -tlnp | grep 3389 inside the VM after logging in via SSH.
Another common issue arises when multiple services try to bind to port 3389 locally. Ensure no other application, such as a web server or another remote desktop client, is using this port on your host machine. If conflicts exist, change the source port in the PuTTY tunnel settings to a different number, such as
3390, and update the Remote Desktop Connection target to
localhost:3390. Remember to update the tunnel configuration in PuTTY to match the new source port.
Maintaining Session Stability
SSH sessions can sometimes drop due to network instability or idle timeouts. To mitigate this, configure the keepalive settings in PuTTY. Navigate to
Connection >
SSH and enable "Seconds between keepalives." Setting this to
60 seconds sends a small packet to keep the connection alive. This prevents intermediate firewalls from dropping the tunnel due to inactivity. For longer sessions, consider using a multiplexer like
tmux or
screen on the remote side if you need to detach and reattach to the SSH session without losing the tunnel context, although this requires careful management of port bindings.
Frequently Asked Questions
Can I use this method on macOS or Linux?
Yes, the principle remains identical. On macOS or Linux, you can use the command-line SSH client with the flag
-L 3389:localhost:3389 to create the same local tunnel. Then, use a native RDP client like Remmina or Microsoft Remote Desktop for Mac to connect to
localhost:3389.
Is it safe to expose port 3389 directly?
Exposing port 3389 directly to the internet is generally discouraged due to the high risk of brute-force attacks and vulnerabilities associated with RDP. Using an SSH tunnel restricts access to only those users who possess valid SSH credentials, adding a significant layer of security.
What happens if I close the PuTTY window?
Closing the PuTTY window terminates the SSH connection, which immediately breaks the tunnel. Any ongoing RDP session will disconnect abruptly. You must keep the SSH client open to maintain the secure pathway for your remote desktop traffic.
How do I change the local port if 3389 is busy?
Go back to the Tunnels section in PuTTY, remove the existing entry, and add a new one with a different source port, such as
5000. Update the destination to
localhost:3389 and save. Your RDP client must then connect to
localhost:5000 instead.
Why does the RDP client show a certificate error?
This occurs because the RDP server on the VM usually generates a self-signed certificate upon installation. It is not signed by a trusted public Certificate Authority. Since the traffic is tunneled through SSH, the encryption is secure, but the identity verification fails. You can safely accept the warning if you trust the VM environment.