Lets say that hypothetically speaking you’re running an application or two which are known to not work behind proxies. What a pickle, especially if those applications have some desire to be online, to communicate with online services. But they can’t.
After a bit of a chat with my friend and fellow podcaster Dave Walker I came up with a solution. It involves 4 pieces of software, all of which are in the Ubuntu repositories. There are guides online to using each piece of software, but none that I could find which brought them all together.
Note: This is a bit of a mess, and whilst it works, it’s not pleasant, and is only really useful for this very specific requirement. I’m just blogging it in case someone else happens to be running the same software as me, and is also stuck behind a poxy proxy.
Here’s the simple non-graphical ‘diagram’ to show the software used and path to get out.
Application -> via tsocks -> ssh (socks proxy) -> corkscrew -> poxy proxy server -> (Internet) -> External host -> ??
In addition to the software required, you’ll also need a box on the outside of the network into which you have ssh access. This is required because we’ll be tunnelling traffic to that machine, so that any software can send/receive packets as if they are on the outside of the firewall/proxy. If you don’t have a box on the outside of the firewall that you can ssh into, give up with this guide now, it’s a pre-requisite.
If you would like to rent a virtual private server (VPS) then I can highly recommend Bitfolk, and if you sign up and mention my name, I get nothing
Debian gets a financial donation though, so that’s something good. Alternatively you could leave a cheap low-power computer permanently switched on at home. Or maybe wake it up when you go out, and switch it off when you’re back home to save some power. I’d probably forget to do that, so mine’s always on and it only draws 8W, so I don’t feel too bad about the constant power drain.
On the server outside the firewall
You’ll probably want to do this setup before you’re stuck behind the nasty nasty firewall and proxy. You can get into a bit of a chicken and egg situation where you can’t configure SSH for this process because you can’t SSH in to change the SSH config.. etc ad infinitum.
Ensure SSH server is installed
For Ubuntu/Debian users this is in the repository, so sudo apt-get install openssh-server is sufficient.
You might want to do some of the usual security things on the server like configuring the SSH server to only accept key logons and not passwords. You may also want to limit what IP addresses you can connect from. Other security options are beyond the scope of this post, but if you have any suggestions, leave a comment below.
Configure SSH to run on port 443
This will only work if the server in question has nothing else running on 443 – like an SSL enabled HTTP server.
The relevant setting is on the server in /etc/ssh/sshd_config and is usually fairly near the top, it’s “Port”, just change the value. You can then restart SSH on Ubuntu/Debian with sudo /etc/init.d/ssh restart.
Probably good at this point to test the setup, to see if you can indeed SSH to the box now you’ve monkeyed around with the SSH config.
On the PC inside the firewall
Install Corkscrew
Corkscrew tunnels SSH traffic over the proxy server.
For Ubuntu users this is in the repository, so sudo apt-get install corkscrew
Configure Corkscrew
Edit ~/.ssh/config
Add the following line, replacing ‘proxyserver 8000′ with the hostname and port number that the proxy server runs on. Note that the path to the Corkscrew executable is right for Ubuntu, but may need to be modified for other distributions, or if you compile it yourself.
ProxyCommand /usr/bin/corkscrew proxyserver 8000 %h %p
Test Corkscrew
Try and logon using SSH on the command line, specifying the port number, username on the remote box and host name of the remote (external) host or IP address.
ssh -p 443 myusername@mylovelyexternalhost.example.com
Pro-tip! Edit ~/.ssh/config and add the following lines to save you having to type so much.
Host myhost
Hostname mylovelyexternalhost.example.com
Port 443
User myusername
Then you can SSH with this:-
ssh myhost
Install tsocks
Tsocks is some lovely magic that forces applications to send their (potentially non-HTTP and thus non-proxy-friendly) TCP traffic over a socks proxy. Install it as you would the other packages, again it’s in the Ubuntu repo, so sudo apt-get install tsocks should sort that in a trice.
Configure tsocks
Edit /etc/tsocks.conf
Ensure lines exist that look like this. This will configure tsocks to attempt to make an outbound connection over a SOCKS5 proxy (which doesn’t exist yet, but will in the next step) which is running on port 1080.
server = 127.0.0.1
server_type = 5
server_port = 1080
Start the socks proxy
At this point all the config is done, all the steps above need only be done once. The stuff below is what you do each time you want to setup the SOCKS proxy, and subsequently send data over it.
ssh -D 1080 -vvv myhost
The -D sets up the persistent SOCKS proxy over the connection to myhost (via corkscrew).
The -vvv makes SSH a bit chatty, causing it to spit out detail whenever we use the SOCKS proxy. This is helpful in determining if things are working. Once you have it working, you can choose to remove that parameter.
Start your application using tsocks
The final step! This is where we use tsocks to send network traffic over the proxy we just brought up.
There are two ways to start tsocks, either using LD_PRELOAD or by prefixing the application you’re running with the tsocks command. Here’s two examples:-
Starting the Ubuntu One Syncdaemon – in which first we disconnect from Ubuntu One, then start it using tsocks and in debug mode, and then reconnect. Then start Rhythmbox. All the traffic for both applications will go over the tunnel to the external box.
$ u1sdtool -q
$ export LD_PRELOAD=/usr/lib/libtsocks.so
$ /usr/bin/python /usr/lib/ubuntuone-client/ubuntuone-syncdaemon --debug
$ u1sdtool -c
$ /usr/bin/rhythmbox
Starting Firefox – in which we can see the other way to use tsocks. Again, all TCP traffic will go over the tunnel.
tsocks /usr/bin/firefox
The only thing that won’t go over the tunnel as far as I can tell is DNS lookups which according to the man page for tsocks:-
“tsocks will normally not be able to send DNS queries through a SOCKS server since SOCKS V4 works on TCP and DNS normally uses UDP. Version 1.5 and up do however provide a method to force DNS lookups to use TCP, which then makes them proxyable. This option can only enabled at compile time, please consult the INSTALL file for more information”
Hope that information is useful to someone, and if there’s any mistakes or omissions, please leave a comment.