VPN over SSH? The SOCKS Proxy
By: Cory Chu
Tags: Computer, Ssh, Socks, VPN, Proxy

Some resources on the internet might be only accessible from clients with particular IP addresses. For example, suppose you want to download a paper published in a journal purchased by your university. In that case, you have to connect to the journal’s website from a computer with an IP address that belongs to your university. If you are working at home, it is well-known that you may connect to the university’s VPN such that your IP address will be disguised as a campus’s IP address that allows you to download the paper paid by your university. However, it is not always possible to use VPN provided by your school. For instance, some VPN requires special client software, which may not support OS like Linux. Is there any simple alternative solution to VPN? The answer is YES if you can SSH to a server running with a university’s IP address, e.g., a workstation running in your laboratory.

SOCKS Proxy

Create The SOCKS Proxy

To solve the problem, we can execute the following command, which creates a SOCKS server listing on port 12345 of your localhost.

$ ssh -NTCD 12345 SSH_remote_host_IP ==========================

-N Do not execute a remote command

-T Disable pseudo-terminal allocation

-C Requests compression of all data

-D <port>

Specifies a local "dynamic" application-level port forwarding. This works by allocating a socket to listen to the port on the local side, optionally Whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh will act as a SOCKS server.

If you want to stop it, just press [Control]-[C]

Firefox via SOCKS Proxy

The next step is setting up your browser’s proxy configuration. Take Firefox as an example. The setting is in the Preference > Network Setting > Settings…

SOCKS proxy setting in Firefox

After doing so, you can find the papers you need and start to download them! As a demonstration, you may search “what is my IP” on Google via the browser with proxy, i.e., open https://www.google.com/search?q=what+is+my+ip. You should found that it displays the IP of SSH_remote_host_IP instead of the IP of your local machine.

In addition to the build-in proxy setting in Firefox, there is a convenient Firefox extension — FoxyProxy, which allows you to turn on/off and switch between different proxies very quickly.

How SOCKS Proxy works

Usually, when we use a browser to open https://www.google.com, it will create a TCP socket pair connecting a random port on your local machine to port 443(for HTTPS) on www.google.com. Then, the browser sends the HTTPS request via this socket pair. However, what we did here is creating a SOCKS Proxy. Instead of communicating with www.google.com directly, we asked the browser to send HTTPS from the random port on your local machine assigned by your browser to port 12345 on localhost, which is the SOCKS server you just created by the ssh command. The HTTPS request will be relayed from localhost:12345 through the SSH tunnel, reaching your remote host. And then, it will be sent from a random port on SSH_remote_host_IP to port 443 on www.google.com.

Other than browser

Since the SOCKS proxy performs at Layer 5 of the OSI model (the session layer), you may use it with many applications that work in a Layer higher than Layer 5, such as FTP, Telnet, HTTP, SSH…

SSH via SOCKS proxy

For example, if you want to SSH to a Far_Away_Host via the SOCKS proxy we just created. You can do:

$ ssh -o ProxyCommand='nc -x localhost:12345 %h %p' username@Far_Away_Host

After login into the Far_Away_Host, you can check that you are deemed as connected from SSH_remote_host_IP instead of your local machine!

username@Far_Away_Host$ who

username pts/3 2021-03-29 14:08 (SSH_remote_host_IP)

FTP via SOCKS proxy

Another example is the SOCKS proxy setting in FileZilla, an FTP client:

SOCKS proxy setting in FileZilla

Further Reading

There is a convenient tool — sshuttle suggested by smw on Hacker News. It works as a poor man’s VPN using ssh, which also doesn’t require admin on the remote machine. The manual is here. It can be easily installed on, e.g., macOS and Ubuntu via:

# on Ubuntu

$ sudo apt install sshuttle

$ sudo port install sshuttle # on macOS, installed by macports $ sudo port install sshuttle

The simplest way to use it is:

$ sshuttle -r username@SSH_remote_host_IP 0.0.0.0/0

, which forwards all traffics on your local machine to the remote host!

Finally, there is a decent tool — Tailscale, which provides a zero-config VPN based on WireGuard. The only concern is that you have to have root privilege on the server-side to install Tailscale software. Otherwise, the user experience with it is just fantastic.

Reference