envoyproxy / envoyproxy/envoy

dynamic_modules/tls: support auto_host_sni for runtime hosts and SNI-scoped session reuse

Open
#45,962 7 comments 0 reactions 0 assignees View on GitHub
help wanted
Dominant language
C++
Stars
28.9k
Forks
5.6k
Avg merge
1d 20h
Merged PRs (30d)
428

Description

*Title*: dynamic_modules/tls: support auto_host_sni for runtime hosts and SNI-scoped session reuse

*Description*:

I would like to propose making `auto_host_sni` usable with hosts added at runtime by dynamic-module clusters, and making upstream TLS session reuse safe when one shared `UpstreamTlsContext` connects to multiple effective SNI names.

cc @wbpcode for visibility/context.

Today, dynamic-module clusters can add hosts dynamically, but the host-add ABI only carries socket addresses. For HTTPS upstreams using:

```yaml
auto_host_sni: true
auto_sni_san_validation: true
```

Envoy needs a logical hostname on the selected `HostDescription`, separate from the concrete socket address used to connect. Without that, runtime-added hosts cannot cleanly use host-driven SNI/SAN validation without pushing per-host transport socket config through xDS.

There is also a related TLS correctness issue: upstream client TLS sessions are currently cached at `ClientContextImpl` scope. That is fine when a client TLS context maps to one server name, but when effective SNI varies by selected host, a session established for one SNI must not be offered to another SNI.

The proposed behavior is:

1. Extend the dynamic-module cluster host-add API so runtime-added hosts may carry an optional logical hostname.
2. Scope upstream client TLS session caching by effective SNI.
3. Include the router/async host-selection support needed for this to work after async `ChooseHost`.

Public API/interface notes:

- Add a dynamic-module cluster ABI path for adding hosts with optional hostnames.
- Preserve existing address-only ABI behavior and compatibility.
- Add or discuss TLS config surface for bounded SNI-scoped client session caching.
- No xDS per-host `transport_socket_matches` should be required for the target use case.

The PoC demonstrates one dynamic-module cluster with two HTTPS upstreams. Each runtime-added host has:

- a concrete resolved socket address for connection, and
- a distinct logical hostname for SNI/SAN validation.

The Envoy config uses one shared `UpstreamTlsContext` with:

```yaml
auto_host_sni: true
auto_sni_san_validation: true
```

Expected validation for an upstream implementation:

- dynamic-module cluster tests cover hostnames passed through the ABI, null/empty hostname legacy behavior, and synthesized hostname preservation.
- TLS tests cover session reuse within the same SNI and no reuse across different SNI names.
- TLS tests cover bounded eviction and empty-SNI behavior if SNI-scoped caching is configurable/bounded.
- router/async tests cover worker-local host resolution and transport socket option rebuild after async host selection.
- integration or regression coverage alternates requests between at least two runtime-added HTTPS hosts with distinct hostnames and verifies:
- both upstreams complete TLS successfully,
- SAN validation uses the selected host hostname,
- request order does not affect correctness,
- session resumption remains possible within the same SNI bucket only.

I am happy to split the implementation into reviewable PRs if maintainers prefer, but I think the issue should track the full behavior because the pieces interact.

[optional *Relevant Links*:]

- Minimal runnable example: https://github.com/dio/auto-sni-choose-host
- Prototype patch and notes: https://gist.github.com/dio/965d1e555909c02013ca882a2b3caa78
- Envoy contribution guidance: https://github.com/envoyproxy/envoy/blob/main/CONTRIBUTING.md

Contributor guide

Open the contributing guide

Research direction

Start with the dynamic-module cluster host-add ABI, upstream TLS session caching in ClientContextImpl, and the router/async ChooseHost path. Read the linked minimal runnable example and prototype notes for context, then trace existing tests in those areas. Done means runtime hostnames drive SNI and SAN validation, sessions are reused only within the same SNI, and async host selection preserves the required behavior, with the listed regression coverage.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
networking, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.