How To Create SSH Proxy Tunnel on Debian 13

Securing your internet connection has never been more critical. Whether you’re working remotely, accessing sensitive data, or simply browsing on public WiFi, SSH proxy tunnels offer a powerful solution for encrypting traffic and protecting your online activities. This comprehensive guide walks you through creating SSH proxy tunnels on Debian 13, from basic setup to advanced configurations.
SSH tunneling transforms your Debian system into a secure gateway, routing traffic through encrypted connections that shield your data from prying eyes. Beyond privacy, these tunnels enable access to remote resources, bypass network restrictions, and create secure pathways between systems. Let’s dive into the practical steps that will have your SSH proxy tunnel operational within minutes.
Understanding SSH Proxy Tunnels
What is an SSH Proxy Tunnel?
An SSH proxy tunnel leverages the Secure Shell protocol to create an encrypted channel between your local machine and a remote server. Unlike standard SSH connections used merely for remote access, tunneling forwards network traffic through this encrypted connection, effectively turning the remote server into a secure proxy.
The beauty lies in its simplicity. All data passing through the tunnel gets wrapped in SSH encryption, making it unreadable to anyone intercepting the connection. This protects everything from web browsing to database queries, API requests to file transfers.
Types of SSH Tunnels
SSH supports three distinct tunneling methods, each serving specific purposes:
- Dynamic Port Forwarding creates a SOCKS proxy that routes traffic dynamically based on application requests. This is ideal for web browsers and applications supporting SOCKS5 protocol.
- Local Port Forwarding maps a local port to a remote destination, perfect for accessing specific services like databases or web panels behind firewalls.
- Remote Port Forwarding exposes local services to remote networks, enabling others to access resources running on your machine through the SSH server.
Each method has distinct advantages. Dynamic forwarding offers flexibility. Local forwarding provides targeted access. Remote forwarding solves NAT traversal challenges.
Prerequisites and System Requirements
System Requirements
Before starting, ensure your Debian 13 (Trixie) installation meets these requirements:
- Active Debian 13 operating system
- Root or sudo privileges for package installation and configuration
- Stable network connection
- Access credentials for a remote SSH server (IP address, username, password or key)
- Minimum 512MB RAM and 1GB free disk space
Required Software
OpenSSH forms the foundation of SSH tunneling on Debian systems. Check if it’s already installed:
ssh -V
This command displays the OpenSSH version. If missing, install both client and server components:
sudo apt update
sudo apt install openssh-client openssh-server -y
Verify the SSH service status:
sudo systemctl status ssh
The output should show “active (running)” in green, confirming the SSH daemon is operational.
Preparing Debian 13 for SSH Tunneling
Installing and Configuring OpenSSH
With OpenSSH installed, enable it to start automatically on system boot:
sudo systemctl enable ssh
sudo systemctl start ssh
These commands ensure SSH remains available after reboots. Confirm the service is listening on port 22:
sudo ss -tlnp | grep :22
You should see SSH binding to port 22, ready to accept connections.
Basic SSH Configuration
The SSH server configuration file controls tunneling capabilities. Open it with your preferred text editor:
sudo nano /etc/ssh/sshd_config
Locate or add these critical directives:
AllowTcpForwarding yes
PermitTunnel yes
GatewayPorts no
AllowTcpForwarding enables port forwarding functionality. PermitTunnel permits tunnel device forwarding. GatewayPorts controls whether remote hosts can connect to forwarded ports—keep it disabled for security unless specifically needed.
After modifications, restart SSH:
sudo systemctl restart ssh
The server now supports secure tunneling operations.
Creating a Dynamic SSH Proxy Tunnel (SOCKS Proxy)
Understanding Dynamic Port Forwarding
Dynamic port forwarding establishes a SOCKS proxy on your local machine, routing application traffic through the SSH connection to the remote server. SOCKS5, the latest version, supports both TCP and UDP protocols while handling authentication and providing better security than its SOCKS4 predecessor.
This method shines when you need flexible proxy capabilities without configuring individual port forwards. Browsers, messaging apps, and numerous other applications support SOCKS proxies natively.
Creating the SOCKS Proxy
Execute this command to establish a dynamic SSH tunnel:
ssh -D 1080 -N -f user@remote-server
Replace user with your remote username and remote-server with the server’s IP address or hostname. Let’s decode each parameter:
-D 1080creates a SOCKS proxy listening on local port 1080-Ntells SSH not to execute remote commands, only forward ports-fbackgrounds the process after authentication
Port 1080 is conventional for SOCKS proxies, though you can choose alternatives like 8080 or 9090 if it’s already in use.
Enter your password when prompted. The tunnel establishes silently in the background. Verify it’s running:
ps aux | grep "ssh -D"
You’ll see the active SSH process with your tunnel parameters.
Configuring Applications to Use SOCKS Proxy
System-Wide Proxy Configuration
Set environment variables to route terminal applications through the proxy:
export ALL_PROXY="socks5://127.0.0.1:1080"
export HTTP_PROXY="socks5://127.0.0.1:1080"
export HTTPS_PROXY="socks5://127.0.0.1:1080"
Make these settings permanent by adding them to ~/.bashrc:
echo 'export ALL_PROXY="socks5://127.0.0.1:1080"' >> ~/.bashrc
source ~/.bashrc
Browser Configuration
Firefox Setup:
Navigate to Settings → Network Settings → Manual proxy configuration. Enter:
- SOCKS Host:
127.0.0.1 - Port:
1080 - Select SOCKS v5
- Check “Proxy DNS when using SOCKS v5”
Chrome/Chromium Setup:
Launch with command-line arguments:
google-chrome --proxy-server="socks5://127.0.0.1:1080"
Test your proxy by visiting a website that displays your IP address. It should show the remote server’s IP, confirming traffic routes through the tunnel.
Creating Local Port Forwarding Tunnels
Local Port Forwarding Explained
Local forwarding maps a port on your machine to a destination accessible from the SSH server. This technique excels when accessing services behind firewalls or on private networks unreachable directly from your location.
Consider accessing a database server that only accepts connections from specific IPs. Local forwarding tunnels your connection through an authorized server, granting access as if you were connecting from that server’s network.
Setting Up Local Port Forwarding
The general syntax follows this pattern:
ssh -L local_port:destination_host:destination_port user@ssh_server
Practical Example: MySQL Database Access
Connect to a MySQL database at db.internal.network through an SSH jump server:
ssh -L 3336:db.internal.network:3306 user@jump.server.com
This forwards local port 3336 to the remote database’s port 3306. Connect to the database using:
mysql -h 127.0.0.1 -P 3336 -u dbuser -p
Your MySQL client connects to localhost port 3336, which SSH tunnels to the remote database.
Multiple Port Forwarding
Forward several ports simultaneously:
ssh -L 3336:db.host:3306 -L 8080:web.host:80 -N -f user@server
This command establishes two forwards: one for database access and another for a web interface. The -N -f flags keep the tunnel running in the background without opening an interactive shell.
Creating Remote Port Forwarding Tunnels
Remote Port Forwarding Explained
Remote forwarding reverses the process, exposing services from your local machine to users on the remote server’s network. This proves invaluable for sharing development servers, demonstrating applications, or bypassing NAT restrictions that prevent inbound connections.
Think of it as punching a hole through firewalls from the inside, allowing external access to services running on your protected network.
Setting Up Remote Port Forwarding
The syntax mirrors local forwarding with reversed logic:
ssh -R remote_port:localhost:local_port user@remote_server
Practical Example: Exposing Local Web Server
Share your local development server running on port 3000:
ssh -R 8080:localhost:3000 -N -f user@remote.server.com
Visitors accessing remote.server.com:8080 now reach your local development environment.
Enabling Remote Port Access
By default, remote forwards only bind to localhost on the SSH server, preventing external access. To allow connections from any address, modify the server’s SSH configuration:
sudo nano /etc/ssh/sshd_config
Add or modify:
GatewayPorts yes
Restart SSH to apply changes:
sudo systemctl restart ssh
Exercise caution with this setting—it exposes forwarded ports to anyone who can reach the server.
Advanced SSH Tunnel Configuration
Using SSH Config File
Managing multiple tunnels via command-line arguments becomes tedious. The SSH configuration file streamlines this process.
Create or edit ~/.ssh/config:
nano ~/.ssh/config
Add tunnel configurations:
Host work-tunnel
HostName remote.company.com
User yourname
DynamicForward 1080
LocalForward 3306 db.internal:3306
ServerAliveInterval 60
ServerAliveCountMax 3
Host dev-tunnel
HostName dev.server.com
User developer
RemoteForward 8080 localhost:3000
IdentityFile ~/.ssh/dev_key
Connect simply by referencing the host alias:
ssh work-tunnel
All defined forwards activate automatically. ServerAliveInterval keeps connections alive through idle periods, preventing timeout disconnections.
SSH Key-Based Authentication
Eliminate password prompts with public key authentication. Generate a key pair:
ssh-keygen -t ed25519 -C "tunnel@debian13"
Accept the default location (~/.ssh/id_ed25519) and optionally set a passphrase for added security.
Copy your public key to the remote server:
ssh-copy-id user@remote.server.com
Test the connection:
ssh user@remote.server.com
You should connect without password prompts. Key-based authentication enhances security while enabling automated tunnel scripts.
Security Best Practices for SSH Tunnels
SSH Server Hardening
Secure your SSH server against unauthorized access:
Change Default SSH Port
Edit /etc/ssh/sshd_config:
Port 2222
Non-standard ports reduce automated attack attempts.
Disable Root Login
PermitRootLogin no
Force attackers to know both a valid username and password.
Limit Authentication Attempts
MaxAuthTries 3
LoginGraceTime 30
These settings limit brute-force effectiveness.
Disable Password Authentication
After setting up key-based authentication:
PasswordAuthentication no
ChallengeResponseAuthentication no
Only key holders can connect.
Restrict Users
AllowUsers alice bob
Explicitly list permitted users.
Apply changes:
sudo systemctl restart ssh
Firewall Configuration
Configure UFW (Uncomplicated Firewall) to protect SSH access:
sudo ufw allow 2222/tcp
sudo ufw limit 2222/tcp
sudo ufw enable
The limit rule implements connection rate limiting, blocking IPs making too many attempts.
Install and configure fail2ban for automated protection:
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Fail2ban monitors logs and temporarily bans IP addresses showing malicious behavior.
Monitoring and Maintenance
Check active SSH connections:
sudo ss -tnp | grep :22
Review authentication logs:
sudo tail -f /var/log/auth.log
Look for failed login attempts or suspicious patterns. Keep your system updated:
sudo apt update && sudo apt upgrade -y
Regular updates patch security vulnerabilities.
Troubleshooting Common Issues
Connection Problems
“Connection Refused” Error
Verify SSH is running:
sudo systemctl status ssh
If stopped, start it:
sudo systemctl start ssh
Check network connectivity:
ping remote.server.com
Test port accessibility:
telnet remote.server.com 22
A successful connection indicates the port is open. Firewall blocking is the most common culprit—verify rules on both local and remote systems.
Authentication Failures
Permission Issues
SSH keys require specific permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
Incorrect permissions cause SSH to reject key-based authentication.
Wrong Username or Host
Double-check connection details:
ssh -v user@remote.server.com
The -v verbose flag displays detailed debugging information.
Tunnel-Specific Issues
“Port Already in Use”
Find the process using the port:
sudo lsof -i :1080
Kill it or choose a different port.
Tunnel Disconnecting
Install autossh for persistent tunnels:
sudo apt install autossh -y
Use it instead of regular SSH:
autossh -M 0 -D 1080 -N -f user@remote.server.com
Autossh monitors connections and automatically reconnects on failure.
Proxy Not Working
Test tunnel functionality:
curl --socks5 127.0.0.1:1080 https://api.ipify.org
This should return the remote server’s IP address. If not, verify the tunnel is running and proxy settings are correct.
Practical Use Cases and Examples
Secure Remote Work
Access company resources securely from any location by routing connections through a company SSH server. This encrypts traffic on untrusted networks like coffee shop WiFi, protecting credentials and sensitive data.
Create a system-wide SOCKS proxy for all applications, or use targeted local forwards for specific services like email servers, internal wikis, or development environments.
Development and Testing
Developers frequently need secure access to remote databases without exposing them directly to the internet. SSH tunnels provide this access safely.
Test webhooks from external services by using remote forwarding to expose your local development server. Services like payment processors or API providers can deliver webhooks to your local environment for testing before deployment.
Creating Persistent SSH Tunnels with Systemd
Systemd ensures tunnels start automatically and recover from failures. Create a service file:
sudo nano /etc/systemd/system/ssh-tunnel.service
Add this configuration:
[Unit]
Description=SSH Tunnel
After=network.target
[Service]
User=youruser
ExecStart=/usr/bin/ssh -D 1080 -N user@remote.server.com
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable ssh-tunnel
sudo systemctl start ssh-tunnel
Check status:
sudo systemctl status ssh-tunnel
The tunnel now starts automatically on boot and restarts if interrupted.
Congratulations! You have successfully use SSH Proxy Tunnel. Thanks for using this tutorial to create SSH Proxy Tunnel on Debian 13 “Trixie” system. For additional help or useful information, we recommend you check the official Debian website.