Skip to content

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