ssh logs you in to another machine and runs commands there over an encrypted connection. The same client copies files, forwards ports, and hops through a bastion host. This sheet covers everyday connections, key management, the agent, tunnels, and a ~/.ssh/config you can start from. Every flag and config keyword below is from the OpenSSH 10.6 manual pages. We attempt to test on all versions.
what it is and when to use it
Use ssh any time you need a shell or a single command on another machine, a file copied to or from it, or a port on it that isn’t exposed to the internet.
| Command | What it does |
|---|---|
ssh -V | Print the client version |
connect
| Command | What it does |
|---|---|
ssh user@server.example.com | Log in |
ssh -p 2222 -i ~/.ssh/id_ed25519 user@server.example.com | A different port, and a specific key |
ssh user@server.example.com 'df -h /' | Run one command and come back |
ssh -t user@server.example.com top | Run a full-screen program: force a terminal |
ssh -J user@bastion.example.com user@internal.example.com | Go through a jump host to reach a machine behind it |
ssh -v user@server.example.com | Debug a connection that fails: -v, -vv, or -vvv for more detail |
ssh -o ServerAliveInterval=30 user@server.example.com | Set any config option for one run |
keys
| Command | What it does |
|---|---|
ssh-keygen -t ed25519 -C "laptop" -f ~/.ssh/id_ed25519 | Make a new Ed25519 key pair, with a comment so you can tell keys apart |
This writes the private key to ~/.ssh/id_ed25519 and the public key to ~/.ssh/id_ed25519.pub. It asks for a passphrase. Use one. In OpenSSH 10.6, Ed25519 is also what ssh-keygen makes when you leave out -t.
| Command | What it does |
|---|---|
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server.example.com | Install your public key on a server so you can log in with it |
ssh-keygen -l -f ~/.ssh/id_ed25519.pub | Show a key’s fingerprint, to compare with what a server or a colleague shows you |
ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub | Rebuild a lost .pub file from the private key |
ssh-keygen -p -f ~/.ssh/id_ed25519 | Change or add a key’s passphrase |
ssh-keygen -F server.example.com | Look up a host’s entry in known_hosts |
ssh-keygen -R server.example.com | Remove a host’s entry from known_hosts |
the agent
The agent holds your decrypted keys in memory, so you type a passphrase once per session instead of on every connection.
| Command | What it does |
|---|---|
eval "$(ssh-agent -s)" | Start an agent in this shell (desktop sessions usually start one for you) |
ssh-add ~/.ssh/id_ed25519 | Add a key |
ssh-add -t 1h ~/.ssh/id_ed25519 | Add a key that expires from the agent after an hour |
ssh-add -l | List the keys the agent holds |
ssh-add -D | Remove them all |
tunnels
| Command | What it does |
|---|---|
ssh -N -L 8080:localhost:80 user@server.example.com | Local forward: localhost:8080 on your machine reaches port 80 on the server |
ssh -N -R 9000:localhost:3000 user@server.example.com | Remote forward: port 9000 on the server reaches port 3000 on your machine |
ssh -N -D 1080 user@server.example.com | Dynamic forward: a SOCKS proxy on localhost:1080 that exits from the server |
ssh -f -N -L 8080:localhost:80 user@server.example.com | Same local forward, sent to the background once it is connected |
-N: don’t run a remote command. Use it for tunnels.-f: go to the background just before running the command, after any password or passphrase prompt.- In
-L 8080:localhost:80, the connection tolocalhost:80is made from the server, solocalhostmeans the server itself.
copy files
| Command | What it does |
|---|---|
scp report.txt user@server.example.com:/tmp/ | Copy a file up |
scp -r user@server.example.com:/var/log/app ./app-logs | Copy a directory down |
scp -P 2222 report.txt user@server.example.com:/tmp/ | scp’s port flag is a capital P (lower-case -p preserves times and modes) |
For big or repeated copies, rsync over ssh only sends what changed. See the rsync tutorial.
escape sequences
Type these at the start of a line in an interactive session: press Enter first, then ~.
| Escape | What it does |
|---|---|
~. | Disconnect. |
~? | List the escapes. |
~# | List forwarded connections. |
~^Z | Put ssh in the background (Ctrl-Z after the tilde). |
~C | A command line for adding or cancelling forwards. It is off by default. Turn it on with EnableEscapeCommandline yes. |
~/.ssh/config
The config file turns long commands into short aliases. With the file below, ssh web does the same as ssh -p 2222 -i ~/.ssh/id_ed25519 -J user@bastion.example.com user@server.example.com.
Host web
HostName server.example.com
User user
Port 2222
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
ProxyJump user@bastion.example.com
Host bastion
HostName bastion.example.com
User user
Host *
ServerAliveInterval 30
ServerAliveCountMax 3
AddKeysToAgent yes
ControlMaster auto
ControlPath ~/.ssh/cm-%C
ControlPersist 10m
| Keyword | What it does |
|---|---|
Host | An alias, or a pattern. * matches every host, so it goes last. |
HostName | The real name or address to connect to. |
User and Port | The same as user@ and -p. |
IdentityFile with IdentitiesOnly yes | Use this key and nothing else, even if the agent offers more. |
ProxyJump | The same as -J. |
ServerAliveInterval 30 and ServerAliveCountMax 3 | Send a keepalive through the connection after 30 seconds of silence, and disconnect after 3 go unanswered. |
AddKeysToAgent yes | When ssh loads a key from a file, it also adds it to the running agent. |
ControlMaster auto, ControlPath, and ControlPersist 10m | Later connections to the same host reuse the first one’s network connection, and that connection stays open for 10 minutes after the last session closes. %C is a hash of the connection details, so each host gets its own socket. |
| Command | What it does |
|---|---|
ssh -G web | Print the settings ssh will actually use for a host, after every Host block is applied |
ssh -O exit web | Close a shared connection kept open by ControlPersist |
chmod 600 ~/.ssh/config | The config must not be writable by anyone else |
You can split the file up with Include, for example Include config.d/* at the top, which reads files from ~/.ssh/config.d/.
gotchas
- For each setting, ssh uses the first value it finds. Command-line options win, then
~/.ssh/configfrom the top down, then/etc/ssh/ssh_config. Put specificHostblocks first andHost *last. - ssh ignores a private key file that other users can read. Keep
~/.sshat700and private keys at600. - "REMOTE HOST IDENTIFICATION HAS CHANGED" means the server’s key doesn’t match
known_hosts. Find out why (the server was rebuilt, or something is in the way) before you runssh-keygen -Ron it. - Agent forwarding (
-AorForwardAgent yes) lets anyone who can bypass file permissions on the remote host, such as root, use your agent through the forwarded connection while you are connected. The manual says to enable it "with caution".ProxyJumpreaches hosts behind a bastion without forwarding the agent. - A local forward binds only to your loopback address by default, so other machines can’t connect to it. A bind address of
*(as in-L '*:8080:localhost:80') or-gopens it to other machines. Do that only on purpose. - Escape sequences only work in a session with a terminal, and only right after a newline.
related on terminal-life
sources
Checked against the OpenSSH 10.6 manual pages (OpenSSH 10.6, released October 6, 2026). ssh-copy-id is checked against the man page that ships in portable OpenSSH’s contrib directory. On older versions, man ssh and man ssh_config on your own machine describe what you have.
- ssh(1): https://man.openbsd.org/ssh
- ssh_config(5): https://man.openbsd.org/ssh_config
- ssh-keygen(1): https://man.openbsd.org/ssh-keygen
- ssh-agent(1): https://man.openbsd.org/ssh-agent
- ssh-add(1): https://man.openbsd.org/ssh-add
- scp(1): https://man.openbsd.org/scp
- ssh-copy-id(1): https://github.com/openssh/openssh-portable/blob/V_10_6_P1/contrib/ssh-copy-id.1
- Release notes: https://www.openssh.com/releasenotes.html
terminal-life.com/cheatsheets/ssh/ · checked against the OpenSSH 10.6 manual pages