DEV Community

ZeroTrust Architect
ZeroTrust Architect

Posted on • Edited on • Originally published at cacheguard.com

TLS Handshake to Reverse Proxy: How HTTPS Works End-to-End in a Production Network

When a browser connects to https://example.com, a series of cryptographic operations happen before a single byte of application data is exchanged. Understanding this sequence is necessary for debugging TLS issues, configuring reverse proxies correctly, and reasoning about what SSL termination actually changes.

How HTTPS Works

The TLS 1.3 handshake

TLS 1.3 (RFC 8446) reduced the handshake from TLS 1.2's two round trips to one. Here is the full sequence:

Client                                Server
  |                                      |
  |-- ClientHello ---------------------->|  (supported ciphers, key share, SNI)
  |<-- ServerHello ----------------------|  (chosen cipher, key share)
  |<-- {EncryptedExtensions} -----------|
  |<-- {Certificate} -------------------|
  |<-- {CertificateVerify} -------------|
  |<-- {Finished} ----------------------|
  |-- {Finished} ----------------------->|
  |                                      |
  |=== Application data (encrypted) ====|
Enter fullscreen mode Exit fullscreen mode

After the first round trip, both sides derive the same session keys from their respective key shares (ECDH). The server's certificate is transmitted inside the encrypted portion of the handshake — an improvement over TLS 1.2 where the certificate was sent in plaintext.

Certificate chain validation

The server sends its certificate chain — end-entity cert, optional intermediate(s), root. The client validates:

  1. Signature chain: Each certificate is signed by the issuer above it, terminating at a trusted root CA in the system trust store.
  2. Name matching: The Subject Alternative Name (SAN) or CN matches the hostname in the request.
  3. Validity period: notBefore and notAfter fields are within the current time.
  4. Revocation status: Via OCSP or CRL (if the client checks — many do not by default).

If any check fails, the browser terminates the connection and displays an error. The specific error code (expired, wrong host, untrusted CA) determines the error page shown.

What changes with a reverse proxy

When a reverse proxy sits in front of your backend, SSL termination moves from the backend to the proxy. The client's TLS session terminates at the proxy, not at the application server.

[Browser] <-- TLS --> [Reverse Proxy] <-- HTTP or TLS --> [Backend]
Enter fullscreen mode Exit fullscreen mode

The certificate presented to the browser belongs to the proxy, not the backend. The proxy forwards the request to the backend — either over plain HTTP on a trusted private network or over a new TLS connection using the backend's certificate.

What the backend loses

Without SSL termination at the proxy, the backend receives the client's IP in the TCP source address. With SSL termination, the TCP connection comes from the proxy's IP. The original client IP must be forwarded in an X-Forwarded-For or X-Real-IP header, and the backend must be configured to trust this header only from the proxy's IP range.

X-Forwarded-For: 203.0.113.42
X-Forwarded-Proto: https
X-Real-IP: 203.0.113.42
Enter fullscreen mode Exit fullscreen mode

Backends that naively trust X-Forwarded-For from any source are vulnerable to IP spoofing.

Session persistence in load-balanced deployments

When the reverse proxy load-balances across multiple backends, stateful applications (anything with server-side sessions) require session persistence — routing all requests from the same client to the same backend. This is typically implemented via a session cookie that encodes the backend assignment.

SSL termination vs SSL passthrough

Termination: The proxy decrypts traffic, inspects/transforms it, and forwards. Enables WAF rules, header injection, caching. Requires the proxy to hold the certificate private key.

Passthrough: The proxy forwards the encrypted TCP stream without decryption, based on SNI alone. The backend holds the key. The proxy cannot inspect or modify content.

Re-encryption: The proxy terminates the client TLS session and opens a new TLS session to the backend. End-to-end encryption with proxy visibility. Higher CPU cost.

High availability for the proxy layer

The reverse proxy becomes a single point of failure. HA is typically implemented with VRRP (Virtual Router Redundancy Protocol) — two proxy instances share a virtual IP. The active instance holds the VIP; if it fails, the standby takes over within seconds.

CacheGuard implements reverse proxy SSL termination via Apache mod_proxy, with integrated WAF (ModSecurity + OWASP CRS), load balancing with session persistence, and native HA mode for multi-appliance deployments. Certificate management and PKI operations are handled through the web interface.

https://www.cacheguard.com/how-https-works/


Originally published on the CacheGuard Blog. CacheGuard is free and open source — GitHub.

Top comments (0)