πŸ”“ SNI Proxies

artistical representation of rama TLS Termination proxy as llama unlocking cargo to move it forward unprotected
A SNI proxy is a specialized type of proxy that operates at the TLS layer, using the Server Name Indication (SNI) field from the TLS handshake to make routing decisions. This allows for intelligent routing of encrypted traffic without needing to decrypt it first.

β€” Wikipedia

Examples:

  • /examples/tls_sni_router.rs: (TLS) SNI Router, a proxy which fowards traffic to encrypted web servers based on the public SNI found in the client hello handshake data sent by the UA as part of the connection establishment.

Description

%3clientclientSNI proxy (rama)SNI proxy (rama)client->SNI proxy (rama)server Aserver ASNI proxy (rama)->server Aserver Bserver BSNI proxy (rama)->server B

A SNI proxy:

  • Accepts TLS connections
  • Peeks at the SNI field in the ClientHello (during TLS handshake)
  • Uses that to route or filter traffic before finishing the handshake

This is a common kind of proxies serving multiple backends:

SNI Transport Proxy
---------------------

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Client β”œβ”€β”€β”€β”€β”€β”€β–Άβ”‚ SNI Proxy      β”œβ”€β”€β”€β”€β”€β”€β–Άβ”‚ Target TLS Server  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚                  β”‚                        β”‚
     β”‚ 1. TCP connect to proxy (:443)            β”‚
     |     (because firewall forwards this       β”‚
     |       traffic or DNS record               β”‚
     |      has been "hijacked")                 β”‚
     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ”‚                        β”‚
     β”‚                  β”‚                        β”‚
     β”‚ 2. Send TLS ClientHello                   β”‚
     β”‚    (includes SNI: example.com)            β”‚
     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ”‚                        β”‚
     β”‚                  β”‚                        β”‚
     β”‚ 3. Proxy inspects SNI                     β”‚
     β”‚    and selects backend                    β”‚
     β”‚                  β”‚                        β”‚
     β”‚ 4. Proxy connects to example.com:443      β”‚
     β”‚                  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ά β”‚
     β”‚                  β”‚                        β”‚
     β”‚ 5. Proxy forwards full TLS handshake      β”‚
     │◀────────────────▢│◀──────────────────────▢│
     β”‚                  β”‚                        β”‚
     β”‚ 6. Encrypted traffic flows transparently  β”‚
     │◀────────────────▢│◀──────────────────────▢│

SNI Proxy as TLS MITM

When an HTTP proxy performs Man-In-The-Middle (MITM) interception on TLS-encrypted traffic (e.g., HTTPS), it effectively operates as an SNI proxy β€” where SNI stands for Server Name Indication, a TLS extension that reveals the intended hostname during the initial handshake.

In this scenario, the proxy terminates the incoming TLS connection from the client and extracts the hostname from the Client Hello's SNI extension. It then uses this hostname to establish a new outbound TLS connection to the intended server. If the SNI is a domain name, the proxy also needs to resolve it via DNS into an IPv4 or IPv6 address.

With Rama, we often refer to these as MITM proxies, especially in the context of web traffic, but it's worth clarifying that not all SNI proxies are MITM proxies, and vice versa. An SNI proxy can operate passively (just routing), whereas a full MITM proxy actively decrypts and re-encrypts TLS traffic.

To improve performance, the SNI proxy can cache DNS resolutions, reducing repeated lookups for frequently accessed domains.

If you're looking to intercept both HTTP and HTTPS traffic, your proxy will need to:

  • Handle raw HTTP directly (no encryption)
  • Act as an SNI-based MITM for HTTPS by terminating TLS after a CONNECT request

This allows full visibility into both HTTP and HTTPS traffic through a unified proxy.

SNI Proxy MITM'ing HTTPS traffic (Rama-style)
-----------------------------------------------

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Client β”œβ”€β”€β”€β”€β”€β”€β–Άβ”‚ SNI Proxy (MITM)   β”œβ”€β”€β”€β”€β”€β”€β–Άβ”‚ Target Server (TLS)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚                    β”‚                          β”‚
     β”‚ 1. TCP connect     β”‚                          β”‚
     β”‚    to proxy (:443) β”‚                          β”‚
     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ”‚                          β”‚
     β”‚                    β”‚                          β”‚
     β”‚ 2. TLS handshake   β”‚                          β”‚
     β”‚    begins with SNI β”‚                          β”‚
     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ”‚                          β”‚
     β”‚                    β”‚                          β”‚
     β”‚ 3. Proxy inspects  β”‚                          β”‚
     β”‚    SNI, resolves   β”‚                          β”‚
     β”‚    target hostname β”‚                          β”‚
     β”‚                    β”‚                          β”‚
     β”‚ 4. TLS handshake   β”‚                          β”‚
     β”‚    complete (client↔proxy)                    β”‚
     β”‚ ◀───────────────────                          β”‚
     β”‚                    β”‚                          β”‚
     β”‚ 5. Proxy connects  β”‚                          β”‚
     β”‚    to target:443   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ”‚
     β”‚ 6. Proxy performs  β”‚                          β”‚
     β”‚    TLS to server   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ”‚
     β”‚                    β”‚                          β”‚
     β”‚                                               β”‚
     β”‚              7. Encrypted HTTPS               β”‚
     β”‚                 relayed via MITM              β”‚
     β”‚                                               β”‚
     │◀──────────────────▢│◀────────────────────────▢│

SNI Proxies as invisible proxies

A SNI Proxy can be send tls-encrypted traffic without it first going via a CONNECT request. This is great for environments that might not support proxies.

This can work by allowing your firewall, ip table, router or some other "box" in the middle, to override the DNS resolution for specific domain names to the IP of the (SNI) proxy. The proxy on its turn will establish a connection based on the Server Name as discussed previously and onwards it goes.

A proxy without a proxy protocol. That is also what a SNI proxy can be.