hafeez@unixshadow:~$ ssh -vvv deploy@web1 # the -vvv tour, line by line
How SSH Connects
The -vvv Tour, Line by Line
every ssh session narrates itself — if you ask loudly enough. here’s what each line means.
# the connection, annotated
tcp
debug1: Connecting to web1 [203.0.113.7] port 22.
Plain TCP first — the same 3-way handshake from the TCP piece. No crypto yet.
debug1: Connection established.
version haggle
debug1: Local version string SSH-2.0-OpenSSH_9.6
debug1: Remote version string SSH-2.0-OpenSSH_9.3
debug1: Remote version string SSH-2.0-OpenSSH_9.3
Both sides announce versions in the clear. Mismatch the major version and you’re done here.
algorithm negotiation
debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: cipher: chacha20-poly1305@openssh.com
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: cipher: chacha20-poly1305@openssh.com
Client offers lists, server picks one from each — key exchange, host key type, cipher, MAC. Like the TLS handshake’s cipher-suite haggle.
host verification
debug1: Server host key: ssh-ed25519 SHA256:2kP7…
debug1: Host ‘web1’ is known and matches the ED25519 host key.
debug1: Found key in ~/.ssh/known_hosts:3
debug1: Host ‘web1’ is known and matches the ED25519 host key.
debug1: Found key in ~/.ssh/known_hosts:3
You verify the server first — this is what stops man-in-the-middle. Unknown key? That scary warning is this step failing.
user authentication
debug1: Authentications that can continue: publickey,password
debug1: Offering public key: ~/.ssh/id_ed25519
debug1: Server accepts key: ~/.ssh/id_ed25519 ED25519 SHA256:9fQ2…
debug1: Authentication succeeded (publickey).
debug1: Offering public key: ~/.ssh/id_ed25519
debug1: Server accepts key: ~/.ssh/id_ed25519 ED25519 SHA256:9fQ2…
debug1: Authentication succeeded (publickey).
Now the server verifies you — your public key against
~/.ssh/authorized_keys. The private key never leaves your machine; it’s a signature challenge, not a password.session
debug1: Entering interactive session.
debug1: pledge: filesystem full
debug1: pledge: filesystem full
Encrypted channel up, shell spawned. OpenSSH even sandboxes itself (
pledge) from here on.# field guide
- known_hosts
- your ledger of server host keys. “WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED” = this file disagrees.
- authorized_keys
- public keys allowed into an account. One line per key, lives on the server.
- ssh-agent
- holds your decrypted private keys in memory so you type the passphrase once.
- host keys ≠ user keys
- host keys identify the server; user keys identify you. Different pairs, different jobs.
- -J
- jump host:
ssh -J bastion web1— one command through the DMZ.
# see it live
# debug like you mean it:
ssh -vvv user@host — the full narration (this whole piece)ssh-keygen -l -f ~/.ssh/id_ed25519.pub — fingerprint of your keyssh-copy-id user@host — install your public key the easy way~/.ssh/config — Host blocks so you never type the flags twiceunixshadow.com · VPS & hosting from the shadowshafeez@unixshadow:~$
