September 2018
Reach internal web-based tools in a private network without a VPN or proxying all your web-traffic through your internal network. Use this to get to a Grafana dashboard, the Consul mananagement UI, the Hadoop admin panel, or whatever else strikes your fancy.
This post is useful if you have the following problems:
Additionally, you'd like to only proxy the requests that need it. The rest of your browsing traffic should just be treated like normal.
There are two components to this solution: SSH tunnels, and using SSH tunnels as a proxy.
OpenSSH can function as a proxy and forward a local port.
$ ssh -q -T -n -N -D 7890 user@your-server &
This opens a SOCKS proxy
to on localhost:7890
, which will pass all traffic through
your-server
. This command assumes you have SSH keys set up
— you won't be prompted for a password.
The &
tells your shell to run the ssh
command in the
background, so you can continue to work in the same terminal. Your tunnel will
stop working once you close your terminal.
Now for the flag soup:
stdin
. This means we can put
the ssh command in the background without fear.ssh
seems to connect, and immediately close the connection again.
I can never remember all these flags. Sometimes, the server also varies. So I have the following function in my shell config:
function proxy() { ssh -q -T -n -N -D 7890 $1 & }
Which let's you type:
$ proxy user@server
So that gives you a tunnel (if you take my word for it). Now let's configure the browser.
Remember we had a requirement to only proxy the requests for the internal services over this tunnel? The browsers I'm aware of don't let you configure this nicely in a GUI. (You can have a "don't proxy" list, but not an "only proxy" list in both Firefox and Chrome.)
Fortunately, the solution lies in the Proxy
auto-config format. It's a JavaScript file in which the function
FindProxyForUrl(url, host)
has to return a specific string with
the config based on the url
and/or host
.
Save the following JavaScript code under ~/.proxy.pac
:
function FindProxyForURL(url, host) { // If you don't have internal DNS, you can do IP // and subnet based configuration. if (isInNet(host, "10.0.0.0", "255.255.255.0")) { return 'SOCKS localhost:7890'; } // Otherwise, you can do something like this: if (host.endsWith('.yourcompany.internal')) { return 'SOCKS localhost:7890'; } // All other traffic treated like normal. return 'DIRECT'; }
Make any modifications you like. The MDN documentation has the details and a list of the functions you can use.
If using Firefox, make your proxy settings look like this (substitute your own home directory):
Chrome has an almost equivalent menu.
After all this is done, you should have a working proxy setup for only the hosts/addresses you want!
N.B.: This apparently also happens to be the format that is used when you "automatically discover proxy settings". Apparently, DHCP servers can advertise a URL with a file in this format. (With the kind of security implications you'd expect — use/demand HTTPS.)