How the SSH protocol works

SSH · Expert · 15 min

Understanding the layers explains debug output, algorithm errors, forwarding and multiplexing behaviour.

SSH version 2 (RFC 4251-4254) is built in three layers over one TCP connection.

Transport layer. Both sides send a version string, then exchange lists of supported algorithms and pick the first client preference the server also supports: key exchange, host key type, cipher and MAC. The key exchange (Diffie-Hellman style) produces shared session keys; the server signs the exchange with its host key, which is what your known_hosts check verifies. OpenSSH 10.0 defaults to the hybrid post-quantum mlkem768x25519-sha256 key exchange, combining ML-KEM with X25519 so a future quantum computer cannot decrypt recorded traffic. Ciphers are typically chacha20-poly1305@openssh.com or AES-GCM. Keys are periodically re-exchanged (RekeyLimit).

User authentication. Inside the encrypted transport the client tries methods (publickey, password, keyboard-interactive...). For publickey, the client signs data bound to the session ID, so a signature cannot be replayed on another connection.

Connection layer. Everything else is channels multiplexed over the connection: an interactive session, an exec request, an sftp subsystem, each forwarded TCP connection (direct-tcpip for -L, forwarded-tcpip for -R), agent forwarding. That is why ControlMaster can add sessions cheaply.

ssh -vvv shows each step; ssh -Q kex (or cipher, key) lists supported algorithms. Errors like "no matching host key type found" mean the algorithm negotiation found no overlap, typically with very old servers using deprecated algorithms (ssh-rsa with SHA-1, DSA, which 10.0 removed entirely).

Example

ssh -vvv web 2>&1 | grep -E 'kex: algorithm|host key algorithm|cipher|Authenticat'
# debug1: kex: algorithm: mlkem768x25519-sha256
# debug1: kex: host key algorithm: ssh-ed25519
# debug1: kex: server->client cipher: chacha20-poly1305@openssh.com ...
# debug1: Authenticated to web ([203.0.113.10]:22) using "publickey".
ssh -Q kex | head -3          # key exchange algorithms this client supports
ssh -Q key                    # supported key types
# talking to a legacy device that only offers ssh-rsa (SHA-1):
ssh -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedAlgorithms=+ssh-rsa old-switch

Remember

  • Transport (kex, cipher, host key) -> user auth -> channels
  • Hybrid post-quantum key exchange is the default in OpenSSH 10
  • Forwards, sessions and sftp are all channels on one connection

Watch out for

  • Permanently re-enabling deprecated algorithms globally (Host *) instead of only for the one legacy host.

Check yourself

  1. What is the host key signature during key exchange used for?
  2. A port forward with -L appears in the protocol as what?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.openssh.com/specs.html