Quick Answer: SSH tunneling creates a SOCKS5 proxy through an encrypted SSH connection. The problem: SSH traffic is easily detected by DPI. Solution: tunnelforge wraps SSH in TLS so it looks like HTTPS, adds multi-user management, a Telegram bot, and a kill switch. Install:
curl -fsSL https://raw.githubusercontent.com/SamNet-dev/tunnelforge/main/install.sh | sudo bash.
Need a VPS? Vultr (free credit), DigitalOcean ($200 free credit), or RackNerd (cheap annual deals).
What Is SSH Tunneling?
SSH (Secure Shell) isn't just for remote server access — it can also create encrypted tunnels that carry any traffic. When you create an SSH tunnel, your computer opens a local SOCKS5 proxy that routes traffic through the SSH connection to your server.
Your Device
|
| SOCKS5 proxy at localhost:1080
| → Encrypted SSH tunnel
|
v
Your Server (VPS)
|
| Traffic exits to the internet from your server's IP
|
v
Destination (websites, apps)
The one-liner that makes this work:
ssh -D 1080 -N -f user@your-server
-D 1080— create a SOCKS5 proxy on local port 1080-N— don't open a shell (just tunnel)-f— run in background
Then configure your browser or system to use localhost:1080 as a SOCKS5 proxy. All traffic flows through your server.
The Problem: SSH Is Detectable
SSH tunneling is simple and effective — but it has a critical weakness in censored countries:
DPI (Deep Packet Inspection) can easily identify SSH traffic.
The SSH protocol has a distinctive handshake that starts with SSH-2.0-OpenSSH_... in plaintext. Even after the handshake, SSH packet patterns (sizes, timing, encryption layer structure) are fingerprint-able. DPI systems in Iran, China, and Russia detect and block or throttle SSH connections, especially on non-standard ports.
Without obfuscation:
Your Device → [SSH handshake visible] → DPI sees "This is SSH" → BLOCKED
With TLS obfuscation:
Your Device → [TLS handshake, looks like HTTPS] → DPI sees "Normal HTTPS" → ALLOWED
└→ Inside the TLS wrapper: SSH tunnel (invisible to DPI)
This is where TLS obfuscation comes in — wrapping the SSH connection inside a TLS layer so it looks identical to normal HTTPS traffic.
How TLS Obfuscation Works
TLS obfuscation (using stunnel) wraps the entire SSH connection in a TLS (HTTPS) layer:
- Your device opens a TLS connection to your server on port 443 (just like visiting a website)
- The DPI system sees a standard TLS handshake with a valid certificate — indistinguishable from HTTPS
- Inside the TLS tunnel, an SSH connection carries your traffic
- The server unwraps TLS, passes the SSH traffic to the SSH daemon, and forwards your traffic to the internet
Layer 1 (visible to DPI): TLS/HTTPS connection to port 443
Layer 2 (encrypted, invisible): SSH connection
Layer 3 (encrypted): Your actual internet traffic (SOCKS5 proxy)
To the censor, your connection looks like you're browsing a website. They'd have to break TLS encryption to know it's actually an SSH tunnel.
Part 1: Basic SSH Tunnel (Without Obfuscation)
If your country doesn't heavily censor SSH, a basic tunnel might be enough:
Create the Tunnel
# On your local machine
ssh -D 1080 -N -f user@your-server-ip
Configure Your Browser
Firefox (recommended — has built-in SOCKS5 support):
- Settings → Network Settings → Manual Proxy Configuration
- SOCKS Host:
127.0.0.1, Port:1080 - Select SOCKS v5
- Check "Proxy DNS when using SOCKS v5" (important — prevents DNS leaks)
System-wide (Linux — for curl and apps that support ALL_PROXY):
export ALL_PROXY=socks5://127.0.0.1:1080
# Note: HTTP_PROXY and HTTPS_PROXY expect HTTP proxy URLs, not SOCKS5
# Use ALL_PROXY for SOCKS5, or use proxychains for apps that don't support it
Or use proxychains (for any app):
sudo apt install proxychains4 -y
# Edit /etc/proxychains4.conf — set: socks5 127.0.0.1 1080
proxychains4 curl ifconfig.me # Should show your server IP
Local Port Forwarding
Access a specific service through the tunnel:
# Forward local port 8080 to a remote web service on port 80
ssh -L 8080:localhost:80 -N -f user@your-server
# Now visit http://localhost:8080 to access the remote server's port 80
# Forward to a database behind the server
ssh -L 5432:db-internal:5432 -N -f user@jump-server
# Now connect to localhost:5432 to reach the internal database
Make It Persistent
The tunnel dies if your connection drops. Use autossh to auto-reconnect:
sudo apt install autossh -y
# Persistent SOCKS5 tunnel
autossh -M 0 -f -N -D 1080 user@your-server \
-o "ServerAliveInterval=30" \
-o "ServerAliveCountMax=3" \
-o "ExitOnForwardFailure=yes"
Full SSH reference: SSH Cheat Sheet
Part 2: tunnelforge (SSH + TLS Obfuscation + Management)
tunnelforge automates everything: SSH tunnel + TLS obfuscation + multi-user management + Telegram bot + kill switch.
What tunnelforge Gives You
- TLS obfuscation — SSH traffic wrapped in TLS, looks like HTTPS to DPI
- Interactive TUI — visual interface for all management
- Live dashboard — real-time connection stats, bandwidth, connected users
- Multi-user — create SSH users with individual limits
- Telegram bot — manage everything from your phone
- Kill switch — auto-blocks direct internet if tunnel drops (prevents leaks)
- Auto-reconnect — tunnel recovers automatically from disconnections
Install
curl -fsSL https://raw.githubusercontent.com/SamNet-dev/tunnelforge/main/install.sh | sudo bash
The interactive wizard:
- Configures the SSH server for tunneling
- Sets up TLS obfuscation (stunnel) on port 443
- Creates the first tunnel user
- Optionally configures the Telegram bot
TUI Dashboard
tunnelforge
The TUI shows:
- Server status and uptime
- Active connections per user
- Bandwidth usage (real-time)
- TLS obfuscation status
- Connected IPs
Manage Users
# Add a user
tunnelforge user add alice
# Add with limits
tunnelforge user add bob --max-connections 3 --expires 2026-12-31
# List users
tunnelforge user list
# Remove user
tunnelforge user remove alice
# Disable/enable
tunnelforge user disable bob
tunnelforge user enable bob
Each user gets SSH credentials that work through the TLS-obfuscated port (443).
Client Connection
Users connect using any SSH client:
# Direct SSH tunnel (if SSH isn't blocked)
ssh -D 1080 -N -p 443 alice@your-server
# Through TLS obfuscation (if SSH is blocked)
# Users need an stunnel client or tunnelforge client
# tunnelforge provides connection instructions for each user
tunnelforge user link alice
Telegram Bot
tunnelforge telegram setup
Bot commands:
/tf_status— server status/tf_users— list active users/tf_add username— create user/tf_remove username— delete user/tf_traffic— bandwidth stats/tf_restart— restart tunnel
Auto-alerts: tunnel down, tunnel recovered, user quota exceeded.
Kill Switch
The kill switch prevents your real IP from leaking if the tunnel drops:
tunnelforge killswitch enable
It adds firewall rules that block all outbound traffic except through the tunnel. If the tunnel disconnects, your internet stops instead of leaking your real IP.
Part 3: Manual TLS Obfuscation (Without tunnelforge)
If you want to set up TLS obfuscation manually:
Server Side (stunnel)
# Install stunnel
sudo apt install stunnel4 -y
# Get a TLS certificate
sudo certbot certonly --standalone -d your-domain.com
# Configure stunnel
sudo nano /etc/stunnel/stunnel.conf
[ssh-over-tls]
accept = 443
connect = 127.0.0.1:22
cert = /etc/letsencrypt/live/your-domain.com/fullchain.pem
key = /etc/letsencrypt/live/your-domain.com/privkey.pem
# Start stunnel
sudo systemctl enable --now stunnel4
Now port 443 accepts TLS connections and forwards the decrypted traffic to SSH on port 22.
Client Side (stunnel)
# Install stunnel on your local machine
sudo apt install stunnel4 -y
# Create client config
cat > ~/stunnel-client.conf << EOF
[ssh-tunnel]
client = yes
accept = 127.0.0.1:2222
connect = your-server:443
EOF
# Start stunnel client
stunnel ~/stunnel-client.conf
# Now SSH through the TLS wrapper
ssh -D 1080 -N -p 2222 [email protected]
The connection path:
SSH client → stunnel client (local) → TLS to port 443 → stunnel server → SSH daemon (port 22)
DPI sees only TLS traffic to port 443 — identical to visiting a website.
Part 4: SSH Tunnel vs Other Methods
| Method | Speed | DPI Resistance | Complexity | Best For |
|---|---|---|---|---|
| SSH tunnel (basic) | Good | Low (SSH is detectable) | Very easy | Light censorship |
| SSH + TLS (tunnelforge) | Good | High (looks like HTTPS) | Easy (automated) | Moderate censorship |
| VLESS+Reality | Good | Excellent | Moderate | Heavy censorship |
| Hysteria2 | Fastest | Excellent | Easy | Heavy censorship + speed |
| SOCKS5 (Dante) | Good | Low | Easy | No censorship, just privacy |
| WireGuard | Fastest VPN | Low (easily detected) | Easy | Privacy, not censorship |
When to Use SSH Tunneling
- You already have SSH access to a server (no additional software needed on server)
- You need a quick tunnel without installing proxy software
- You want multi-hop through jump hosts (SSH natively supports this)
- Your setup uses SSH keys already and you want to reuse that infrastructure
When to Use Something Else
- You need maximum speed → Hysteria2
- You need the strongest DPI resistance → VLESS+Reality
- You need CDN fallback → Clean Cloudflare IPs
- You only need Telegram → MTProto Proxy
- You need last-resort bypass → DNS Tunneling
Part 5: Advanced SSH Tunneling
Multi-Hop (Chaining Servers)
Route through multiple servers for extra privacy:
# Jump through server1 to reach server2
ssh -J user@server1 -D 1080 -N user@server2
# Or chain in SSH config:
# Host hop1
# HostName server1.com
# User user
# Host final
# HostName server2.com
# User user
# ProxyJump hop1
Reverse Tunnel (Access Home from Anywhere)
If your home is behind NAT/CGNAT, create a reverse tunnel from home to your VPS:
# On your home machine (connects OUT to your VPS)
autossh -M 0 -f -N -R 2222:localhost:22 user@your-vps
# Now from anywhere, SSH to your VPS port 2222 reaches your home machine
ssh -p 2222 homeuser@your-vps-ip
This is how you access a home server without port forwarding. See Home Server Guide.
Dynamic Port Forwarding + ProxyChains
Use SSH tunnel with any command-line tool:
# Create tunnel
ssh -D 1080 -N -f user@server
# Use with any program via proxychains
proxychains4 curl ifconfig.me
proxychains4 wget https://example.com/file.zip
proxychains4 nmap -sT target.com
Part 6: Security Hardening
Harden the SSH Server
# Only allow tunnel users (no shell access)
# In /etc/ssh/sshd_config:
Match User tunnel-user
AllowTcpForwarding yes
X11Forwarding no
PermitTunnel no
GatewayPorts no
AllowAgentForwarding no
ForceCommand /bin/true
This allows the user to create tunnels but prevents them from getting a shell or doing anything else on the server.
Use Key-Only Authentication
# Disable password login
PasswordAuthentication no
Guide: SSH Keys Setup
Use Fortify
Fortify auto-detects SSH and hardens it:
bash <(curl -sL https://github.com/SamNet-dev/fortify/raw/main/install.sh)
fortify --harden ssh
Guide: Fortify Server Hardening
Fail2ban (Brute Force Protection)
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
Guide: Fail2ban Setup
Troubleshooting
# Check SSH service
sudo systemctl status sshd
# Check stunnel (TLS obfuscation)
sudo systemctl status stunnel4
# Check if port 443 is listening
ss -tlnp | grep 443
# Test SSH connection directly
ssh -v user@server -p 22
# Test through TLS
openssl s_client -connect your-server:443
# Check tunnel is working
curl --socks5 127.0.0.1:1080 ifconfig.me
| Problem | Fix |
|---|---|
| SSH connection refused | Check sshd running: systemctl status sshd. Check firewall |
| SSH connection times out | Port blocked by ISP. Use TLS obfuscation on port 443 |
| TLS connection fails | Check stunnel config and certificate paths. Renew cert: certbot renew |
| Tunnel works but internet is slow | Check server bandwidth. Try compression: ssh -C -D 1080 ... |
| SOCKS5 proxy not working in browser | Check proxy is set to SOCKS5 (not HTTP). Enable "Proxy DNS" |
| DNS leaking through tunnel | Enable "Proxy DNS when using SOCKS v5" in Firefox, or use proxychains |
| Tunnel drops frequently | Use autossh with keepalive: ServerAliveInterval=30 |
| "Permission denied" | Check SSH key permissions (600) or password. Check AllowUsers in sshd_config |
Related Guides
- SSH Cheat Sheet — every SSH command
- SSH Keys Setup — key-based authentication
- How to Secure SSH — hardening guide
- Complete SSH Guide — deep dive
- SOCKS5 Proxy Setup — SOCKS5 without SSH
- Every Way to Bypass Internet Censorship — all methods compared
- Hysteria2 Setup — fastest protocol
- Clean Cloudflare IPs — CDN bypass
- 3X-UI Panel Setup — VLESS/VMess proxy
- MTProto Proxy Setup — Telegram proxy
- Fail2ban Setup — brute force protection
- Fortify Server Hardening — automated hardening
- Home Server Guide — reverse tunnels for home access
SamNet Open Source Tools
| Tool | Purpose |
|---|---|
| tunnelforge | SSH tunnel manager with TLS obfuscation, TUI, Telegram bot |
| fortify | Server security hardening |
| paqctl | Censorship bypass (Paqet + GFW-Knocker) |
| MTProxyMax | Telegram proxy manager |
| cfray | Cloudflare clean IP scanner |
| wg-orchestrator | WireGuard VPN management |
Related Tools
- VPN Leak Test — verify tunnel is working
- Port Scanner — check if ports are open
- What's My IP — verify IP changed
- Speed Test — test tunnel speed