linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Simulator
  • Knowledge base
  • Interview prep
Index
Categories
All entries
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
home/linux/kb/Networking: L4 and above/tls-handshake

kb/network-l4 ── Networking: L4 and above ── intermediate

TLS Handshake

TLS is the encryption layer above TCP. Before data flows, both sides run a handshake: they exchange keys, verify the certificate, and agree on a cipher.

view as markdownaka: tls, ssl, tls13

Where TLS lives

TLS (Transport Layer Security, RFC 8446 for 1.3) is the layer between TCP and the application:

Application (HTTP, IMAP, SMTP, ...)
    │
TLS (encryption + authentication)
    │
TCP (reliability)
    │
IP / Ethernet

HTTPS is HTTP inside TLS. When a browser opens https://...:

  1. DNS resolution (see dns-resolution)
  2. TCP tcp-handshake to port 443
  3. TLS handshake (see below): new packets inside the TCP connection
  4. After the handshake, ordinary HTTP exchange with an encrypted payload

TLS 1.3 handshake (simplified)

TLS 1.3 is a one-roundtrip handshake:

Client                                Server
  │                                     │
  │  ── ClientHello ───────────────►    │
  │      • TLS-versions supported       │
  │      • cipher-suites supported      │
  │      • SNI: hostname                │
  │      • client key share (X25519)    │
  │                                     │
  │  ◄── ServerHello                    │
  │      • chosen cipher (TLS_AES_256...)│
  │      • server key share             │
  │      ◄── Encrypted Extensions       │ (after this everything encrypted)
  │      ◄── Certificate                │
  │      ◄── CertificateVerify          │
  │      ◄── Finished                   │
  │                                     │
  │  ── Finished ─────────────────►     │
  │                                     │
  │  ◄═════════════ HTTP data ════════►│

TLS 1.2 required 3 roundtrips and was slower. TLS 1.3 uses 1 roundtrip plus 0-RTT for session resumption.

What happens in the handshake

  1. Version and cipher negotiation: which encryption algorithm to use (TLS_AES_256_GCM_SHA384, ChaCha20-Poly1305, and others)
  2. Key exchange: exchange of key material via ECDH (X25519, secp256r1)
  3. Server authentication: the server presents an x509 certificate; the client verifies the chain up to a known CA
  4. (Optional) Client authentication: mTLS: the client also sends a certificate
  5. Derive keys: both sides compute shared keys for encrypting data
  6. Finished: mutual confirmation that everything completed without MITM

SNI (Server Name Indication)

Server certificates are tied to a domain name. When one IP hosts several sites (virtual hosting), the server does not know which domain to serve until the HTTP request arrives, and HTTP only arrives after the handshake.

The fix is SNI: the client writes the server name in plaintext inside ClientHello. The server picks the correct certificate. This means the hostname is visible to a network observer even in HTTPS, which motivated the development of Encrypted Client Hello (ECH) in newer versions.

Seeing it live

bash
openssl s_client -connect example.com:443 -servername example.com < /dev/null

The output shows the negotiated cipher, the certificate chain, and the verification result.

In [[#cmd-tcpdump|tcpdump]] on port 443 you can see the TLS handshake packets, but the payload is encrypted from ServerHello onward.

§ команды

bash
openssl s_client -connect example.com:443 -servername example.com < /dev/null 2>&1 | head -30

Perform a TLS handshake manually; shows the certificate chain and the negotiated cipher

bash
openssl x509 -in cert.pem -noout -subject -issuer -dates

Read subject, issuer, and validity dates from a certificate file

bash
openssl s_client -connect host:443 -showcerts < /dev/null

Print the full certificate chain in PEM format

bash
echo | openssl s_client -connect host:443 2>/dev/null | openssl x509 -noout -dates

Print only the certificate expiry dates (useful for monitoring)

bash
curl -vsI https://example.com 2>&1 | grep -E 'TLS|cipher'

Show TLS details via curl: version, cipher, and ALPN

§ см. также

  • tcp-handshakeTCP three-way handshakeTCP connection opens with three packets: SYN from the client, SYN-ACK from the server, ACK from the client. After that the connection is Established and data transfer can begin.
  • http-protocolHTTP/1.1, HTTP/2, HTTP/3HTTP/1.1 is a text-based protocol with keep-alive. HTTP/2 is binary with multiplexing over a single TCP connection. HTTP/3 carries HTTP/2 semantics over QUIC/UDP without TCP head-of-line blocking.
  • http2-internalsHTTP/2: Binary Framing, HPACK, Stream MultiplexingHTTP/2 is binary multiplexing over a single TCP connection. HPACK compresses headers through an indexed dictionary. Streams are independent. Server push is deprecated. On a loss-prone link, HoL blocking is a real problem, solved by QUIC.
  • websocketWebSocket: Bidirectional Channel over HTTPWebSocket is a bidirectional channel over a single TCP connection. The upgrade from HTTP/1.1 uses the Upgrade header; after that, both sides exchange binary frames. Typical use cases: real-time UI, chats, dashboards, live updates.

§ упоминается в уроках

  • ›intermediate-09-tls-handshake
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies