Two common scenarios require routing traffic through a remote server: accessing private network resources, or browsing from a different geographic IP. An SSH SOCKS5 tunnel solves both in under a minute, no VPN software required.
How SSH -D Works
The -D flag creates a dynamic port forward: SSH listens on a local port and acts as a SOCKS5 proxy. Traffic exits from the SSH server's network:
Your app -> localhost:1080 (SOCKS5) -> SSH encrypted -> remote server -> internet
macOS & Linux: Quick Start
# Start tunnel in background
ssh -D 1080 -f -C -q -N user@your-server.com
# Verify it is running
pgrep -a ssh
# Confirm traffic routes via the server
curl --socks5 127.0.0.1:1080 https://ipinfo.io/ip
Flag meanings:
-
-D 1080: SOCKS5 proxy on local port 1080 -
-f: fork to background after auth -
-C: gzip compression -
-q: quiet mode -
-N: tunnel only, no remote command
macOS: Toggle Script
Save as ~/bin/tunnel, chmod +x, then sudo tunnel:
#!/usr/bin/env bash
NET_SERVICE="Wi-Fi" # run: networksetup -listallnetworkservices
PORT=1080
SERVER="user@your-server.com"
if [[ "$EUID" -ne 0 ]]; then
echo "Run as root: sudo $0"; exit 1
fi
PID=$(pgrep -f "ssh -D ${PORT}")
if [[ -n "$PID" ]]; then
echo "Disconnecting (PID $PID)..."
kill -9 "$PID"
networksetup -setsocksfirewallproxystate "${NET_SERVICE}" off
echo "Tunnel closed."
else
echo "Connecting to ${SERVER}..."
ssh -D "${PORT}" -f -C -q -N "${SERVER}"
networksetup -setsocksfirewallproxy "${NET_SERVICE}" 127.0.0.1 "${PORT}"
networksetup -setsocksfirewallproxystate "${NET_SERVICE}" on
echo "Connected. System SOCKS proxy active on :${PORT}."
fi
networksetup sets the macOS system-wide SOCKS proxy, all apps that respect it route through the tunnel.
Linux: Route CLI Tools with Proxychains4
# Install
sudo apt install proxychains4 # Debian/Ubuntu
sudo dnf install proxychains-ng # Fedora
# Edit /etc/proxychains4.conf:
# comment out: socks4 127.0.0.1 9050
# add: socks5 127.0.0.1 1080
# Start the SSH tunnel
ssh -D 1080 -f -C -q -N user@your-server.com
# Route any CLI tool
proxychains4 curl https://ipinfo.io/ip
proxychains4 git clone https://github.com/someorg/private-repo
sshuttle: Transparent Full-System Proxy (No Config Required)
sshuttle routes all TCP traffic via OS-level interception:
brew install sshuttle # macOS
sudo apt install sshuttle # Ubuntu
# Route everything, exclude the SSH server to avoid a loop
sshuttle -r user@your-server.com 0.0.0.0/0 --exclude your-server.com
# Route only a private subnet behind the server
sshuttle -r user@your-server.com 10.0.0.0/8
# Stop with Ctrl+C
No browser config. Every TCP connection is intercepted transparently.
Windows: Bitvise + Proxifier
- Install Bitvise SSH Client
- Under Services > SOCKS/HTTP Proxy Forwarding, enable SOCKS5 on
127.0.0.1:1080. Log in. - Install Proxifier:
- Add proxy:
127.0.0.1:1080, SOCKS5 - Add rule targeting the apps you want to route (e.g.,
chrome.exe)
- Add proxy:
SSH Config for Reliability
Add to ~/.ssh/config to keep the tunnel alive through network idle timeouts:
Host tunnel-server
HostName your-server.com
User youruser
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
ServerAliveCountMax 3
Compression yes
Start with: ssh -D 1080 -f -C -q -N tunnel-server
SSH -D vs sshuttle vs WireGuard
| Feature | SSH -D | sshuttle | WireGuard |
|---|---|---|---|
| Setup complexity | Low | Low | Medium |
| Routes all traffic | No (per-app SOCKS) | Yes (all TCP) | Yes (all protocols) |
| UDP support | No | No | Yes |
| Server prerequisites | SSH only | SSH only | wireguard-tools |
| Speed | Good | Good | Excellent |
| Best for | Single-app routing | Full TCP proxy | Permanent VPN |
Security Best Practices
- Key-based auth only:
ssh-keygen -t ed25519 - Restrict server to your user:
AllowUsers youruserin/etc/ssh/sshd_config - Use a non-standard port to reduce automated brute-force:
Port 2222insshd_config - Rotate SSH keys annually
Top comments (0)