Using SSH to web-browse behind the Fermilab firewall

Little-known features of ssh and web browsers (Firefox at least) makes it fairly simple to use the web browser to get to web pages that are hidden behind firewalls. Ssh has a 'DynamicForward' feature which provides a SOCKS service that can make any TCP connection from the server on behalf of the client. Web browsers support "proxy auto-configuration" .pac files that contain a small programming language (details here and here) that among other things enables automatically selecting the SOCKS service for selected web sites. It can even be set up to behave differently based on the IP address of a laptop so it only takes effect when it is outside of Fermilab. For those of us who are accustomed to using ssh, this is more convenient than a VPN and much better-performing than running a separate web browser inside the firewall over an X connection or VNC or even nomachine.

This is what I put in my laptop's ~/.ssh/config, using fnalu as an example although it can be any ssh server inside the firewall and any port available on your desktop/laptop:

Host fnalu-first
    DynamicForward 1078
A similar dynamic forward can be set up for Windows users in PuTTY under the "SSH" "Tunnels" option page.

Then I create a www.pac file (or any name you like, pac stands for Proxy Auto Config) with this for accessing restricted Fermilab websites:

function FindProxyForURL(url, host) {
    // internal-only FNAL sites
    if (shExpMatch(host,"bss*")
             || shExpMatch(host,"time*")
             || shExpMatch(host,"")
             || shExpMatch(host,"")
	    ) {
	// go direct if inside the FNAL firewall
	if (isInNet(myIpAddress(),"","")) {
	    return "DIRECT";
        return "SOCKS5";
    // All other requests go directly to the WWW:
    return "DIRECT";
You can put that file either on your local disk or on a web site (or use mine), and then at least in Firefox 3 you go to "Preferences" "Advanced" "Network" "Settings" and fill in an Automatic proxy configuration URL and click OK. If you change the contents of the file and want to use it without restarting Firefox, go to the same place and click Reload. A URL for a file on the local disk is "file://" plus the complete path (which itself begins with a slash for a total of 3 slashes). Note: Even though there is a place for a PAC file in the Mac System Preferences under Network -> Advanced -> Proxies, I haven't been able to get it to work with Safari.

Then whenever I am outside the firewall and need to access a restricted site I just need to do 'ssh fnalu-first' in one xterm window first. If I forget to connect I get an error saying the proxy refused to make the connection.

The same technique can be used to tunnel to different places as well, for example CERN. My .pac file includes CERN and it can be used with the following .ssh/config entry:

Host lxplus-first
    DynamicForward 1079

If you prefer more manual control and simpler setup, an alternative to using automated switching in a .pac file is to use the QuickProxy Firefox plugin. That gives you a button with which you can turn the configured proxy on and off. You could set up the SOCKS proxy in the Firefox network settings, and only enable it when you are off-site with the QuickProxy button. When it is enabled, all browser traffic will then go through the ssh connection to the Fermilab network.

Another Firefox add-on FoxyProxy gives automated control of proxy selections but with a higher level (and harder to share) interface than a .pac file.

Snow Leopard NOTE: when I first upgraded my Mac laptop to Snow Leopard, this was not working for me because Firefox 3.6.6's myIpAddress() was always returning Eventually I found out that it was related to the fact that I had put in the network DNS search domain but my IP address is in the domain. The was overriding the default The workaround is to list both and in the search domains. It takes a period of time for it to take effect, roughly 10 minutes. I found that an extra line in the .pac file

    alert("source_ipaddress: '" + myIpAddress() + "' ")
and looking at the Messages tab under "Tools" "Error Console" was helpful in debugging.