SSH

Essential SSH commands for secure remote access and file transfers.

cli
sshlinuxsecurityterminalnetworking

Basic Connection

# Connect to remote host
ssh user@hostname
ssh user@192.168.1.100

# Connect on specific port
ssh -p 2222 user@hostname

# Connect with specific identity file
ssh -i ~/.ssh/my_key user@hostname

# Connect with verbose output (debugging)
ssh -v user@hostname
ssh -vv user@hostname   # More verbose
ssh -vvv user@hostname  # Maximum verbosity

Key Management

# Generate SSH key pair (Ed25519 - recommended)
ssh-keygen -t ed25519 -C "your_email@example.com"

# Generate RSA key (4096 bits)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# Generate key with specific filename
ssh-keygen -t ed25519 -f ~/.ssh/my_custom_key

# Copy public key to remote server
ssh-copy-id user@hostname
ssh-copy-id -i ~/.ssh/my_key.pub user@hostname

# Copy key manually
cat ~/.ssh/id_ed25519.pub | ssh user@hostname "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

# Change passphrase on existing key
ssh-keygen -p -f ~/.ssh/id_ed25519

# View key fingerprint
ssh-keygen -lf ~/.ssh/id_ed25519.pub

# Remove host from known_hosts
ssh-keygen -R hostname

SSH Agent

# Start SSH agent
eval "$(ssh-agent -s)"

# Add key to agent
ssh-add ~/.ssh/id_ed25519

# Add key with specific lifetime (seconds)
ssh-add -t 3600 ~/.ssh/id_ed25519

# List keys in agent
ssh-add -l

# Remove all keys from agent
ssh-add -D

# Remove specific key
ssh-add -d ~/.ssh/id_ed25519

File Transfer with SCP

# Copy file to remote
scp file.txt user@hostname:/path/to/destination/

# Copy file from remote
scp user@hostname:/path/to/file.txt ./local/

# Copy directory recursively
scp -r ./local_dir user@hostname:/remote/path/

# Copy with specific port
scp -P 2222 file.txt user@hostname:/path/

# Copy with specific key
scp -i ~/.ssh/my_key file.txt user@hostname:/path/

# Preserve file attributes
scp -p file.txt user@hostname:/path/

File Transfer with SFTP

# Start SFTP session
sftp user@hostname

# SFTP with specific port
sftp -P 2222 user@hostname

# Common SFTP commands
# ls              - List remote directory
# lls             - List local directory
# cd path         - Change remote directory
# lcd path        - Change local directory
# get file        - Download file
# put file        - Upload file
# mget *.txt      - Download multiple files
# mput *.txt      - Upload multiple files
# mkdir dir       - Create remote directory
# rm file         - Delete remote file
# exit            - Close session

Port Forwarding

# Local port forwarding (access remote service locally)
# Forward local:8080 to remote:80
ssh -L 8080:localhost:80 user@hostname

# Forward to a third host through SSH server
ssh -L 8080:internal.server:80 user@gateway

# Remote port forwarding (expose local service remotely)
# Forward remote:8080 to local:3000
ssh -R 8080:localhost:3000 user@hostname

# Dynamic port forwarding (SOCKS proxy)
ssh -D 9090 user@hostname

# Keep tunnel open without shell
ssh -N -L 8080:localhost:80 user@hostname

# Run in background
ssh -f -N -L 8080:localhost:80 user@hostname

Jump Hosts / Bastion

# Connect through jump host
ssh -J jumpuser@jumphost user@destination

# Multiple jump hosts
ssh -J user1@host1,user2@host2 user@destination

# Using ProxyJump in config (preferred)
# See SSH Config section below

# Legacy ProxyCommand method
ssh -o ProxyCommand="ssh -W %h:%p jumpuser@jumphost" user@destination

Remote Commands

# Execute single command
ssh user@hostname "ls -la"

# Execute multiple commands
ssh user@hostname "cd /var/log && tail -100 syslog"

# Run command with sudo
ssh user@hostname "sudo systemctl restart nginx"

# Run local script on remote
ssh user@hostname 'bash -s' < local_script.sh

# Run command in background
ssh user@hostname "nohup ./long_running.sh &"

SSH Config File

# Location: ~/.ssh/config

# Basic host configuration
Host myserver
    HostName 192.168.1.100
    User admin
    Port 22
    IdentityFile ~/.ssh/my_key

# Jump host configuration
Host internal
    HostName 10.0.0.5
    User developer
    ProxyJump bastion

Host bastion
    HostName bastion.example.com
    User jumpuser
    IdentityFile ~/.ssh/bastion_key

# Wildcard configuration
Host *.example.com
    User deploy
    IdentityFile ~/.ssh/deploy_key

# Keep connections alive
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

# Multiplexing (reuse connections)
Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

Tunneling Examples

# Access remote MySQL locally
ssh -L 3306:localhost:3306 user@dbserver

# Access remote web app
ssh -L 8080:localhost:80 user@webserver

# Access internal service through bastion
ssh -L 5432:internal-db:5432 user@bastion

# Create SOCKS proxy for browsing
ssh -D 8080 -f -C -q -N user@hostname

# Reverse tunnel (expose local dev server)
ssh -R 80:localhost:3000 user@public-server

Security Best Practices

# Disable password authentication (in /etc/ssh/sshd_config)
# PasswordAuthentication no

# Disable root login
# PermitRootLogin no

# Use specific allowed users
# AllowUsers admin deploy

# Change default port
# Port 2222

# Set proper permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/authorized_keys

# Test SSH config syntax
sshd -t

Troubleshooting

# Debug connection issues
ssh -vvv user@hostname

# Check SSH service status
systemctl status sshd

# View SSH logs
sudo tail -f /var/log/auth.log      # Debian/Ubuntu
sudo tail -f /var/log/secure        # RHEL/CentOS

# Test connection without logging in
ssh -o BatchMode=yes -o ConnectTimeout=5 user@hostname echo ok

# Check open SSH connections
ss -tnp | grep ssh
netstat -tnp | grep ssh

# Kill stuck SSH session
# Press: ~.  (tilde, then period)

Options Reference

OptionDescription
-pSpecify port number
-iIdentity file (private key)
-lLogin name
-vVerbose mode (use -vv or -vvv for more)
-qQuiet mode
-NNo remote command (for tunnels)
-fGo to background
-LLocal port forwarding
-RRemote port forwarding
-DDynamic port forwarding (SOCKS)
-JJump host
-XEnable X11 forwarding
-YTrusted X11 forwarding
-CEnable compression
-AAgent forwarding
-tForce pseudo-terminal allocation
-oSpecify config option