HOWTO: Get Windows Remote Desktop Client To Connect To localhost

or "Tunneling Terminal Services traffic over SSH"

Update: Greg Depasse dropped me a line quite some time back noting that Remote Desktop actually lets you connect to your host on any internal loopback address but 127.0.0.1 (i.e., you can use 127.0.0.2), which is something I really ought to have figured out on my own (it's standard TCP/IP stack behaviour). Which means you don't need to change the compatibility mode - just use 127.0.0.2, at least with current client versions. Nevertheless, the information below is still useful.

Introduction

Like many people, I use SSH on a daily basis to tunnel traffic to and fro between machines. It is pretty common to have to access Terminal Services on a Windows 2000 server behind a firewall and have no other way to get past it without SSH.

Usually, that would be only a matter of typing:

ssh me@server -L 3389:target_server:3389

and aiming a Remote Desktop client at localhost, and you'd be in business.

The XP Remote Desktop client

However, one of the major annoyances of the XP Terminal Services client is that it will not allow you to connect to localhost, even if you specify an alternate port like 3390 (remember, you are bound to be running Terminal Services on your own machine, so 3389 will be taken).

(You can open a Remote Desktop session to localhost on a Windows 2000 Server box, but that allows multiple concurrent sessions by design. XP does not - at least not yet, and apparently also by design so that you cannot deploy cheap application servers on XP Professional. Oh well...)

Solution

There is a way around the XP client's limitations, though. Just copy the files:

mstsc.exe
mstscax.dll

to a separate folder, right-click on mstsc.exe, choose Properties... and go to the Compatibility tab.

Under Compatibility Mode, check "Run this program in compatibility mode for:" and select "Windows 98 / Windows ME" from the drop-down list.

You can now do things like:

ssh me@server -L 3390:target_server:3389
mstsc /v localhost:3390

(or just double-click on your modified copy after starting the SSH tunnel and enter localhost:3390)

And you'll connect to localhost just fine - your RDP session will be forwarded via SSH to the target_server.

Conclusion

And why does this work? Well, my guess is that mstsc.exe uses something like the Win32 EnumServices API to check if you can run the service at all, and bars you from connecting to any of your network addresses (including, of course, localhost).

Windows 98, however, does not have these APIs, and programs running under emulation under XP cannot access them.


Notes:

The Remote Desktop Connection client for Mac OS X 1.0 ignores the :port section of the address, since connecting to localhost works, and localhost:3390 does not. Furthermore, it only allows one session at a time.

A slightly updated version now allows for specifying the port, but still does not allow for simultaneous sessions.

Bear in mind that you cannot SSH to a XP box and try to forward RDP traffic to it via localhost - The Remote Desktop service will reject the connection.

Also, Danny Carrol wrote in mentioning that changing the compatibility mode to Windows 98 can screw up your keyboard layout (oddly enough, when using the "US International Keyboard", not the standard US layout). The fix seems to be forcing the client to use the standard US keyboard map.