Cheat Sheets

SSH Commands Cheat Sheet for Linux SysAdmins

A quick reference of OpenSSH commands and options for daily Linux and Unix system administration. Covers connections, key management, tunneling, file transfers, config shortcuts, and troubleshooting.

Original content from computingforgeeks.com - post 1284

Current as of March 2026. Tested with OpenSSH 9.9p1 on Rocky Linux 10.1 and OpenSSH 9.6p1 on Ubuntu 24.04

Basic SSH Connections

Connect to a remote server:

# Connect as current user
ssh server.example.com

# Connect as a specific user
ssh [email protected]

# Connect with a specific private key
ssh -i ~/.ssh/id_ed25519 [email protected]

# Connect to a non-standard port
ssh -p 2222 [email protected]

# Connect with verbose output (debugging)
ssh -v [email protected]
ssh -vv [email protected]   # more verbose
ssh -vvv [email protected]  # maximum verbosity

SSH Key Generation and Management

Generate SSH key pairs for passwordless authentication:

# Generate Ed25519 key (recommended, fastest, most secure)
ssh-keygen -t ed25519 -C "admin@server"

# Generate RSA 4096-bit key (wider compatibility)
ssh-keygen -t rsa -b 4096 -C "admin@server"

# Generate key with custom filename
ssh-keygen -t ed25519 -f ~/.ssh/myserver_key

# Generate key without passphrase (automation use only)
ssh-keygen -t ed25519 -f ~/.ssh/deploy_key -N ""

Copy your public key to a remote server for passwordless login:

# Standard method
ssh-copy-id [email protected]

# Copy a specific key
ssh-copy-id -i ~/.ssh/myserver_key.pub [email protected]

# Copy to a non-standard port
ssh-copy-id -p 2222 [email protected]

To change or update an SSH key passphrase:

ssh-keygen -p -f ~/.ssh/id_ed25519

View the fingerprint of a key:

ssh-keygen -lf ~/.ssh/id_ed25519.pub

SSH Agent and Key Caching

The SSH agent caches decrypted private keys so you enter the passphrase once per session:

# Start the agent
eval $(ssh-agent)

# Add default key (~/.ssh/id_ed25519 or ~/.ssh/id_rsa)
ssh-add

# Add a specific key
ssh-add ~/.ssh/myserver_key

# Add key with a timeout (seconds) - auto-removed after expiry
ssh-add -t 3600 ~/.ssh/id_ed25519

# List loaded keys
ssh-add -l

# Remove all keys from agent
ssh-add -D

Forward the agent to a remote server (allows hopping to other servers without copying keys):

ssh -A [email protected]

SSH Config File (~/.ssh/config)

The SSH config file saves connection settings so you don’t type them every time. Create or edit ~/.ssh/config:

# Simple host alias
Host webserver
    HostName 192.168.1.50
    User admin
    Port 2222
    IdentityFile ~/.ssh/webserver_key

# Bastion/jump host setup
Host bastion
    HostName bastion.example.com
    User jumpuser

Host internal-db
    HostName 10.0.1.100
    User dbadmin
    ProxyJump bastion

# Wildcard for all hosts in a domain
Host *.prod.example.com
    User deploy
    IdentityFile ~/.ssh/prod_key
    StrictHostKeyChecking no

# Keep connections alive (prevent timeouts)
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

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

After configuring, connect with just the alias:

ssh webserver
ssh internal-db

For a deeper dive, see our guide on managing SSH connections with the config file.

Remote Command Execution

Run a command on a remote server without opening an interactive shell:

# Run a single command
ssh admin@server 'uptime'

# Run multiple commands
ssh admin@server 'df -h && free -m'

# Run commands that need a TTY (e.g., sudo, top)
ssh -t admin@server 'sudo systemctl restart nginx'

# Run a local script on the remote server
ssh admin@server 'bash -s' < local_script.sh

Example - check disk usage on a remote host:

$ ssh admin@webserver 'df -h /'
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        50G   12G   36G  25% /

File Transfer - SCP and SFTP

Copy files between local and remote systems using SCP:

# Copy local file to remote server
scp file.txt admin@server:/tmp/

# Copy remote file to local machine
scp admin@server:/var/log/syslog ./syslog.txt

# Copy entire directory recursively
scp -r /local/dir admin@server:/remote/dir

# SCP with non-standard port (uppercase -P)
scp -P 2222 file.txt admin@server:/tmp/

# Copy with bandwidth limit (in Kbit/s)
scp -l 5000 largefile.tar.gz admin@server:/data/

For a complete reference, see using SCP on Linux to securely transfer files.

Use SFTP for interactive file transfer sessions:

# Start an SFTP session
sftp admin@server

# SFTP with non-standard port (uppercase -P)
sftp -P 2222 admin@server

# Common SFTP commands inside the session:
# put localfile.txt       - Upload file
# get remotefile.txt      - Download file
# ls                      - List remote files
# lls                     - List local files
# cd /remote/path         - Change remote directory
# lcd /local/path         - Change local directory
# mkdir dirname           - Create remote directory
# rm filename             - Delete remote file
# bye                     - Exit session

Copy files over SSH using tar (useful when scp/rsync is unavailable):

# Compress and copy remote files to local machine
ssh admin@server "tar czf - /var/log/nginx/" | tar xzf - -C /tmp/

# Push local directory to remote server
tar czf - /local/dir/ | ssh admin@server "tar xzf - -C /remote/path/"

Transfer Directories and Streams Over SSH

Beyond SCP and SFTP, SSH works as a transport layer for any data stream. These patterns are especially useful for large directories, database backups, and log collection.

Transfer an entire directory using tar piped over SSH:

tar czf - -C /path directory | ssh user@host "tar xzf - -C /remote/path"

This compresses locally, streams over the encrypted channel, and extracts on the remote side in a single pipeline. No intermediate archive file needed.

Sync files with rsync over SSH (incremental, only transfers changes):

rsync -avz -e ssh /local/dir/ user@host:/remote/dir/

Rsync output shows each transferred file and a summary:

sending incremental file list
config/
config/app.conf
config/db.conf
static/
static/logo.png

sent 24,518 bytes  received 104 bytes  16,414.67 bytes/sec
total size is 89,230  speedup is 3.62

Pipe a PostgreSQL database dump directly to a remote backup server:

pg_dumpall | ssh user@backup-server "cat > /backups/db-$(date +%F).sql"

Pull a remote log file and compress it locally in one step:

ssh user@host "cat /var/log/syslog" | gzip > remote-syslog.gz

SSH Port Forwarding and Tunnels

Local Port Forwarding (-L)

Forward a local port to a remote service. Access a remote service as if it were running locally:

# Forward local port 8080 to remote port 80
ssh -L 8080:localhost:80 admin@server

# Access a database behind a firewall
ssh -L 3306:db-server:3306 admin@bastion

# Run in background (-f) with no remote command (-N)
ssh -f -N -L 8080:internal-app:8080 admin@bastion

After running, open http://localhost:8080 in your browser to access the remote service.

Remote (Reverse) Port Forwarding (-R)

Expose a local service to the remote server:

# Make local port 3000 available as port 9000 on the remote server
ssh -R 9000:localhost:3000 admin@server

# Run in background
ssh -f -N -R 9000:localhost:3000 admin@server

SOCKS Proxy (-D)

Create a SOCKS5 proxy for tunneling all traffic through the SSH server:

# Create SOCKS proxy on local port 9999
ssh -D 9999 admin@server

# Run in background
ssh -f -N -D 9999 admin@server

Configure your browser to use localhost:9999 as a SOCKS5 proxy. All browser traffic routes through the SSH server. Both SOCKS4 and SOCKS5 protocols are supported.

For more tunnel patterns, see our guide on creating SSH tunnels on Linux.

Jump Hosts and ProxyJump

Access servers behind a bastion/jump host without intermediate shell sessions:

# Jump through a bastion to reach an internal server
ssh -J bastion.example.com [email protected]

# Multiple jumps (chain bastions)
ssh -J bastion1,bastion2 admin@internal-server

# With specific user and port on the jump host
ssh -J jumpuser@bastion:2222 [email protected]

This replaces the older ProxyCommand method and is cleaner. Set it permanently in ~/.ssh/config with the ProxyJump directive.

X11 Forwarding

Run graphical applications on a remote server and display them locally:

# Enable X11 forwarding
ssh -X admin@server

# Trusted X11 forwarding (less restrictions, use with trusted servers)
ssh -Y admin@server

# Launch a specific application
ssh -X admin@server 'firefox'
ssh -X admin@server 'virt-manager'

The remote server must have X11Forwarding yes in /etc/ssh/sshd_config and xauth installed.

SSH Multiplexing

Reuse a single TCP connection for multiple SSH sessions to the same host. Speeds up repeated connections and reduces authentication overhead:

# Create the socket directory
mkdir -p ~/.ssh/sockets

Add to ~/.ssh/config:

Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

Check and manage multiplexed connections:

# Check connection status
ssh -O check admin@server

# Terminate a shared connection
ssh -O exit admin@server

SSH Escape Sequences

Escape sequences are entered after pressing Enter, then the tilde (~) character:

~.     - Disconnect (kill frozen session)
~^Z    - Suspend SSH session (background it)
~#     - List forwarded connections
~&     - Background SSH when waiting for connections to close
~?     - Show all escape sequences
~C     - Open SSH command line (add port forwards on the fly)
~~     - Send a literal tilde

The ~. escape is especially useful for killing a frozen SSH session when the remote host becomes unresponsive and Ctrl+C does nothing.

Mount Remote Filesystem with SSHFS

Mount a remote directory over SSH as a local filesystem using SSHFS:

# Mount remote directory
sshfs admin@server:/var/www /mnt/remote-www

# Mount with specific port
sshfs -p 2222 admin@server:/data /mnt/remote-data

# Mount with specific SSH key
sshfs -o IdentityFile=~/.ssh/mykey admin@server:/data /mnt/remote-data

# Unmount
fusermount -u /mnt/remote-www

SSH Certificate Authentication

SSH certificates solve a real scaling problem. Instead of copying individual public keys to every server's authorized_keys, you sign user keys with a Certificate Authority (CA) and configure servers to trust that CA. One config change on the server, and any signed key is accepted.

Generate a CA key pair:

ssh-keygen -t ed25519 -f /tmp/ssh_ca -N ""

Sign a user's public key with the CA:

ssh-keygen -s /tmp/ssh_ca -I myuser-cert -n root -V +52w /tmp/user_key.pub

The output confirms the signed certificate and its validity window:

Signed user key /tmp/user_key-cert.pub: id "myuser-cert" serial 0 for root valid from 2026-03-25T13:36:00 to 2027-03-24T13:37:54

Inspect the certificate to verify its contents:

ssh-keygen -Lf /tmp/user_key-cert.pub

The certificate details show the key type, validity period, allowed principals, and extensions:

/tmp/user_key-cert.pub:
        Type: [email protected] user certificate
        Public key: ED25519-CERT SHA256:xR3tVqMOoXCfQPbU8oAaYNgiK1rfZQXpLa5Zh8VKU2M
        Signing CA: ED25519 SHA256:mP2n3LkqFbTge7WBsXo1YbklHv9K7sEzOGFn9Lmario (using ssh-ed25519)
        Key ID: "myuser-cert"
        Serial: 0
        Valid: from 2026-03-25T13:36:00 to 2027-03-24T13:37:54
        Principals:
                root
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc

To make a server trust this CA, add the CA public key and configure sshd_config:

sudo cp /tmp/ssh_ca.pub /etc/ssh/ca.pub

Open the sshd configuration file:

sudo vi /etc/ssh/sshd_config

Add the following line:

TrustedUserCAKeys /etc/ssh/ca.pub

Restart sshd to apply:

sudo systemctl restart sshd

Any user presenting a key signed by this CA can now log in without their public key being in authorized_keys. For environments with dozens or hundreds of servers, this eliminates the key distribution headache entirely.

Known Hosts Management

Manage the ~/.ssh/known_hosts file which stores server fingerprints:

# Remove a host entry (after server rebuild/IP change)
ssh-keygen -R server.example.com
ssh-keygen -R 192.168.1.50

# Scan and display a server's host keys
ssh-keyscan server.example.com

# Add a host key to known_hosts without connecting
ssh-keyscan -H server.example.com >> ~/.ssh/known_hosts

For more on managing host key checks, see how to disable SSH host key checking.

SSH Hardening Quick Reference

Key settings to change in /etc/ssh/sshd_config for production servers:

# Disable password authentication (use keys only)
PasswordAuthentication no

# Disable root login
PermitRootLogin no

# Restrict to specific users
AllowUsers admin deploy

# Change default port
Port 33000

# Disable empty passwords
PermitEmptyPasswords no

# Set login grace time
LoginGraceTime 30

# Limit authentication attempts
MaxAuthTries 3

# Disable X11 forwarding (if not needed)
X11Forwarding no

After editing, validate and restart:

sudo sshd -t && sudo systemctl restart sshd

To change the SSH port on RHEL/Rocky Linux with SELinux, you also need to relabel the port with semanage. For an extra security layer, set up SSH two-factor authentication.

Debug SSH Connections

When a connection fails or behaves unexpectedly, the -v flag reveals what SSH is actually doing under the hood. Each additional v increases detail:

# Basic debug output
ssh -v user@host

# More detail (key exchange, authentication steps)
ssh -vv user@host

# Maximum verbosity (packet-level)
ssh -vvv user@host

A successful connection with -v produces output like this (key lines to watch for):

debug1: Connection established.
debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: server->client cipher: [email protected]
debug1: Server host key: ssh-ed25519 SHA256:P8odc80FL2b1H7ch7W1odskiLoaBhwr9BGOClmZlN20
debug1: Host '192.168.1.134' is known and matches the ED25519 host key.
Authenticated to 192.168.1.134

The key exchange (kex) lines tell you which algorithms were negotiated. If the connection stalls before "Connection established," the issue is network level (firewall, DNS, routing). If it stalls after key exchange but before "Authenticated," the problem is authentication: wrong key, missing authorized_keys entry, or permission issues on ~/.ssh.

Troubleshooting SSH Connections

# Debug connection issues (verbose mode)
ssh -vvv admin@server

# Test SSH config syntax before restart
sudo sshd -t

# Check if sshd is listening
ss -tlnp | grep sshd

# Check SSH service status
systemctl status sshd

# View auth logs (RHEL/Rocky/Fedora)
sudo journalctl -u sshd -f

# View auth logs (Debian/Ubuntu)
sudo tail -f /var/log/auth.log

# Fix permissions (common cause of key auth failure)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/config

Quick Reference Table

CommandDescription
ssh user@hostConnect to remote host
ssh -p 2222 user@hostConnect on custom port
ssh -i key user@hostConnect with specific key
ssh -J jump user@hostConnect via jump host
ssh -L 8080:host:80 user@gwLocal port forward
ssh -R 9000:localhost:3000 user@hostReverse port forward
ssh -D 9999 user@hostSOCKS proxy
ssh -X user@hostX11 forwarding
ssh -A user@hostAgent forwarding
ssh user@host 'command'Run remote command
ssh-keygen -t ed25519Generate Ed25519 key
ssh-copy-id user@hostCopy public key to server
ssh-addAdd key to agent
ssh-keyscan hostFetch host public key
ssh-keygen -R hostRemove host from known_hosts
scp file user@host:/pathCopy file to remote
scp user@host:/path fileCopy file from remote
sftp user@hostInteractive file transfer
sshfs user@host:/dir /mntMount remote directory
tar czf - dir | ssh user@host "tar xzf - -C /path"Transfer directory over SSH
rsync -avz -e ssh src/ user@host:dst/Sync with rsync over SSH
ssh -v user@hostDebug connection
ssh-keygen -s ca -I id -n user key.pubSign key with CA
ssh-keygen -Lf cert.pubInspect certificate
ssh-keygen -lf key.pubShow key fingerprint

For SSH security best practices, cipher recommendations, and the full configuration reference, the official OpenSSH man pages at openssh.com are the authoritative source.

Related Articles

Automation Install Chef Server & Workstation on Ubuntu 20.04 Linux Mint How To Configure NFS File Sharing on Linux Mint 22|21 Debian Install SVN (Subversion) Server on Ubuntu 24.04 / Debian 13 Desktop Install Cinnamon Desktop on Ubuntu 22.04 or Ubuntu 20.04

Leave a Comment

Press ESC to close