Routing traffic through an SSH SOCKS proxy encrypts connections between a local system and a remote server, shielding web activity from untrusted networks and local observers. Using the SOCKS5 protocol in combination with an SSH tunnel also helps bypass simple network restrictions and captive environments that only allow limited outbound traffic.
An SSH SOCKS proxy relies on dynamic port forwarding, where ssh listens on a local TCP port and behaves as a SOCKS server. Applications configured to use that local port send their requests into the encrypted tunnel, and the remote SSH server opens outbound connections on their behalf, including optional remote DNS resolution when using SOCKS5h.
A working setup requires valid credentials on a remote SSH server, permission to keep an interactive or background session open, and an unused local port (commonly 8080) for the proxy listener. Some applications need explicit SOCKS5 settings and may not support proxies at all, and heavy tunneling can add latency or trigger rate limits on the remote side, so configuration should be tested carefully before relying on it for critical traffic.
Steps to create SOCKS proxy using SSH:
- Open a terminal on the local system.
- Optionally verify basic SSH connectivity to the remote host.
$ ssh user@host.example.net hostname host
- Start an SSH session with dynamic port forwarding on local port 8080.
$ ssh -D 8080 user@host.example.net
-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. Dynamic port forwardings can also be specified in the configuration file.8080 in the example is the port that the SOCKS proxy listens on; any unused port from 1025 to 65535 can be chosen as a non-root user.
Common options to run SOCKS proxy in the background:
$ ssh -D 8080 -fCqN user@host.example.net
- -f: Requests ssh to go to background just before command execution
- -C: Requests compression of all data
- -q: Quiet mode that suppresses most warnings and diagnostic messages
- -N: Does not execute a remote command
- Confirm that the SSH process is listening on the local SOCKS port.
$ ss -natp | grep 8080 LISTEN 0 128 127.0.0.1:8080 0.0.0.0:* users:(("ssh",pid=15044,fd=5)) LISTEN 0 128 [::1]:8080 [::]:* users:(("ssh",pid=15044,fd=4)) - Show the external IP address when connecting directly.
$ curl ifconfig.me 203.0.113.10
- Show the external IP address when using the SOCKS proxy.
$ curl -x socks5h://127.0.0.1:8080 ifconfig.me 203.0.113.50
The socks5h scheme forces hostname and DNS resolution to occur through the proxy, which avoids local DNS leaks.
- Confirm that the external IP address obtained through the SOCKS proxy matches the remote SSH server’s network and differs from the direct connection result.
- Configure the browser or other applications to use a SOCKS5 proxy at host 127.0.0.1 on port 8080 so that traffic is routed through the SSH tunnel.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
