The biggest challenge in helping out a friend in need (running Linux, of course — I don’t bother troubleshooting any Windows problems with any tool other than an Ubuntu Live CD now-a-days) is often their local networking setup. Why? Because I can point out tutorials or guides until I am blue in the face but some people are just very uncomfortable reconfiguring their system and insist they will ‘mess it up’, so sometimes you have to just do it help fix things yourself and firewalls get in the way.
The quick thing to do is SSH into their machine, or VNC in, and just troubleshoot the problem yourself. However, 9 times out of 10 a router, or a NAT, or a firewall, or a proxy, or an act of god will prevent you from establishing a TCP connecton to the machine. To get around this problem most commercial troubleshooting applications require the user to initiate the connection. So, I figure, why can’t we use some quick open source tunnel magic to do the same?
Here is my quick and handy guide to “hacking in” (aka (reverse) ssh port forwarding) to somebody’s PC that is behind a firewall or NAT:
0) You need yourself a machine which has an open ssh port (22 by default) to the internet for this to work (herein referred to as myopenpc.com). It doesn’t have to be your machine, it can be a third party machine that you have a login to. All it needs is to be running openssh on it. A Linode.com node, or a dreamhost shell account, anything like these will do. I personally use a cluster I still have access to at my undergraduate college the University of Penn (yay Force@STWing!).
You’ll also need a login on <YOUROPENPC>.com (herein: myopenpc.com) for your friend (or they can borrow yours) as well as a login on your friend’s machine (duh) and preferrably also root on your friend’s machine (if only temporary).
1) When you first help your friend setup their computer add an extra desktop shortcut for them which will run the following command (or walk them through typing in this command)
ssh -C -R 8888:localhost:22 FRIENDSUSERNAME@<YOUROPENPC>.com
When your friend runs this command it will prompt for a password. Now you can either give them their own username and password on the open-to-the-world machine or you can temporarily change your password (if you dont mind giving them access to your account… assuming they have no idea what a terminal is I find this option works fine for most cases).
So, what does this do? “-R” means “Reverse Port Foward” — When SSH makes the connection to the “myopenpc.com” server it sets up an extra port on “myopenpc.com” (port 8888) to automagically redirect back to port 22 on localhost. Therefore any data sent to port 8888 on myopenpc.com actually is rerouted over the original ssh connection to port 22 on localhost. (localhost in this case means your friend’s computer).
(-C just means enable compression. If you’re going to do VNC forwarding (see below) this will help keep bandwidth usage down and speed up)
2) Next, you need to login to myopenpc.com:
3) From here, you can now do:
ssh -p 8888 username_on_friends_computer@localhost
and Voila! You’re now logged into your friend’s computer despite any firewall or NAT they might have!
Alright, but what if you REALLY need access to their X Session (aka what they see on their screen) to help with the issue? We can fix that too.
4) Install x11vnc and run it on your friend’s PC (which you can now do because you’re logged into their machine)
sudo apt-get install x11vnc && x11vnc -display :0
5) x11vnc will by default host a vnc session on port 5900. We, however, only have access to port 22 on our friend’s computer (remeber the :22 in the initial ssh -R command?). Nothing is stoping us from running another ssh session with a new port number though! So, from your friend’s PC, log into myopenpc.com again!
ssh -C -R 8889:localhost:5900 FRIENDSUSERNAME@myopenpc.com
Now we have two different ssh connections from your friend’s computer to myopenpc.com. One sets up port 8888 to redirect back to your friend’s computer on port 22 (for ssh connections) and one redirects back to your friends computer on port 5900 (for VNC). You could change this to any port you want — 80 for HTTP if your friend has a webserver, 631 if you want to access their CUPS printing page etc.
6) We’re not quiet done, however. Only myopenpc.com port 8889 can talk to the x11vnc server on your friend’s machine. Unless you have an X session with a vncviewer on myopenpc.com you still can’t connect. So, what we now need to do, is connect a port on YOUR machine to port 8889 on myopenpc.com. This is a “forward” port forward and can be done quiet simply.
ssh -C -L 9999:localhost:8889 email@example.com
Now any data sent to port 9999 on your machine will actually be routed via ssh to port 8889 on myopenpc.com. Any data sent to port 8889 on myopenpc.com actually is routed via another ssh session to port 5900 on your friend’s computer. Ah, what a tangled web we weave!
7) We’re almost done! Now, all we need to do is setup the vnc session by pointing to localhost port 9999 (which redirects to myopenpc.com which redirects to your friend’s computer)
Recap of what we covered:
- ssh -R — Reverse port forwarding. This allows you to setup a port on the REMOTE machine which points to your LOCAL machine.
- ssh -L — Normal port forwarding. This allows you to setup a port on the LOCAL machine which points to the REMOTE machine.
- ssh -C — Enable compression in your ssh connections.
- Port 22 — what ssh uses by defualt
- Port 5900 — what VNC uses by default
- Port 631 — what CUPS (Linux/Unix printing services) uses by default
- x11vnc — a program which starts a VNC session based on an already running X session
- vncviewer — a standard program to connect to a VNC session.