Skip to content

CONCEPT Cited by 2 sources

Egress SNI Filtering

Egress SNI filtering is the pattern of enforcing an outbound allow-list based on hostnames matched against the TLS ClientHello's Server Name Indication (SNI) field rather than on IP addresses. Traffic to a destination is allowed only if its SNI value matches a configured allow-list.

Why SNI is the load-bearing field

In a TLS 1.2 / 1.3 handshake, the client sends the hostname of the server it wants to reach in clear text inside the ClientHello — the SNI extension. This is what multiplexed TLS services (a single IP serving foo.com and bar.com) use to route to the right certificate. A middlebox positioned between client and internet can read the SNI without breaking TLS encryption (it's on the outside of the encrypted tunnel).

An SNI-based firewall rule looks like: "allow TCP/443 outbound only if SNI ∈ {api.foo.com, s3.us-east-1.amazonaws.com, *.bar.com}."

Why hostnames beat IPs for egress allow-listing

IP allow-lists have been the traditional shape of firewall egress rules, and they bit-rot rapidly:

  • SaaS providers rotate IPs frequently — hours-to-days cadence.
  • CDNs and edge networks front many services on shared IP ranges.
  • Cloud provider IP ranges change; AWS publishes ip-ranges.json for exactly this reason.
  • A single hostname can map to hundreds of IPs — any of which may be valid.

Hostnames are part of the client-provider contract. api.stripe.com is stable; the IPs behind it aren't. SNI filtering makes the allow-list track what actually changes slowly.

Canonical AWS topology

The idiomatic implementation on AWS (per the Generali post):

  App pods (private subnet) ──► Network Firewall (public subnet)
                                   │ filter rule: SNI ∈ allow-list
                                 NAT Gateway (protected subnet)
                                 Internet

Note the ordering: the firewall sits before NAT. Blocked flows don't reach NAT, so a compromised pod trying to exfiltrate to an unapproved host fails at the firewall, not silently at the destination.

See systems/aws-network-firewall for AWS-specific details.

Side benefits

  • Traffic-pattern analysis. The firewall naturally logs each observed hostname → useful for discovering what SaaS dependencies an app actually has (often a surprise).
  • Compliance evidence. A per-connection hostname log is an auditable trail showing applications can only access approved external services.
  • Zero-trust alignment. Implicit-deny + explicit-allow egress is the outbound-facing complement to inbound zero-trust authorisation.

Caveats

  • Encrypted SNI (ESNI) / Encrypted ClientHello (ECH). These TLS extensions encrypt the SNI field, breaking SNI filtering. Not yet deployed at production scale across major SaaS, but the long-term threat to the pattern. When ECH is universal, egress filtering needs to pivot to other signals (DNS-over-HTTPS observation, explicit forward-proxy auth, or L7 decrypting proxies).
  • Only works on TLS-using traffic. Non-TLS protocols need separate filtering by 5-tuple / DNS observation.
  • SNI can be spoofed — a compromised client can send a different SNI than the actual Host header inside the TLS tunnel. Downstream servers will usually reject the mismatch, but the allow-list firewall alone doesn't close this gap; layered controls (deep-packet-inspection proxy or mTLS pinning) are needed for strict zero-trust.
  • Wildcard scope. *.foo.com is trivially allowed; attacker- controlled subdomains under trusted parents defeat the check.

Seen in

  • systems/aws-network-firewall — the AWS implementation.
  • systems/aws-eks — the workload tenant behind the per-VPC egress filter.
  • systems/amazon-evs — workload tenant behind the centralised-inspection deployment of the same primitive.
  • concepts/mutual-tls — sibling TLS-based security primitive (identity-oriented rather than hostname-oriented).
  • concepts/centralized-network-inspection — architectural scale-out of hostname-based egress filtering across many VPCs.
  • patterns/dns-proxy-for-hostname-filtering — sibling hostname-based egress filtering at the DNS layer (via eBPF CGROUP_SOCK_ADDR + userspace DNS proxy), per-process attribution instead of per-flow middlebox log; GitHub's 2026-04 deploy-safety firewall is the canonical instance. Different point in the same design space: SNI is protocol-layer + middlebox, DNS is DNS-syscall-layer + on-host.
Last updated · 200 distilled / 1,178 read