SSH Tunnel for Remote Desktop via Intermediary Server Part II

I asked previously how to configure 2 SSH tunnels using an intermediary server in order to run Remote Desktop through them and I managed to make it work. Now, I'm trying to do the same, using the same machines, but in reverse order. Here's the setup:

  1. Windows 7 PC in a private network, sitting behind a firewall.
  2. Public access Linux server, which has access to the PC.
  3. Windows 7 laptop, at home, on which I wish to do Remote Desktop from the PC.

I use Putty on the laptop to create a reverse tunnel from it to the Linux server: R60666 localhost:3389.

I use Putty on the PC to create a regular tunnel from it to the Linux server: L60666 localhost:60666.

I SSH to the Linux sever and I run telnet localhost 60666 and it seems to produce the expected output, as described in the debugging tips that I received here.

I try to connect Remote Desktop from the PC to the laptop: localhost:60666. It asks for my username and password, I click OK and it locks my current session on the laptop (so I see the welcome screen on the laptop instead of my desktop), it shows the "Welcome" message in the Remote Desktop screen and then it just goes black. It doesn't disconnect, it doesn't provide any error and I'm not able to perform any actions in the Remote Desktop screen. I tried the same setup with a Windows XP laptop and I'm experiencing the same symptoms. I also tried to use different ports than 60666, but nothing changed. Does anybody have any idea what I'm doing wrong?


Update: As pointed out by @jwinders, I'm not able to run telnet PC 3389 from the Linux server directly. Since Windows Firewall has a rule to allow all connections on port 3389, I have no idea what is blocking it. Fortunately, I'm able to create a SSH tunnel from the Linux machine to the PC ssh 3389:localhost:3389 'domain\user'@PC.


Solution 1:

I ran into the same black screen + disconnect problem myself today, using putty as my client. I did find a solution eventually.

I switched from putty to bitvise tunnelier, and setup a S2C connection with the following settings:

listen if:0.0.0.0
listen port:13389
destination host:localhost
dest port:3389

As chance would have it, I'm using bitvise ssh server on my server, so this may just be a happy combination for two products made by the same vendor. It would be great if this solves the problems for others.

For the record, I'm not affiliated with these guys in any way.

Solution 2:

I don't see anything wrong with your SSH tunnels. Connecting to localhost:60666 on the PC should end up at localhost:3389 on the Laptop. And the fact you're getting a login screen confirms this assessment.

A bit of googling on the blank screen get's me to this Microsoft knowledge base article: http://support.microsoft.com/kb/555840. It states a blank screen might by due to possible MTU size mismatches:

Verity that the server, client and the network equipment using the "MTU" size.

Given your fair amounts of network hops, firewalls and what have you, packet fragmentation is quite likely :) Most Windows machines use an MTU of 1300 by default, while most Linux boxes have 1500 (the max allowed value for LAN, not considering jumbo frames). You can try lowering these to reduce fragmentation.

See also:

  • http://www.snailbook.com/faq/mtu-mismatch.auto.html
  • http://www.chakraborty.ch/standards/ssl-ssh-and-mtu-problems/

Solution 3:

Wouldn't a VPN be more appropriate? OpenVPN is super simple to configure. Here is a sample config and some links to guide your through the certificate creation process.

Just configure the intermediary to be the host, and the guests can dial in and still communicate with each other.

apt-get install openvpn
mkdir /etc/openvpn/easy-rsa
mkdir -p /etc/openvpn/ccd/client_server
touch /etc/openvpn/ipp.txt
cp /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
source ./vars
./clean-all
./build-ca 
./build-key-server server
./build-dh
cd /etc/openvpn/easy-rsa/keys
openssl pkcs12 -export -out server.p12 -inkey server.key -in server.crt -certfile ca.crt

Then create a new file /etc/openvpn/client_server.conf and put the following in it, changing the SERVER_IP_ADDRESS as appropriate

local SERVER_IP_ADDRESS
port 8443
proto udp
dev tun
ca /etc/openvpn/easy-rsa/keys/ca.crt
pkcs12 /etc/openvpn/easy-rsa/keys/server.p12
dh /etc/openvpn/easy-rsa/keys/dh2048.pem
ifconfig-pool-persist /etc/openvpn/ipp.txt
server 192.168.100.0 255.255.255.0
client-config-dir /etc/openvpn/ccd/client_server
ccd-exclusive
keepalive 10 120
comp-lzo
persist-key
persist-tun
status /var/log/openvpn-status.log
verb 3
reneg-sec 0
client-to-client

Then build a key per user who is going to connect, and create the config file in the ccd dir

./build-key-pkcs12 [email protected]
echo "ifconfig-push 192.168.100.2 255.255.255.0" > /etc/openvpn/ccd/client_server/[email protected]

The IP address MUST be suitable for a /30 subnet (see http://www.subnet-calculator.com/cidr.php), as there is only 2 addresses available (server and client) per connection. So your next available client IP would be 192.168.100.6 and so on.

Then you now have static IPs per connecting user.

Then supply the [email protected] file to the end-user and use the following config file

client
dev tun
proto udp
remote SERVER_IP_ADDRESS 8443
pkcs12 [email protected]
resolv-retry infinite
nobind
ns-cert-type server
comp-lzo
verb 3
reneg-sec 0

Solution 4:

If you are running the ssh session within the user account (using program such as putty.exe), when you try to login via rdp, it will disrupt that connection causing the rdp session to break. What you need to do is run the ssh tunnel as a service which won't be interrupted.