Lifehacker a nice write up on Firefox web browsing with SOCKS proxies. The tip about network.proxy.socks_remote_dns was new to me and I will have to play with that sometime. Safari, my primary browser, seems to resolve DNS requests at the proxy by default so that saves me the hassle in the meantime.

One of the take home messages of the Lifehacker entry is that you can run “ssh -D 1080” on your workstation, then configure Firefox (as well as most other browsers) to use a SOCKS proxy at localhost port 1080. This provides encrypted communications between your workstation and server (great when your workstation is on an untrusted wireless network) and for masquerading as the server (useful when accessing websites that are behind a firewall or that restrict access by IP address).

Very simple, extremely handy. But what if you want to use remote server that is behind a firewall and only accessible via a gateway machine?

----------------               -------------         -------------
| workstation  |               |           |         |  server   |
|              | --------------|  gateway  | ------- |           |
|(web browser) |               |           |         |  (SOCKS)  |
----------------               -------------         -------------

In that case you have to tunnel through the gateway to get to the SOCKS server running on the server. In this post I’m going to walk though building up the ssh command that will achieve such a tunnel. I will then present an alternate, more generic method.

Forwarding Port 1080 Across the Gateway:

I know I need the sshd on server to act as a SOCKS server so I want to an ssh connection to server with the -D option. So I start with the standard syntax for that.

ssh -D 1080

Since I can not reach the server directly so I need to add a connection to the gateway and have gateway issue the ssh command for the server to do the SOCKS thing.

ssh “ssh -D 1080”

If I run this command from my workstation I will connect to the gateway and then the secondary ssh command will be executed, establishing a SOCKS server on the server. Nice, but completely useless at this point. Let’s keep going.

Now I need to open a local port forward for port 1080 on my workstation to the gateway. This is the same basic requirement needed if the gateway was not involved (the ‘-D 1080’ syntax also sets up a local port 1080 forward), only in this case I don’t want SOCKS on the gateway. A regular local port forward is what I need, with workstation port 1080 bound to port 1080 on the gateway. The option syntax for that (-L 1080:localhost:1080) is incorporated into our previous command:

ssh -L 1080:localhost:1080 “ssh -D 1080”

Finally, I do not want the shell on the gateway machine to handle stdin or stdout so I need to force a pseudo-terminal on the gateway with the “-t” option.

The final command is:

ssh -t -L 1080:localhost:1080 “ssh -D 1080”

With this connection made I can configure my web browser to use localhost port 1080 for a SOCKS proxy and confirm that all is working by visiting a site, such as, that reports my IP address. The IP reported IP address should be that of the remote server.

Alternate Method Using a Generic Port Forward:

The previous method specifically tunnels a SOCKS proxy connection across a gateway. The next method uses a plain, generic tunnel across the gateway and then a connection is made to that tunnel using dynamic forwarding (SOCKS).
The generic tunnel is set up like so.

ssh -t -L 2222:localhost:2222 “ssh -L 2222:localhost:22”

Then I start up the SOCKS proxy server, listening on port 1080, on my localhost to which I’ve connected via port 2222 – the port to the tunnel.

ssh -p 2222 -NfD 1080 localhost

I’ve added the optional ‘-Nf’ options to put the proxy connection in the background.

The advantage of this alternative, generic tunneling method is that the generic tunnel can also be used for other forwardings, X11 for example.

ssh -nfY -p 2222 localhost /usr/X11R6/bin/xclock