On this page

SSH Protocol

SSH is more than just "encrypted telnet"—it features a three-layer separation: Transport Layer (key exchange + encryption), Authentication Layer (public key/password/certificate), and Connection Layer (multiplexing port forwarding/X11/SFTP). Port forwarding turns SSH into a "Swiss Army knife."

Overview

SSH (Secure Shell, 1995/2006) is a core tool for Unix/Linux system administration. The protocol is divided into three layers: the Transport Layer handles key exchange and encryption, the User Authentication Layer handles identity verification (public key/password/TOTP), and the Connection Layer multiplexes channels such as shell/port forwarding/SFTP over a single TCP connection. SSH port forwarding (-L/-R) can serve as a simple VPN—mapping remote ports to local ones via an encrypted tunnel. SSH 2.0 fixed critical security issues present in SSH 1.x, making it the only secure version available today.

Three-Layer Architecture

Connection Protocol (RFC 4254):  channels (shell, exec, forward, SFTP)
User Authentication (RFC 4252):  password, publickey, keyboard-interactive
Transport Layer (RFC 4253):      key exchange, encryption, server auth
TCP

Transport Layer: Key Exchange (curve25519-sha256)

SSH Key Exchange Five Steps (curve25519-sha256) ① Establish Connection & Negotiate Algorithms ② DH Key Exchange ③ Derive Keys & Verify Host Version Exchange C ↔ S exchange SSH-2.0-OpenSSH_9.6 Algorithm Negotiation (KEXINIT) Candidate lists: kex / host_key Encryption algorithms / MAC algorithms C → S: KEX_ECDH_INIT Send temporary public key Q_C S → C: KEX_ECDH_REPLY K_S (host public key) + Q_S (temporary public key) Signature over H, proving possession of private key Calculate Shared Key shared secret → H = session_id Derive IV / encryption key / MAC key (bidirectional) Client Verifies K_S First connection: check fingerprint Write/compare known_hosts Verification order is critical: the signature first proves the server holds the K_S private key, and known_hosts comparison then prevents man-in-the-middle hijacking. Trust for the first connection relies on TOFU (Trust On First Use)—this is the only step in SSH that cannot be fully automated.

User Authentication

Methods (tried in order):
  1. publickey: Client: sign(session_id + request + publickey, privatekey)
     Server: verify → SSH_MSG_USERAUTH_SUCCESS
  2. keyboard-interactive: TOTP or challenge-response
  3. password: transmitted over encrypted channel (secure)

Connection Layer: Channel Multiplexing

Each channel is independent:
  SSH_MSG_CHANNEL_OPEN: type="session" → channel 0
  SSH_MSG_CHANNEL_OPEN: type="direct-tcpip" → channel 1 (port forwarding)

Channel types:
  session:         shell, exec, subsystem (SFTP)
  direct-tcpip:    Local port forwarding (-L)
  forwarded-tcpip: Remote port forwarding (-R)

Port Forwarding

Local (-L 8080:internal:80): SSH client listens on :8080 → tunnel → SSH server connects to internal:80
Remote (-R 3000:localhost:22): SSH server listens on :3000 → tunnel → SSH client connects to localhost:22

References

  • RFC: 4251-4254, 5656, 8731
  • Source Code: OpenSSH (sshconnect2.c for auth, channels.c for channels)

Keywords: SSH, transport, kex, publickey, channel, port forwarding, SFTP, known_hosts