Java, Java Webstart and SOCKS

When connected to work via VPN I live behind the corporate firewall. Unfortunately this means that I can't connect to the various Go servers, as the firewall won't allow you to connect to arbitrary port numbers. There is a way through the firewall, using a SOCKS proxy, but most of the various Go server clients are Java Webstart applications, and WebStart applications can't unfortunately talk SOCKS, nor can they be successfully SOCKSified using the normal runsocks wrapper. In fact as far as I can tell, Java apps in general can't talk SOCKS unless they have been specifically written to do so. The consequence of this was that I had to keep dropping the VPN connection every time I wanted to play Go, which was a pain. Never one to let a little adversity to stand in my way, I came up with a solution, which might be of interest to others - if you are such a person, read on.

The obvious solution is to put an intermediate proxy that can talk SOCKS between the Java client and the SOCKS proxy - the Java client talks vanilla TCP/IP to the intermediate proxy, and the intermediate proxy then talks SOCKS to the SOCKS server. I thought it would be a snap to find something out there in OpenSourceLand to do this. I wanted something simple, lightweight and entirely userland, but to my surprise I couldn't seem to find anything. I therefore hacked something together myself.

What I ended up with was a simple userland port forwarder - it listens on a range of given ports, and each time it receives a connection it spawns a thread that connects to a specified destination port and transfers data from/to the two endpoints. An example configuration file is shown below:

#
# socksy configuration file.
# Edit as appropriate, then run:
#     $ export $(runsocks env | grep SOCKS_SERVER)
#     $ socksy -d socksy.config
#
# File format is
# : -> : [ , ...]
#  can be "* to wildcard the local interface.
#

# Internet Go Server.
*:7777 -> igs.joyjoy.net:7777, igs.joyjoy.net:6969

# Kisedo Go Server.
*:2379 -> kgs.kiseido.com:2379

# Perl IRC
*:6667 -> irc.perl.org:6667, grouch.irc.perl.org:6667, london.irc.perl.org:6667

Where more than one destination is specified, each is tried in order until one succeeds. The code works fine as it is, but isn't exactly feature rich - for example UDP isn't supported. There's also no logging, and no client access control. However TCP Out Of Band data is catered for correctly. I'm happy to share the code if anyone wants it, and if someone feels then need extra bells & whistles, contributions are gratefully accepted :-)

The code has only been tested on Solaris, so I haven't put a link to the source as I don't want people downloading it and then complaining it doesn't work on Linux, as I don't have access to a Linux box. If you wan the source and are prepared to make it work on Linux, let me know. In fact I've put this entry here in the hope that if I scatter it with enough keywords, someone will find it with Google and come and talk to me about it;-)

Tags : , , ,
Categories : Web, Tech