SSH port forwarding is a powerful feature that allows forwarding network traffic through SSH encrypted tunnels, protecting data transmission of insecure protocols.
Port Forwarding Types
1. Local Port Forwarding
Forward local port traffic through SSH tunnel to remote server.
bash# Basic syntax ssh -L [local_address:]local_port:target_host:target_port user@SSH_server # Example 1: Access remote server's MySQL (port 3306) ssh -L 3306:localhost:3306 user@remote-server # Example 2: Access internal network service ssh -L 8080:192.168.1.50:80 user@jump-host # Example 3: Bind to specific local address ssh -L 127.0.0.1:8080:localhost:80 user@remote-server
Use Cases:
- Access remote server databases
- Access internal network web services
- Bypass firewall restrictions
2. Remote Port Forwarding
Forward remote server port traffic through SSH tunnel to local.
bash# Basic syntax ssh -R [remote_address:]remote_port:target_host:target_port user@SSH_server # Example 1: Let remote server access local web service ssh -R 8080:localhost:80 user@remote-server # Example 2: Bind to all remote server interfaces ssh -R 0.0.0.0:8080:localhost:80 user@remote-server # Example 3: Persistent forwarding (requires GatewayPorts yes on server) ssh -g -R 8080:localhost:80 user@remote-server
Use Cases:
- Internal network penetration
- Remote debugging of local services
- Expose local services to public network
3. Dynamic Port Forwarding
Create SOCKS proxy for dynamic traffic forwarding.
bash# Basic syntax ssh -D local_port user@SSH_server # Example: Create SOCKS5 proxy ssh -D 1080 user@proxy-server # Example: Bind to specific address ssh -D 127.0.0.1:1080 user@proxy-server
Use Cases:
- Browser proxy
- Bypass network censorship
- Anonymous access
Practical Application Examples
Scenario 1: Secure Access to Remote Database
bash# Create tunnel ssh -L 3307:db-server:3306 user@jump-host # Connect to database in another terminal mysql -h 127.0.0.1 -P 3307 -u dbuser -p
Scenario 2: Internal Network Penetration
bash# Execute on local machine ssh -N -R 8080:localhost:3000 user@public-server # Now can access local service via public-server:8080
Scenario 3: Browser Proxy
bash# Create SOCKS proxy ssh -D 1080 -N user@proxy-server # Configure browser to use SOCKS5 proxy: 127.0.0.1:1080
Advanced Configuration
1. Server-side Configuration
In /etc/ssh/sshd_config:
bash# Allow remote port forwarding to bind to all interfaces GatewayPorts yes # Allow TCP forwarding AllowTcpForwarding yes
2. Persistent Connection
bash# Use autossh to maintain connection autossh -M 0 -L 3306:localhost:3306 user@remote-server -N # Or use ServerAliveInterval ssh -o ServerAliveInterval=60 -L 3306:localhost:3306 user@remote-server -N
3. Background Running
bash# Use -N parameter (no remote command execution) ssh -N -L 3306:localhost:3306 user@remote-server # Use -f parameter (background running) ssh -f -N -L 3306:localhost:3306 user@remote-server
Security Considerations
- Limit Access: Only bind to localhost (127.0.0.1)
- Use Firewall: Restrict port access permissions
- Regular Monitoring: Monitor active port forwarding
- Use Key Authentication: Avoid password authentication
- Limit Users: Only allow trusted users to use port forwarding
Troubleshooting
bash# Check port listening status netstat -tuln | grep 3306 # Test connection telnet localhost 3306 # View SSH logs tail -f /var/log/auth.log
Best Practices
- Use
-Nparameter to avoid executing remote commands - Use
-fparameter for background running - Configure
ServerAliveIntervalto keep connection active - Use
autosshfor automatic reconnection - Pre-set common forwarding rules in configuration file
- Regularly audit port forwarding configurations