networking · difficulty ◆◆
ssh — connect securely to a remote machine
One encrypted channel to any machine — to type commands, run a script, or forward a port. SSH is how you reach every box you do not physically sit in front of.
You can read this on a server through a channel that was encrypted in 1995 and has been battle-tested by every cloud, bank, and botnet since. No wonder you still type it fifty times a day.
AI-generated draft · reviewed and editedThis text was generated with AI as a first draft, then reviewed and edited by the author, who holds editorial responsibility for it.$ sshWhat it does
ssh establishes an end-to-end encrypted connection from your machine to a remote host, then gives you a shell on it as if you sat in front of it. The encryption covers everything after the initial handshake — your password, your command input, and the output. First contact uses a host key: the server proves it is really the server you think it is, so a man-in-the-middle cannot silently read or rewrite your traffic.
Why it matters
ssh is the backbone of remote administration. Every VPS, every cloud VM, every CI runner, and most containers are reached by it. Beyond a plain shell it does the three things admins rely on daily: run a one-off command on a remote box (ssh host 'command'), copy files with scp or rsync over the same channel, and forward ports (-L, -R, -D) to reach services that never should be exposed publicly. Master ssh and you can manage any Linux box on earth.
Example
$ ssh -v -o BatchMode=yes -o ConnectTimeout=3 localhostOpenSSH_9.6p1 Ubuntu-3ubuntu13.20, OpenSSL 3.0.13 30 Jan 2024
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files
debug1: /etc/ssh/ssh_config line 21: Applying options for *
debug1: Connecting to localhost [127.0.0.1] port 22.
debug1: Connection established.
debug1: identity file /home/kmail/.ssh/id_rsa type -1
[...one probe per key type follows: ecdsa, ecdsa_sk, ed25519, ed25519_sk, xmss, dsa — all type -1 except ed25519...]
debug1: identity file /home/kmail/.ssh/id_ed25519 type 3
debug1: Local version string SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.20
debug1: Remote protocol version 2.0, remote software version OpenSSH_9.6p1 Ubuntu-3ubuntu13.20Verified live on this box (Ubuntu 24.04, OpenSSH_9.6p1 Ubuntu-3ubuntu13.20). -v shows the handshake step by step: config files read, TCP connection established to port 22, then one identity probe per key type — type 3 means a usable ed25519 key was found, type -1 means 'no key of that type'. The probe lines repeat for every key type, which is why they are elided above. When a connection stalls, -v (or -vvv) is how you find out where.
$ ssh -o StrictHostKeyChecking=yes -o UserKnownHostsFile=/tmp/empty -o BatchMode=yes localhostNo ED25519 host key is known for localhost and you have requested strict checking.
Host key verification failed.
EXIT=255Verified live. This is SSH refusing to connect to a host whose key it does not recognize — the protection against a man-in-the-middle pretending to be your server. The fix is usually a password: answer yes on the first connection to store the host key, or use StrictHostKeyChecking=accept-new when you trust the very first contact.
$ ssh -o BatchMode=yes -o ConnectTimeout=5 dbadmin@127.0.0.1dbadmin@127.0.0.1: Permission denied (publickey,password).
EXIT=255Verified live against the sshd on this box — the loopback address is simply the reachable host available here; the same thing happens against any server that wants a key you do not have. BatchMode=yes forbids the interactive password prompt, so this fails immediately instead of hanging. That is intentional in scripts: the agent must use a key, and a missing or invalid key fails fast with a clear 'Permission denied' instead of blocking on a prompt nobody can answer. (For contrast, an address in the documentation range such as 203.0.113.20 is not routable, so there you get 'ssh: connect to host 203.0.113.20 port 22: Connection timed out' rather than a permission error.)
$ ssh deploy@kmail.at "uptime && df -h / | tail -1" 09:14:22 up 14 days, 2:35, 1 user, load average: 0.08, 0.11, 0.09
/dev/sda1 25G 12G 12G 50% /A one-off command over ssh runs on the remote host and returns its output to your terminal — then closes. Wrap multiple commands in quotes and they all execute remotely. This is how you check disk or load on ten servers in a loop without opening ten interactive sessions.
Common flags
- -p PORT
- connect to PORT on the remote host (default 22)
- -i IDENTITY_FILE
- use this private key file instead of the default ~/.ssh/id_*
- -o OPTION
- set any ssh_config option on the CLI, e.g. -o ConnectTimeout=5 or -o BatchMode=yes
- -L [BIND:]PORT:HOST:HPORT
- local port forwarding: tunnel your local port to a remote service through the ssh connection
- -C
- enable compression for slower links in the tunnel
- -v
- verbose handshake logging — the diagnostic you reach for when a connect hangs
- -X / -Y
- forward X11 GUI apps (with -Y trusting the remote). Also see -L/-R/-D for port forwarding.
History
A Finnish answer to Telnet
Tatu Ylonen wrote the first SSH in 1995 at Helsinki University of Technology, when Telnet and rlogin still shipped passwords and commands in plaintext across the network — anyone sniffing the wire could read them. SSH encrypted the whole channel, and encrypted remote login spread quickly through the Unix world. Ylonen went on to found SSH Communications, and today's OpenSSH descends directly from his ssh 1.2.12 — the last release with a licence free enough to reuse — which the OpenBSD team forked in 1999.
The key dance
Authentication uses a key pair, not a password, when set up right: your private key stays on your machine, the matching public key goes into ~/.ssh/authorized_keys on the server. Logging in is a proof-of-possession challenge — the server sends a value only someone holding your private key can answer. That is why ssh-agent keeps the key loaded in memory and why you never copy your private key to a server.
Fun facts
Pros & cons
pros
- + End-to-end encrypted, key-based auth — no plaintext passwords on the wire
- + Runs one-off commands, interactive shells, file copies, and port forwards over one channel
- + Ubiquitous: every Linux/Unix/macOS box has OpenSSH built in
- + The host-key model catches man-in-the-middle attacks on first contact
cons
- − Interactive password prompts block unattended scripts — BatchMode and keys are the workaround
- − Default no-compression tunnels can be slow on high-latency links without -C
- − Debugging handshake failures (-v, keys, permissions) has a real learning curve
- − Port forwarding is easy to get backwards — local vs remote direction confuses people
Takeaways
- 1Set up key auth with ssh-copy-id and stop typing passwords — then use BatchMode=yes in scripts to fail fast when the key is missing
- 2Run a one-off remote job with ssh user@host "command" and the output returns to your terminal
- 3Diagnose a hanging connection with ssh -v — the handshake log shows exactly where it stalls
- 4Reach a private service safely with -L localhost:port:target:port instead of opening it to the internet
- 5Never store or copy your private key onto a server; the server holds only the public key in authorized_keys
