πŸ”§SSH Tunneling Complete Guide

Overview

SSH tunneling is one of the most reliable and commonly used methods for pivoting and port forwarding. SSH provides encrypted tunnels that can bypass firewalls and access internal services.


SSH Tunnel Types

1. Local Port Forwarding (-L)

Purpose: Forward local port to remote destination through SSH server

Syntax:

ssh -L [local_ip:]local_port:destination_host:destination_port user@ssh_server

# Common usage
ssh -L 8080:192.168.1.100:80 user@10.10.10.50

Traffic Flow:

[Your Machine] β†’ [SSH Server/Pivot] β†’ [Target Service]
localhost:8080 β†’ 10.10.10.50:22 β†’ 192.168.1.100:80

Real-world Examples:

# Access internal web server
ssh -L 8080:192.168.1.100:80 user@pivot.com
# Then browse: http://localhost:8080

# Access internal RDP
ssh -L 3389:192.168.1.50:3389 user@pivot.com
# Then RDP to: localhost:3389

# Access database server
ssh -L 1433:db.internal.com:1433 user@jumpbox.com

# Forward multiple ports
ssh -L 8080:web.internal:80 -L 3389:dc.internal:3389 user@pivot.com

2. Remote Port Forwarding (-R)

Purpose: Forward remote port back to local machine (reverse tunnel)

Syntax:

ssh -R [remote_ip:]remote_port:local_host:local_port user@remote_server

# Common usage
ssh -R 8080:127.0.0.1:80 user@remote.com

Traffic Flow:

[Remote Machine] β†’ [SSH Server] β†’ [Your Local Service]
remote:8080 β†’ your_machine:22 β†’ localhost:80

Use Cases:

# Expose local web server to remote network
ssh -R 8080:127.0.0.1:80 user@target.com

# Expose local listener for reverse shells
ssh -R 4444:127.0.0.1:4444 user@target.com

# Expose local SMB share
ssh -R 445:127.0.0.1:445 user@target.com

3. Dynamic Port Forwarding (-D)

Purpose: Create SOCKS proxy for multiple connections

Syntax:

ssh -D [local_ip:]local_port user@ssh_server

# Common usage
ssh -D 1080 user@10.10.10.50

Configuration:

# Set up SOCKS proxy
ssh -D 1080 user@pivot.com

# Configure proxychains
echo "socks5 127.0.0.1 1080" >> /etc/proxychains.conf

# Use with tools
proxychains nmap -sT -Pn 192.168.1.0/24
proxychains firefox

SSH Options and Flags

Essential Flags

-L    # Local port forwarding
-R    # Remote port forwarding  
-D    # Dynamic port forwarding (SOCKS)
-N    # Don't execute remote command (useful for tunneling only)
-f    # Fork into background
-q    # Quiet mode
-T    # Disable pseudo-terminal allocation
-C    # Enable compression
-g    # Allow remote hosts to connect to forwarded ports

Practical Combinations

# Background tunnel with no shell
ssh -fNT -L 8080:192.168.1.100:80 user@pivot.com

# Multiple port forwards in background
ssh -fNT -L 8080:web.internal:80 -L 3389:dc.internal:3389 user@pivot.com

# SOCKS proxy in background
ssh -fNT -D 1080 user@pivot.com

# Compressed tunnel for slow connections
ssh -fNTC -D 1080 user@pivot.com

Advanced SSH Tunneling

Multiple Hops (ProxyJump)

# SSH through multiple hosts
ssh -J user1@hop1.com,user2@hop2.com user3@final-target.com

# Port forward through multiple hops
ssh -J user@pivot1.com -L 8080:internal.local:80 user@pivot2.com

SSH Config File

# ~/.ssh/config
Host pivot
    HostName 10.10.10.50
    User pentester
    Port 22
    LocalForward 8080 192.168.1.100:80
    LocalForward 3389 192.168.1.50:3389
    DynamicForward 1080

# Usage
ssh pivot

Persistent Tunnels with autossh

# Install autossh
apt install autossh

# Persistent tunnel that reconnects
autossh -M 20000 -fNT -L 8080:192.168.1.100:80 user@pivot.com

# Monitor port 20000 for connection health
# Automatically reconnects if connection drops

Troubleshooting SSH Tunnels

Common Issues

1. Permission Denied

# Check SSH key permissions
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 700 ~/.ssh/

# Test SSH connection first
ssh -v user@pivot.com

2. Port Already in Use

# Check what's using the port
netstat -tlnp | grep :8080
lsof -i :8080

# Kill process or use different port
ssh -L 8081:192.168.1.100:80 user@pivot.com

3. Connection Refused

# Test from SSH server first
ssh user@pivot.com
curl http://192.168.1.100:80

# Check if service is running on target
nmap -p 80 192.168.1.100

4. GatewayPorts Issue

# Allow external connections to forwarded ports
ssh -g -L 0.0.0.0:8080:192.168.1.100:80 user@pivot.com

# Or set in SSH server config (/etc/ssh/sshd_config)
GatewayPorts yes

Debugging Commands

# Verbose SSH output
ssh -v -L 8080:192.168.1.100:80 user@pivot.com

# Check tunnel status
netstat -tlnp | grep :8080
ss -tlnp | grep :8080

# Test tunnel connectivity
curl -v http://localhost:8080
nc -v localhost 8080

SSH Tunneling in Different Scenarios

Scenario 1: Web Application Testing

# Set up tunnel to internal web app
ssh -fNT -L 8080:internal-web.corp.com:80 user@jumpbox.corp.com

# Set up Burp Suite proxy
ssh -fNT -L 8080:internal-web.corp.com:80 -L 8443:internal-web.corp.com:443 user@jumpbox.corp.com

# Access through browser
firefox http://localhost:8080

Scenario 2: Database Access

# Access internal SQL Server
ssh -fNT -L 1433:sql.internal.corp:1433 user@jumpbox.corp.com

# Connect with sqlcmd
sqlcmd -S localhost,1433 -U sa -P password

# Access MySQL
ssh -fNT -L 3306:mysql.internal.corp:3306 user@jumpbox.corp.com
mysql -h 127.0.0.1 -P 3306 -u root -p

Scenario 3: RDP/VNC Access

# Forward RDP port
ssh -fNT -L 3389:windows.internal.corp:3389 user@jumpbox.corp.com

# Connect with rdesktop
rdesktop localhost:3389

# Forward VNC port
ssh -fNT -L 5900:linux.internal.corp:5900 user@jumpbox.corp.com
vncviewer localhost:5900

SSH Tunneling with Metasploit

Using SSH Sessions

# Get SSH session in Metasploit
use auxiliary/scanner/ssh/ssh_login
set RHOSTS 10.10.10.50
set USERNAME user
set PASSWORD password
run

# Use session for port forwarding
sessions -i 1
portfwd add -l 8080 -p 80 -r 192.168.1.100

Security Considerations

SSH Server Configuration

# Secure SSH config (/etc/ssh/sshd_config)
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowTcpForwarding yes
GatewayPorts no
ClientAliveInterval 60

Key Management

# Generate SSH key pair
ssh-keygen -t ed25519 -f ~/.ssh/pivot_key

# Copy public key to target
ssh-copy-id -i ~/.ssh/pivot_key.pub user@pivot.com

# Use specific key
ssh -i ~/.ssh/pivot_key user@pivot.com

Firewall Evasion

# Use non-standard SSH port
ssh -p 2222 user@pivot.com

# SSH over HTTP tunnel (if needed)
# Use tools like HTTPTunnel or similar

Best Practices

  1. Always test basic SSH connectivity first

  2. Use key-based authentication when possible

  3. Clean up tunnels after use (kill background processes)

  4. Monitor tunnel stability with autossh

  5. Use compression (-C) for slow connections

  6. Employ least privilege (specific ports only)

  7. Log tunnel activities for documentation


Quick Reference

Task

Command

Local forward

ssh -L 8080:target:80 user@pivot

Remote forward

ssh -R 8080:localhost:80 user@target

SOCKS proxy

ssh -D 1080 user@pivot

Background tunnel

ssh -fNT -L 8080:target:80 user@pivot

Multiple ports

ssh -L 8080:web:80 -L 3389:dc:3389 user@pivot

Through jump host

ssh -J jump.com -L 8080:target:80 user@final


References

  • SSH Manual: man ssh

  • SSH Config: man ssh_config

  • OpenSSH Cookbook: https://en.wikibooks.org/wiki/OpenSSH

  • HTB Academy: Pivoting, Tunneling & Port Forwarding

Last updated