SSH Cheat Sheet

Most used
ssh user@host                           # connect
ssh -p 2222 user@host                   # non-standard port
ssh-keygen -t ed25519 -C "you@laptop"   # create a key pair
ssh-copy-id user@host                   # install your public key on the server
scp file.txt user@host:/tmp/            # copy a file to the server
ssh -L 8080:localhost:80 user@host      # local port forward (tunnel)

This page covers the OpenSSH client and server shipped by every major distro. For a step-by-step setup of key login and disabling passwords, read how to set up SSH keys. If a connection fails, jump to troubleshooting.

Connecting

CommandWhat it does
ssh hostConnect as your local user name
ssh user@hostConnect as user
ssh -p 2222 user@hostCustom port
ssh -i ~/.ssh/work_ed25519 user@hostUse a specific private key
ssh user@host 'df -h'Run one command remotely and exit
ssh -t user@host 'sudo systemctl restart nginx'Force a terminal (needed for sudo prompts, top, vim)
ssh -J bastion user@internalConnect through a jump host
ssh -X user@hostX11 forwarding (-Y for trusted; only for X11 apps)
ssh -C user@hostCompress traffic (helps on slow links)
ssh -4 user@host / -6Force IPv4 or IPv6
ssh -v user@hostVerbose debug output (-vvv for more)
ssh -o ConnectTimeout=5 user@hostSet any config option on the command line

Keys and the agent

CommandWhat it does
ssh-keygen -t ed25519 -C "comment"New Ed25519 key pair (recommended)
ssh-keygen -t rsa -b 4096RSA key for old systems without Ed25519
ssh-keygen -t ed25519-skKey bound to a FIDO2 hardware token
ssh-keygen -p -f ~/.ssh/id_ed25519Change or add a passphrase
ssh-keygen -y -f ~/.ssh/id_ed25519Print the public key from a private key
ssh-keygen -lf ~/.ssh/id_ed25519.pubShow a key's fingerprint
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@hostAppend a public key to the server's authorized_keys
eval "$(ssh-agent -s)"Start an agent in the current shell
ssh-addAdd default keys to the agent
ssh-add -t 1h ~/.ssh/id_ed25519Add a key that expires after an hour
ssh-add -l / ssh-add -DList loaded keys / remove all
ssh -A user@hostForward your agent (only to hosts you trust)

Copying files

CommandWhat it does
scp file user@host:/path/Copy a local file to the server
scp user@host:/path/file .Copy from the server to the current directory
scp -r dir/ user@host:/path/Copy a directory recursively
scp -P 2222 file user@host:Custom port (capital P), into the home directory
scp -3 host1:/f host2:/fCopy between two remote hosts through your machine
sftp user@hostInteractive file transfer (put, get, ls, cd)
rsync -avz dir/ user@host:/path/dir/Sync a directory (only changed files are sent)
rsync -avz -e 'ssh -p 2222' dir/ user@host:/path/rsync over a custom SSH port
rsync -avP big.iso user@host:Show progress and resume partial transfers
sshfs user@host:/srv ~/mntMount a remote directory (package sshfs; unmount with fusermount3 -u ~/mnt)

Port forwarding and tunnels

CommandWhat it does
ssh -L 8080:localhost:80 user@hostLocal forward: localhost:8080 on your machine reaches port 80 on the server
ssh -L 5433:db.internal:5432 user@bastionReach a database the server can see but you can't
ssh -R 9000:localhost:3000 user@hostRemote forward: port 9000 on the server reaches port 3000 on your machine
ssh -D 1080 user@hostDynamic SOCKS5 proxy on localhost:1080
ssh -N -L 8080:localhost:80 user@hostTunnel only, no remote shell
ssh -fN -L 8080:localhost:80 user@hostSame, in the background
ssh -L 0.0.0.0:8080:localhost:80 user@hostLet other machines on your LAN use the tunnel

Client config: ~/.ssh/config

Settings here apply automatically, so ssh web1 replaces a long command line. The first value found for each option wins, so put specific Host blocks before Host *.

Host web1
    HostName 203.0.113.10
    User deploy
    Port 2222
    IdentityFile ~/.ssh/work_ed25519
    IdentitiesOnly yes

Host internal-*
    ProxyJump bastion

Host *
    AddKeysToAgent yes
    ServerAliveInterval 60
    ServerAliveCountMax 3
CommandWhat it does
ssh -G web1Print the final config that would be used for a host
ControlMaster auto + ControlPath ~/.ssh/cm-%r@%h:%p + ControlPersist 10mReuse one connection for later sessions (much faster repeat logins)
ssh -O exit web1Close a shared master connection
LocalForward 8080 localhost:80Config-file version of -L
Include ~/.ssh/config.d/*Split config into several files (put it at the top)

Server side (sshd)

Put changes in a drop-in such as /etc/ssh/sshd_config.d/50-local.conf instead of editing the main file. Always keep a working session open while you test.

CommandWhat it does
sudo sshd -tCheck the configuration for errors before restarting
sudo sshd -T | grep -i passwordauthShow the effective value of a setting
sudo systemctl restart sshRestart on Debian/Ubuntu (unit name ssh)
sudo systemctl restart sshdRestart on Fedora, Arch, openSUSE (unit name sshd)
PasswordAuthentication noKeys only (set up keys first)
PermitRootLogin noBlock direct root login (prohibit-password allows keys only)
AllowUsers alice bobOnly these users may log in
sudo ss -tlnp | grep sshConfirm sshd is listening and on which port
journalctl -u ssh -fFollow sshd logs (-u sshd on Fedora/Arch)

On Ubuntu 22.10 and later, sshd is started by ssh.socket. If you change Port, run sudo systemctl daemon-reload and sudo systemctl restart ssh.socket so the socket listens on the new port. On Fedora with SELinux, a new port also needs sudo semanage port -a -t ssh_port_t -p tcp 2222. More on unit names in the systemctl cheat sheet.

Troubleshooting connections

CommandWhat it does
ssh -vvv user@hostSee exactly where authentication fails
ssh-keygen -R hostRemove an old host key after a legitimate reinstall (see REMOTE HOST IDENTIFICATION HAS CHANGED)
chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keysFix permissions that make sshd ignore your key (Permission denied (publickey))
nc -zv host 22Check whether the port is reachable (Connection refused)
ssh -o PubkeyAuthentication=no user@hostTest password login on its own
Enter, then ~.Kill a hung session; ~? lists all escape sequences

Common recipes

Run a long job that survives disconnects (see the tmux cheat sheet):

ssh -t user@host 'tmux new -A -s main'

Open a remote web admin panel that only listens on the server's localhost:

ssh -N -L 9090:localhost:9090 admin@server
# then browse to http://localhost:9090

Run the same command on several servers:

for h in web1 web2 db1; do
    echo "== $h"; ssh "$h" 'uptime'
done

Copy your public key manually when ssh-copy-id is not available:

cat ~/.ssh/id_ed25519.pub | ssh user@host 'mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'

Back up a remote database straight to your machine:

ssh db1 'sudo -u postgres pg_dump mydb | gzip' > mydb-$(date +%F).sql.gz

Compare a remote file with a local one:

diff <(ssh web1 cat /etc/nginx/nginx.conf) /etc/nginx/nginx.conf

Gotchas

  • -p vs -P. ssh uses lowercase -p for the port; scp and sftp use uppercase -P (lowercase -p means "preserve times").
  • Service name differs. The unit is ssh on Debian/Ubuntu/Mint and sshd on Fedora/Arch/openSUSE. The package to install is openssh-server (apt, dnf, zypper) or openssh (pacman).
  • Permissions are strict. sshd ignores authorized_keys if your home, ~/.ssh or the file is writable by others. Private keys must be 600 or the client refuses them.
  • Too many keys. With many keys in the agent, the server may disconnect with "Too many authentication failures" before the right key is tried. Use IdentitiesOnly yes with IdentityFile.
  • scp uses SFTP now. Current OpenSSH scp transfers over the SFTP protocol. Remote paths with spaces need only normal quoting; scp -O forces the legacy protocol for very old servers.
  • Agent forwarding is a risk. Anyone with root on the remote host can use your forwarded agent. Prefer ProxyJump (-J) for hopping through bastions.
  • Lockout risk. Test with sshd -t and a second session before closing the first one after any change to sshd or the firewall.

Reference: ssh(1) and ssh_config(5) in the OpenBSD manual pages (OpenSSH upstream).

Frequently asked questions

How do I SSH on a different port?

Use ssh -p 2222 user@host. For scp the flag is a capital -P: scp -P 2222 file user@host:.

How do I copy files over SSH?

scp file user@host:/path/ for quick copies, or rsync -avz dir/ user@host:/path/ for directories and resumable transfers.

What is the difference between -L and -R port forwarding?

-L opens a port on your machine that forwards to something reachable from the server. -R opens a port on the server that forwards back to something reachable from your machine.

How do I stop SSH asking for my key passphrase every time?

Load the key into an agent with ssh-add, or set AddKeysToAgent yes in ~/.ssh/config. GNOME and KDE start an agent automatically.

How do I get out of a frozen SSH session?

Press Enter, then type ~. (tilde, period). This escape sequence closes the connection from the client side.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.