SSH: Advanced SSH — Tunneling, SCP, SFTP, and Server Hardening

Advanced SSH techniques including local and remote port forwarding, dynamic SOCKS proxy, SCP and SFTP file transfer, SSH multiplexing, server hardening, Fail2Ban setup, and troubleshooting SSH connections.

Advanced SSH Capabilities

Beyond basic remote access, SSH provides a powerful set of features for secure network tunneling, file transfer, and connection optimization. This guide covers:

  • Port forwarding (local, remote, dynamic)
  • File transfer with SCP and SFTP
  • SSH multiplexing for performance
  • Server hardening to reduce attack surface
  • Troubleshooting and debugging

Tunneling and Port Forwarding

SSH port forwarding (also called SSH tunneling) allows you to securely route traffic for other protocols through an encrypted SSH connection. This is useful for:

  • Accessing internal services through a firewall
  • Encrypting otherwise cleartext protocols
  • Bypassing network restrictions securely

Local Port Forwarding (-L)

Forward a local port through the SSH server to a remote destination. Traffic sent to the local port is forwarded through the SSH tunnel to the remote host.

bash
ssh -L 8080:localhost:80 user@remote_host

# Explanation:
# -L 8080:localhost:80
#    8080       → local port on your machine
#    localhost  → destination from the SSH server's perspective
#    80         → destination port on the remote end

After running this, accessing http://localhost:8080 on your machine sends traffic through the SSH tunnel to port 80 on remote_host.

md
Use Case: Access a web server running on remote_host:80
locally via localhost:8080, even if port 80 is firewalled.

Your Machine:8080 --> SSH Tunnel --> remote_host:80

Remote Port Forwarding (-R)

Forward a port on the remote server back to your local machine. Allows the remote server to access a service running locally.

bash
ssh -R 9090:localhost:22 user@remote_host

# Explanation:
# -R 9090:localhost:22
#    9090       → port opened on remote_host
#    localhost  → destination from your machine's perspective
#    22         → local port to forward to (SSH on your machine)

After running this, anyone connecting to remote_host:9090 is forwarded back to port 22 on your local machine.

md
Use Case: Allow remote_host to SSH back into your local machine
when your machine is behind NAT or a firewall.

remote_host:9090 --> SSH Tunnel --> YourMachine:22

Dynamic SOCKS Proxy (-D)

Create a SOCKS proxy server that routes traffic dynamically through the SSH connection. Works with any application that supports SOCKS5.

bash
ssh -D 8080 user@remote_host

After running this, configure your browser or application to use localhost:8080 as a SOCKS5 proxy — all traffic routes through remote_host.

md
Use Case: Route web browsing through a remote server
to access geo-restricted content or bypass local network restrictions.

Application --> SOCKS5 localhost:8080 --> SSH Tunnel --> remote_host --> Internet


Copying Files with SCP

SCP (Secure Copy Protocol) transfers files securely over SSH. It uses the same authentication and encryption as SSH.

Copy File TO Remote Server

bash
# Basic copy to remote
scp file.txt user@remote_host:/path/to/destination

# Copy with non-default SSH port
scp -P 2222 /local-files user@ip-address:remote-files

# Practical example
scp -P 2222 /opt/test user@192.168.1.100:~/Downloads

Copy File FROM Remote Server

bash
# Copy file from remote to current local directory
scp user@remote_host:/path/to/file.txt .

# Copy directory recursively
scp -r user@remote_host:/remote/directory/ ./local-copy/

SCP Options

OptionDescription
-P <port>Specify non-default SSH port
-rRecursively copy directories
-i <keyfile>Use specific identity file
-vVerbose output for debugging
-CEnable compression

Secure File Transfer with SFTP

SFTP (SSH File Transfer Protocol) provides an interactive file transfer session with a command-line interface similar to FTP, but fully encrypted.

bash
# Connect to remote SFTP server
sftp user@remote_host

# Connect on a custom port
sftp -P 2222 user@remote_host

SFTP Interactive Commands

Once connected:

bash
# Download a file from remote to local
get remote_file.txt

# Download entire directory
get -r remote_directory/

# Upload a local file to remote
put local_file.txt

# Upload entire directory
put -r local_directory/

# List remote directory contents
ls

# List local directory contents
lls

# Change remote directory
cd /path/on/remote

# Change local directory
lcd /path/on/local

# Create remote directory
mkdir new_directory

# Remove remote file
rm remote_file.txt

# Exit SFTP session
exit


SSH Multiplexing for Faster Connections

SSH multiplexing allows multiple SSH sessions to share a single TCP connection. This dramatically speeds up subsequent connections to the same host because the authentication handshake only happens once.

bash
# Add to ~/.ssh/config
echo "
Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 10m" >> ~/.ssh/config

Create the sockets directory:

bash
mkdir -p ~/.ssh/sockets

md
With multiplexing:
First connection: full SSH handshake (normal speed)
Subsequent connections to same host: reuse socket (near-instant)

Useful for: deployment scripts, Ansible, git operations over SSH


SSH Escape Sequences

When connected to a remote host, SSH provides escape sequences for session control. The escape character is ~ (tilde) followed by a command:

SequenceAction
~.Kill a hung or unresponsive SSH session
~^ZSuspend the SSH session (send to background)
~#List forwarded connections
~?Display help for escape sequences

The escape character only works when typed after a newline.


Securing the SSH Server

Change the Default SSH Port

Moving SSH off port 22 reduces exposure to automated scanners and brute-force bots that target the default port.

bash
sudo nano /etc/ssh/sshd_config

# Find and change:
Port 22
# To:
Port 2222

sudo systemctl restart ssh

Disable Root Login

Never allow direct root SSH access. Require users to authenticate as a regular user and escalate with sudo:

bash
# In /etc/ssh/sshd_config:
PermitRootLogin no

Restrict Which Users Can Connect

Limit SSH access to specific users:

bash
# In /etc/ssh/sshd_config:
AllowUsers user1 user2

Disable Password Authentication

Once key-based authentication is configured and tested, disable password authentication to prevent brute-force attacks:

bash
# In /etc/ssh/sshd_config:
PasswordAuthentication no
PubkeyAuthentication yes

Complete Hardened sshd_config Snippet

bash
Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers user1 user2
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2


Using Fail2Ban to Prevent Brute-Force Attacks

Fail2Ban monitors SSH log files and automatically blocks IP addresses that show signs of brute-force attacks (multiple failed authentication attempts).

bash
# Install Fail2Ban
sudo apt install fail2ban

# Enable and start the service
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Fail2Ban's default SSH jail monitors /var/log/auth.log and bans IPs with more than 5 failed attempts within 10 minutes for 10 minutes.


Troubleshooting SSH Issues

Checking SSH Logs

bash
# View recent SSH log entries
journalctl -u ssh --no-pager | tail -n 20

# Watch SSH logs in real time
journalctl -u ssh -f

Common log messages and their meanings:

  • Accepted publickey for user — successful key authentication
  • Failed password for user — failed password attempt
  • Invalid user admin — attempt to log in as a non-existent user
  • Connection closed by authenticating user — connection dropped during auth

Debugging SSH Connection

bash
# Maximum verbosity SSH connection debug
ssh -vvv user@remote_host

# Look for:
# "Offering public key:" → which keys are being offered
# "Authenticated to host" → successful auth
# "Permission denied" → auth failed

The three levels of -v progressively reveal more internal SSH negotiation detail:

  • -v — basic connection and authentication steps
  • -vv — key exchange and cipher negotiation
  • -vvv — full packet-level debugging

SSH Security Hardening Summary

md
Essential SSH Hardening Checklist:
├── Change default port from 22 to a high port
├── Disable root login (PermitRootLogin no)
├── Disable password authentication after setting up keys
├── Restrict access to specific users (AllowUsers)
├── Install and configure Fail2Ban
├── Set MaxAuthTries to 3
├── Use strong key types: Ed25519 or RSA-4096
├── Rotate SSH keys periodically
└── Monitor /var/log/auth.log for suspicious patterns