SSH with SOCKS as a VPN
When the only connection I have into a network is SSH, yet I need to do more work than is possible over a single SSH session, I set up a simple VPN-like solution using the following.
I add to my
Host sshgw.example.net DynamicForward 16000 Host *.example.net User shane ProxyCommand ~/.bin/nc-ssh-autoproxy.sh %h %p 16000
The first host listed is the machine where I connect using SSH. I set up a SOCKS proxy on port 16000. The second host section is generic for the entire environment. It specifies a
ProxyCommand which calls a script that pipes the SSH connections over the SOCKS proxy when the proxy is up.
Here is the
#!/bin/sh # netcat-openbsd needed for -x proxy option HOST=$1 PORT=$2 PROXY=$3 netstat -an | grep LISTEN | grep -q "$PROXY" STAT=$? if [ $STAT = 1 ] ; then /bin/nc $HOST $PORT else /bin/nc -x localhost:$PROXY $HOST $PORT fi
One thing to note is that you need to have the OpenBSD version of Netcat, not the GNU version. The OpenBSD version supports connecting to SOCKS proxies. If you are using Debian or Ubuntu, install the
The reason for using the
nc-ssh-autoproxy.sh script is that if a SOCKS proxy is not up, the SSH connection goes directly to the host. But if the proxy is running, all new SSH connections use the proxy.
I frequently use the initial SSH connection to open an IRC session. That way I’m not likely to accidentally close it thinking it is an unused terminal and stop the proxy.
A SOCKS proxy is a general solution that you can send web, email, and other traffic through it to the machines behind the SSH gateway. You can set your applications to use the SOCKS proxy on
localhost:$PORT and everything should work.
I like to take it a step further though for web browsing: I install FoxyProxy in Firefox and configure FoxyProxy to only send requests for *.example.net through the proxy. All other traffic is sent using the normal methods for the machine.
An example FoxyProxy config:
- Create a new proxy, enable SOCKS5
- Add a new pattern
- Name the pattern
- Provide a URL pattern (I prefer regular expression patterns; here’s an example: