Setting up a simple SOCKS proxy tunnel over SSH📄 BetterWays.dev wiki page | 🕑 Last updated: Oct 8, 2022
If you have any kind of Linux/Unix server accessible over SSH, it's very easy to use it as a simple proxy server. This can be used as a form of a simple VPN tunnel (for example, to bypass content filters and other restrictions on your local Internet connection). Even the cheapest Linux/BSD VPS options will be more than enough for this.
This feature is built into OpenSSH, and you don't need to install any additional software, or do any additional configuration.
All you need to do is open an ssh connection from the client side with a dynamic port forwarding option:
ssh -D 1080 myserver
-D option tells ssh to use the local 1080 port for dynamic, application-level port forwarding. In a practical sense, this means that your ssh client will act as a SOCKS 4/5 server on that port.
Depending on your configuration, you may also need to specify an SSH port and user (i.e.
ssh -p 2222 [email protected], but in that case, you may want to consider setting up a host profile in your ~/.ssh/config file instead).
After that, all you need to do is tell your browser to use a SOCKS proxy on localhost:1080.
In Firefox, you can set SOCKS proxy in Settings / Network Settings / Configure Proxy Access to the Internet - Manual proxy configuration:
- SOCKS Host: localhost
- Port: 1080
- SOCKS v5
With Google Chrome/Chromium, you need to start the browser with
Non-interactive / scripting use
If you don't want the SSH client to open an interactive session, you can prevent it from executing the shell with
-N flag, and
-f flag to put it into the background, i.e.:
ssh -N -f -D 1080 myserver
If you want to automatically restart the connection when necessary, you can use
autossh tool (the syntax is the same):
autossh -N -f -D 1080 myserver
If you're using Putty instead of CLI ssh client, you need to add 1080 as a source port and select Dynamic as a forwarding option under Connection / SSH / Tunnels.
Relevant ssh options
-D [bind_address:]port Specifies a local “dynamic” application-level port forwarding. This works by allocating a socket to listen to port on the local side, optionally bound to the specified bind_address. 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. Only root can forward privileged ports. Dy‐ namic port forwardings can also be specified in the configuration file. IPv6 addresses can be specified by enclosing the address in square brackets. Only the superuser can forward privileged ports. By default, the local port is bound in accordance with the GatewayPorts setting. However, an explicit bind_address may be used to bind the connection to a specific address. The bind_address of “localhost” indicates that the listening port be bound for local use only, while an empty address or ‘*’ indicates that the port should be available from all interfaces. -N Do not execute a remote command. This is useful for just for‐ warding ports. -f Requests ssh to go to background just before command execution. This is useful if ssh is going to ask for passwords or passphrases, but the user wants it in the background. This im‐ plies -n. The recommended way to start X11 programs at a remote site is with something like ssh -f host xterm. If the ExitOnForwardFailure configuration option is set to “yes”, then a client started with -f will wait for all remote port for‐ wards to be successfully established before placing itself in the background.