Keys
# New key (Ed25519 is the default choice today)
ssh-keygen -t ed25519 -C "alice@laptop"
# Choose the file name with -f (default is ~/.ssh/id_<type>)
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_work -C "alice@work"
ssh -i ~/.ssh/id_ed25519_work alice@host # use it (or IdentityFile in ~/.ssh/config)
# Fingerprint of a key, to compare with what a server shows
ssh-keygen -lf ~/.ssh/id_ed25519.pub
# Change or add a passphrase
ssh-keygen -p -f ~/.ssh/id_ed25519
# Load the key into the agent once per session
eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519| Key type | Command | Notes |
|---|---|---|
| Ed25519 | ssh-keygen -t ed25519 | Fixed size, fast, short keys. Use it unless something can’t. |
| ECDSA | ssh-keygen -t ecdsa -b 521 | -b is 256, 384 or 521 (default 256) |
| RSA | ssh-keygen -t rsa -b 4096 | For old servers and devices. Default size is 3072 bits since OpenSSH 8.0 |
| DSA | ssh-keygen -t dsa | Obsolete: disabled by default since OpenSSH 7.0, removed in 10.0. Replace any DSA key you find |
OpenSSH has supported Ed25519 since 6.5 (2014). Since 9.5 (October 2023), ssh-keygen without -t creates an Ed25519 key instead of RSA. The OpenSSH developers chose it for its small public keys; it also signs without a per-signature random nonce, which ECDSA needs to get right every time.
ssh-copy-id
Appends your public key to ~/.ssh/authorized_keys on the server, creates ~/.ssh if needed and fixes its permissions. It logs in with your password (or another key) once to do that.
ssh-copy-id alice@host # agent keys, else newest ~/.ssh/id*.pub
ssh-copy-id -i ~/.ssh/id_ed25519_work.pub alice@host # a specific key
ssh-copy-id -p 2222 alice@host # non-standard port
ssh-copy-id -o ProxyJump=bastion [email protected] # any ssh -o option
ssh-copy-id -n alice@host # dry run: show what would be added
ssh -o PasswordAuthentication=no alice@host true && echo key works| Flag | Meaning |
|---|---|
-i file | Key to install (.pub is added if you leave it out) |
-p port | SSH port |
-o option | Passed to ssh, e.g. ProxyJump, IdentityFile |
-n | Dry run |
-f | Force: install even if the key seems to be there already |
-s | Use SFTP; for servers that allow only SFTP |
Keys already on the server are skipped, so running it twice is safe. Where ssh-copy-id isn’t available (Windows, minimal images), do the same by hand:
cat ~/.ssh/id_ed25519.pub | ssh alice@host \
'umask 077; mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'Connect
ssh user@host
ssh -p 2222 user@host
ssh -i ~/.ssh/deploy_ed25519 deploy@host
ssh user@host 'df -h /' # run one command
ssh -t user@host 'sudo htop' # command that needs a terminal
ssh -v user@host # debug: which key, which auth method~/.ssh/config
Put hosts here once, then ssh db is all you type, and scp, rsync and git use it too.
Host db
HostName 192.0.2.11
User alice
Port 2222
IdentityFile ~/.ssh/id_ed25519
Host *.prod
User admin
ProxyJump bastion
Host *
ServerAliveInterval 30
AddKeysToAgent yes
IdentitiesOnly yesThe first matching value wins, so put specific hosts above Host *.
Jump hosts
A jump host (or bastion) is the one hardened server that accepts SSH from outside; you reach every other server through it. That gives one place to enforce MFA, log admin sessions and close access, which is why PCI DSS and ISO 27001 audits usually expect one.
ssh -J bastion [email protected]
ssh -J bastion1,bastion2 user@targetProxyJump keeps your keys on your machine. Avoid ForwardAgent on hosts you don’t fully trust: root there can use your agent.
Port forwarding
# Local: reach a remote service on localhost:5433
ssh -L 5433:localhost:5432 db
# Local through a host to something only it can reach
ssh -L 8080:192.0.2.20:80 bastion
# Remote: expose your local port 3000 on the server's port 9000
ssh -R 9000:localhost:3000 host
# SOCKS proxy for a browser
ssh -D 1080 bastion
# Tunnel only, no shell, in the background
ssh -fN -L 5433:localhost:5432 dbCopy files
scp file.txt db:/tmp/
scp -r db:/var/log/app ./logs/
scp -P 2222 file.txt user@host: # capital P for the port
sftp dbFor directories and anything large, rsync -a over SSH is better: it resumes and copies only changes.
Multiplexing
Reuse one connection for every session to a host; repeated logins become instant.
Host *
ControlMaster auto
ControlPath ~/.ssh/cm-%r@%h:%p
ControlPersist 10mKnown hosts
ssh-keygen -R host # forget a host after it's rebuilt
ssh-keyscan -t ed25519 host # fetch a host key (verify it out of band)A changed host key warning on a server that wasn’t rebuilt is exactly what the warning is for. Find out why before you remove the old key.
sshd hardening
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
AllowGroups ssh-users
MaxAuthTries 3
LoginGraceTime 20
X11Forwarding nosudo sshd -t && sudo systemctl reload ssh # test the config, then reloadKeep your current session open and test a new login in a second terminal before you close it. The service is called ssh on Debian and Ubuntu and sshd on RHEL.
Keep in mind
- Permissions:
~/.ssh700, private keys 600,authorized_keys600. sshd ignores keys with looser permissions. ~.on a new line kills a hung session;~?lists the other escapes.
Related
- Linux pipes cheat sheet: redirects and chaining commands
- curl cheat sheet: HTTP requests and APIs
Comments
Sign in with Google, GitHub or Facebook to comment.
Loading comments…
