Linux SSH and Remote Access Guide
SSH (Secure Shell) is the standard for secure remote access to Linux systems. This guide covers SSH connections, key-based authentication, file transfer, and advanced techniques.
Overview: SSH Tools
| Tool | Purpose | Example |
|---|---|---|
ssh |
Remote shell access | ssh user@server |
scp |
Secure file copy | scp file.txt user@server:/path/ |
rsync |
Sync files/directories | rsync -av /local/ user@server:/remote/ |
ssh-keygen |
Generate SSH keys | ssh-keygen -t ed25519 |
ssh-copy-id |
Copy public key | ssh-copy-id user@server |
sftp |
Secure FTP | sftp user@server |
Basic SSH Usage
Connecting to Remote Server
# Basic connection
ssh user@hostname
# Specific port
ssh -p 2222 user@hostname
# With IP address
ssh user@192.168.1.100
# Verbose output (debugging)
ssh -v user@hostname
ssh -vv user@hostname # More verbose
ssh -vvv user@hostname # Most verbose
# Execute command and exit
ssh user@hostname "ls -la"
# Interactive shell
ssh -t user@hostname bash
SSH Configuration
# User SSH config
nano ~/.ssh/config
# Example configuration:
Host myserver
HostName server.example.com
User myusername
Port 22
IdentityFile ~/.ssh/id_ed25519
Host shortcut
HostName 192.168.1.100
User admin
Port 2222
# Now connect with:
ssh myserver
ssh shortcut
SSH Key-Based Authentication
Generating SSH Keys
# Generate Ed25519 key (recommended)
ssh-keygen -t ed25519 -C "your_email@example.com"
# Generate RSA key (compatibility)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# Specify custom filename
ssh-keygen -t ed25519 -f ~/.ssh/custom_key
# Generate without passphrase (not recommended)
ssh-keygen -t ed25519 -N ""
# Generate with specific comment
ssh-keygen -t ed25519 -C "work laptop"
Copying Public Key to Server
# Easiest method
ssh-copy-id user@hostname
# With specific key
ssh-copy-id -i ~/.ssh/custom_key.pub user@hostname
# Manual method
cat ~/.ssh/id_ed25519.pub | ssh user@hostname "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# Set correct permissions on server
ssh user@hostname "chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
Using SSH Keys
# Connect with default key
ssh user@hostname
# Connect with specific key
ssh -i ~/.ssh/custom_key user@hostname
# Add key to agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# List added keys
ssh-add -l
# Remove all keys from agent
ssh-add -D
Secure File Transfer
scp - Secure Copy
# Copy file to remote
scp file.txt user@server:/remote/path/
# Copy file from remote
scp user@server:/remote/file.txt /local/path/
# Copy directory recursively
scp -r directory/ user@server:/remote/path/
# Copy with specific port
scp -P 2222 file.txt user@server:/path/
# Copy with progress
scp -v file.txt user@server:/path/
# Copy with bandwidth limit (KB/s)
scp -l 1000 largefile.zip user@server:/path/
# Preserve file attributes
scp -p file.txt user@server:/path/
# Copy multiple files
scp file1.txt file2.txt user@server:/path/
# Copy from server to server
scp user@server1:/path/file.txt user@server2:/path/
rsync - Efficient Sync
# Basic sync
rsync -av source/ user@server:/dest/
# Sync with progress
rsync -avP source/ user@server:/dest/
# Sync with compression
rsync -avz source/ user@server:/dest/
# Sync and delete removed files
rsync -av --delete source/ user@server:/dest/
# Dry run (simulate)
rsync -avn source/ user@server:/dest/
# Exclude patterns
rsync -av --exclude='*.log' source/ user@server:/dest/
# Include/exclude
rsync -av --include='*.txt' --exclude='*' source/ user@server:/dest/
# Sync with bandwidth limit
rsync -av --bwlimit=1000 source/ user@server:/dest/
# Resume interrupted transfer
rsync -avP --partial source/ user@server:/dest/
# Sync over specific SSH port
rsync -av -e "ssh -p 2222" source/ user@server:/dest/
sftp - Secure FTP
# Connect to server
sftp user@hostname
# SFTP commands:
ls # List remote directory
lls # List local directory
pwd # Print remote directory
lpwd # Print local directory
cd /path # Change remote directory
lcd /path # Change local directory
get remotefile # Download file
put localfile # Upload file
get -r directory/ # Download directory
put -r directory/ # Upload directory
mkdir dirname # Create remote directory
rm filename # Delete remote file
exit # Exit sftp
SSH Port Forwarding and Tunneling
Local Port Forwarding
#Forward local port to remote server
ssh -L 8080:localhost:80 user@server
# Access via: http://localhost:8080
# Forward to different host through server
ssh -L 3306:database.internal:3306 user@gateway
# Multiple forwards
ssh -L 8080:localhost:80 -L 3306:localhost:3306 user@server
Remote Port Forwarding
# Forward remote port to local machine
ssh -R 8080:localhost:80 user@server
# Remote server can now access your local port 80 via localhost:8080
# Forward to different local machine
ssh -R 3000:192.168.1.100:3000 user@server
Dynamic Port Forwarding (SOCKS Proxy)
# Create SOCKS proxy
ssh -D 1080 user@server
# Configure browser to use localhost:1080 as SOCKS5 proxy
# With compression
ssh -D 1080 -C user@server
SSH Tunneling Examples
# Access internal web server
ssh -L 8080:intranet.internal:80 user@gateway
# Visit: http://localhost:8080
# Database tunnel
ssh -L 3306:mysql.internal:3306 user@gateway
# Connect: mysql -h 127.0.0.1 -P 3306
# RDP through SSH
ssh -L 3389:windows.internal:3389 user@gateway
# Connect RDP to: localhost:3389
Advanced SSH Techniques
SSH Connection Multiplexing
# Enable connection sharing in ~/.ssh/config
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h:%p
ControlPersist 10m
# Create socket directory
mkdir -p ~/.ssh/sockets
# Now multiple SSH connections will share single TCP connection
Persistent SSH Sessions
# Using screen
ssh user@server
screen
# Detach: Ctrl+A, D
# Reattach: screen -r
# Using tmux
ssh user@server
tmux new -s work
# Detach: Ctrl+B, D
# Reattach: tmux attach -t work
# Using autossh (auto-reconnect)
autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" user@server
SSH Jump Hosts
# Through jump host
ssh -J jumphost user@destination
# Multiple jump hosts
ssh -J jump1,jump2 user@destination
# In ~/.ssh/config:
Host destination
ProxyJump jumphost
SSH Agent Forwarding
# Forward SSH agent
ssh -A user@server
# In ~/.ssh/config:
Host server
ForwardAgent yes
# Warning: Only use on trusted servers!
SSH Security
Server Configuration
# Edit SSH server config
sudo nano /etc/ssh/sshd_config
# Recommended settings:
Port 22 # Change to non-standard port
PermitRootLogin no # Disable root login
PasswordAuthentication no # Use keys only
PubkeyAuthentication yes # Enable key authentication
MaxAuthTries 3 # Limit auth attempts
AllowUsers user1 user2 # Whitelist users
DenyUsers baduser # Blacklist users
ClientAliveInterval 300 # Keep connections alive
ClientAliveCountMax 2 # Auto-disconnect idle sessions
# Restart SSH service
sudo systemctl restart sshd
Client Security
# Disable password authentication
ssh -o PasswordAuthentication=no user@server
# Strict host key checking
ssh -o StrictHostKeyChecking=yes user@server
# In ~/.ssh/config:
Host *
StrictHostKeyChecking ask
HashKnownHosts yes
PasswordAuthentication no
SSH Keys Security
# Set correct permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/config
# Use passphrase for keys
ssh-keygen -t ed25519 -a 100
# Change key passphrase
ssh-keygen -p -f ~/.ssh/id_ed25519
Troubleshooting SSH
Connection Issues
# Test connection with verbose output
ssh -vvv user@hostname
# Test specific port
telnet hostname 22
nc -zv hostname 22
# Check SSH service status
sudo systemctl status sshd
# Check firewall
sudo ufw status
sudo iptables -L -n | grep 22
# Check SSH logs
sudo tail -f /var/log/auth.log # Debian/Ubuntu
sudo tail -f /var/log/secure # RHEL/CentOS
Permission Issues
# Fix SSH directory permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/*
chmod 644 ~/.ssh/*.pub
chmod 644 ~/.ssh/known_hosts
chmod 644 ~/.ssh/config
# Check authorized_keys
cat ~/.ssh/authorized_keys
# Server-side permissions
sudo ls -la /home/user/.ssh/
Key Authentication Not Working
# Check if key is added to agent
ssh-add -l
# Add key to agent
ssh-add ~/.ssh/id_ed25519
# Test with specific key
ssh -i ~/.ssh/id_ed25519 user@hostname
# Check server config
sudo grep -i pubkey /etc/ssh/sshd_config
# Check server logs for errors
sudo grep "sshd" /var/log/auth.log | tail -20
Useful SSH Tricks
SSH Escape Sequences
# During SSH session, press ~:
~. # Disconnect
~^Z # Suspend SSH session
~# # List of forwarded connections
~& # Background SSH when waiting for forwarded connections
SSH without Password Prompt
# Using SSH key with ssh-agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# Or use sshpass (not recommended for production)
sshpass -p 'password' ssh user@hostname
SSH with Timeout
# Connect with timeout
ssh -o ConnectTimeout=10 user@hostname
# Connection keep-alive
ssh -o ServerAliveInterval=60 user@hostname
Quick Reference
# Connect
ssh user@hostname # Basic connection
ssh -p 2222 user@hostname # Custom port
ssh -i key user@hostname # Specific key
# Generate keys
ssh-keygen -t ed25519 # Generate key
ssh-copy-id user@hostname # Copy public key
ssh-add ~/.ssh/key # Add to agent
# File transfer
scp file.txt user@host:/path/ # Copy file
scp -r dir/ user@host:/path/ # Copy directory
rsync -avz /local/ user@host:/remote/ # Sync
# Port forwarding
ssh -L 8080:localhost:80 user@host # Local forward
ssh -R 8080:localhost:80 user@host # Remote forward
ssh -D 1080 user@host # SOCKS proxy
# Config management
nano ~/.ssh/config # Edit config
sudo nano /etc/ssh/sshd_config # Server config
sudo systemctl restart sshd # Restart SSH
# Security
chmod 700 ~/.ssh # Fix permissions
chmod 600 ~/.ssh/id_ed25519 # Fix key permissions