JVM proxy through a remote/reverse SSH tunnel


You may come across a scenario where you need to test your Java application from an alternate network, or you may not have sufficient network access where your code/application resides.  The JVM comes equipped with awesome proxy capabilities using SOCKs and a more specific HTTP proxy.  These can be set as environment properties when starting the JVM (http.proxyHost,http.proxyPort,socksProxyHost,socksProxyPort) or set programatically.  You can even configure a ProxySelector class for advanced proxy logic.  See Oracle’s Documentation for advanced usage.

Your http requests can go through SOCKs as well, but if the HTTPProxy is defined, then it will use the more specific proxy for the protocol it needs.

Here’s an example of the JVM options you would use to start your Java application to use proxies:

-Xmx2G -Dhttp.proxyHost=192.168.1.2 -Dhttp.proxyPort=80 -DsocksProxyHost=192.168.1.2 -DsocksProxyPort=1080

But, what if you don’t have direct access to the proxy server? You’ll need to use an SSH Tunnel. What if you can’t SSH out of your box? If you can SSH in, you can still create a remote/reverse tunnel. Here’s how that is done in Putty. Right click on the top of your active ssh putty window and chose ‘Change Settings’. Add the tunnels shown in the screenshots below to your connection. I noticed that sometimes ssh servers don’t have permissions to open up lower-numbered ports, so it took some trial and error before discovering that higher-numbered ports worked. The destination address of the tunnel is where the port will be forwarded to. The ‘Dynamic’ setting turns the tunnel into a SOCKs proxy itself and may be good if you don’t have a SOCKs server available, but I never got this working, but could have been because I was trying lower port numbers.

Putty1

Putty2

After you add those ports and apply the settings to your putty ssh session, your development machine now has two listening ports, one for http proxy, one for SOCKs proxy. Then you point your JVM at the localhost ports rather than the remote proxy ports.

-Xmx2G -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8555 -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=8666

The SOCKs proxy in the JVM will even tell MySQL database connections to use the proxy. If you want a specific Apache HttpClient connection to use the proxy, you can configure it like this:

DefaultHttpClient client = new DefaultHttpClient();
HttpHost proxy = new HttpHost(“127.0.0.1”, 8555, “http”);
client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

or

client.getParams().setParameter(“socksProxyHost”,”127.0.0.1″);
client.getParams().setParameter(“socksProxyPort”, 8666);

If you are using Java’s URL class to make a request you can set a proxy for it:

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(“127.0.0.1”, 8555));
HttpURLConnection connection = (HttpURLConnection) new
URL(myUrlString).openConnection(proxy);

If you are developing on a Windows box and need to SSH into that box, a good SSH Server that allows you to open up tunnels is COPSSH.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s