How SSH works: what happens when you type ssh user@host
4 min readTerminal · Linux · Security · Guides6 views
People say 'SSH terminal' as if it were one thing. It is two: a protocol that builds an encrypted tunnel between two machines, and a terminal session that runs through that tunnel. Knowing where one ends and the other begins explains almost every confusing SSH error you will ever see.
The problem SSH replaced
Before SSH, remote login meant Telnet or rlogin. Your username, your password and every keystroke crossed the network as plain text, readable by anyone on the path. SSH (version 2 is the one in use today) fixes that with encryption, server authentication and flexible client authentication, all over a single TCP connection, port 22 by default. The specs are RFC 4251 to 4254 if you want the source.
What happens when you press Enter
- Connect and greet — a TCP handshake on port 22, then each side sends a version banner such as
SSH-2.0-OpenSSH_x. They also list the algorithms they support and agree on a common set. - Key exchange — client and server run a Diffie-Hellman style exchange (curve25519 is common). Both sides derive the same session keys without ever sending them over the wire. From here on, everything is encrypted and integrity-checked.
- The server proves who it is — it signs the exchange with its host key. Your client compares that key's fingerprint against
~/.ssh/known_hosts. - You prove who you are — user authentication: a public key, a password, or another method the server allows.
- Channels open — the connection opens a session channel. That is where your shell will live.
Order matters. The tunnel is already encrypted before you type a password, which is why a password over SSH is not the Telnet problem. It also tells you where a failure happened: a timeout is the network, a host-key warning is stage three, and Permission denied (publickey) is stage four.
Host keys and the first-connection question
The first time you connect, SSH says it cannot establish the authenticity of the host and shows a fingerprint. There is no certificate authority by default; SSH uses trust on first use. It stores the fingerprint, and if it ever changes you get a loud REMOTE HOST IDENTIFICATION HAS CHANGED warning. Sometimes that is a reinstalled server. Sometimes it is not. Verify the fingerprint out of band, for example from your provider's console or from the server itself:
# on the server: print the host key fingerprint
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubWhy keys beat passwords
A key pair has a private half that stays on your machine and a public half that you place in ~/.ssh/authorized_keys on the server. During authentication your client signs data tied to this specific session with the private key, and the server checks the signature with the public key. The private key never travels, so there is nothing to intercept and nothing to guess. A password can be brute-forced, and any server with port 22 open to the internet gets guessed at constantly.
ssh-keygen -t ed25519 -C "laptop"
ssh-copy-id user@host
ssh user@hostWhere the terminal comes in
After authentication, the client asks the server for a pseudo-terminal (PTY) and then for a shell. The server starts the shell attached to that PTY. Meanwhile your local terminal switches to raw mode, so every keypress, including Ctrl-C, is sent to the remote side as bytes instead of being handled locally. The remote PTY is what turns that byte into an interrupt for the foreground process. Your window size is sent in the request and updated on resize, which is why vim and htop draw correctly.
Run ssh host some-command and the story changes: no PTY by default, the command runs, output comes back and the exit code is passed through. That is how scripts, rsync and git over SSH work. Same tunnel, different channel request.
More than a shell
- Port forwarding —
ssh -L 5432:localhost:5432 user@hostcarries a local port through the tunnel to a service on the remote side. - ProxyJump —
ssh -J bastion user@internalhops through a gateway machine in one command. - SFTP and scp — file transfer runs as a subsystem on the same connection.
- Multiplexing — many channels share one connection, which is why connection reuse with
ControlMastermakes repeat logins feel instant. - ssh-agent — holds your unlocked key in memory so you type the passphrase once.
Where it bites
- Trust on first use — blindly typing yes on an unknown fingerprint is the weakest moment in the whole flow.
- Agent forwarding (`-A`) — it lets the remote host use your agent, so anyone with root there can use your keys while you are connected. Prefer
ProxyJump. - Keys with no passphrase — an unprotected private key is a password sitting in a file.
- Password login left on — turn it off once your key works, and block direct root login.
- Locking yourself out — one typo in
sshd_configplus a restart and you are outside your own server. Test the config first and keep your current session open.
# /etc/ssh/sshd_config
PasswordAuthentication no
PermitRootLogin no
# test the config, then reload (service is named ssh on Ubuntu, sshd on many other distros)
sudo sshd -t && sudo systemctl reload sshThe failure drill
When a connection fails, run ssh -v user@host and read the output in stage order: connect, key exchange, host key, authentication, channel. Add more v flags for more detail. The failure is almost always sitting under one of those words, and the verbose log will name it.
SSH is a locked pipe first and a terminal second. Get the pipe right and the terminal takes care of itself.

Written by
Shihab Hossain — Full-Stack Developer
I build fast, thoughtful products end-to-end — web experiences with React & Next.js, Android apps with Flutter, and the infrastructure behind them.
Work with me