---
title: SSH Protocol
url: https://doc.liz6.com/en/networking/12-security-protocols/01-ssh-protocol
locale: en
area: networking
tags:
- networking
- security-protocols
date: 2026-06-30
modified: 2026-07-16
description: '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."'
---

# 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)

<svg viewBox="0 0 720 330" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,'Source Han Sans CN','Microsoft YaHei',sans-serif" role="img" aria-label="SSH Key Exchange Five Steps: Version Exchange, Algorithm Negotiation, DH Exchange, Key Derivation, Host Identity Verification">
  <defs><marker id="sshkexah" markerWidth="10" markerHeight="8" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#475569"/></marker></defs>
  <rect width="720" height="330" fill="#ffffff"/>
  <text x="360" y="28" text-anchor="middle" font-size="17" font-weight="700" fill="#1f2933">SSH Key Exchange Five Steps (curve25519-sha256)</text>

  <rect x="24" y="48" width="214" height="26" rx="6" fill="#4f46e5"/>
  <text x="131" y="65" text-anchor="middle" font-size="13" font-weight="700" fill="#ffffff">① Establish Connection &amp; Negotiate Algorithms</text>
  <rect x="258" y="48" width="214" height="26" rx="6" fill="#0d9488"/>
  <text x="365" y="65" text-anchor="middle" font-size="13" font-weight="700" fill="#ffffff">② DH Key Exchange</text>
  <rect x="492" y="48" width="204" height="26" rx="6" fill="#22c55e"/>
  <text x="594" y="65" text-anchor="middle" font-size="13" font-weight="700" fill="#ffffff">③ Derive Keys &amp; Verify Host</text>
  <line x1="238" y1="61" x2="258" y2="61" stroke="#475569" stroke-width="1.6" marker-end="url(#sshkexah)"/>
  <line x1="472" y1="61" x2="492" y2="61" stroke="#475569" stroke-width="1.6" marker-end="url(#sshkexah)"/>

  <rect x="32" y="86" width="198" height="46" rx="6" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="131" y="103" text-anchor="middle" font-size="12" font-weight="700" fill="#3730a3">Version Exchange</text>
  <text x="131" y="121" text-anchor="middle" font-size="10" fill="#4f46e5">C ↔ S exchange SSH-2.0-OpenSSH_9.6</text>
  <rect x="32" y="140" width="198" height="56" rx="6" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="131" y="157" text-anchor="middle" font-size="12" font-weight="700" fill="#3730a3">Algorithm Negotiation (KEXINIT)</text>
  <text x="131" y="174" text-anchor="middle" font-size="10" fill="#4f46e5">Candidate lists: kex / host_key</text>
  <text x="131" y="188" text-anchor="middle" font-size="10" fill="#4f46e5">Encryption algorithms / MAC algorithms</text>

  <rect x="266" y="86" width="198" height="46" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="365" y="103" text-anchor="middle" font-size="12" font-weight="700" fill="#115e59">C → S: KEX_ECDH_INIT</text>
  <text x="365" y="121" text-anchor="middle" font-size="10" fill="#0f766e">Send temporary public key Q_C</text>
  <rect x="266" y="140" width="198" height="66" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="365" y="157" text-anchor="middle" font-size="12" font-weight="700" fill="#115e59">S → C: KEX_ECDH_REPLY</text>
  <text x="365" y="174" text-anchor="middle" font-size="10" fill="#0f766e">K_S (host public key) + Q_S (temporary public key)</text>
  <text x="365" y="188" text-anchor="middle" font-size="10" fill="#0f766e">Signature over H, proving possession of private key</text>

  <rect x="500" y="86" width="188" height="58" rx="6" fill="#dcfce7" stroke="#4ade80"/>
  <text x="594" y="103" text-anchor="middle" font-size="12" font-weight="700" fill="#166534">Calculate Shared Key</text>
  <text x="594" y="121" text-anchor="middle" font-size="10" fill="#15803d">shared secret → H = session_id</text>
  <text x="594" y="135" text-anchor="middle" font-size="10" fill="#15803d">Derive IV / encryption key / MAC key (bidirectional)</text>
  <rect x="500" y="154" width="188" height="66" rx="6" fill="#ffedd5" stroke="#f97316"/>
  <text x="594" y="171" text-anchor="middle" font-size="12" font-weight="700" fill="#9a3412">Client Verifies K_S</text>
  <text x="594" y="188" text-anchor="middle" font-size="10" fill="#c2410c">First connection: check fingerprint</text>
  <text x="594" y="202" text-anchor="middle" font-size="10" fill="#c2410c">Write/compare known_hosts</text>

  <rect x="40" y="242" width="640" height="70" rx="8" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="360" y="264" text-anchor="middle" font-size="12.5" fill="#3730a3">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.</text>
  <text x="360" y="284" text-anchor="middle" font-size="12.5" fill="#3730a3">Trust for the first connection relies on TOFU (Trust On First Use)—this is the only step in SSH that cannot be fully automated.</text>
</svg>

## 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*
