vectordotdev / vectordotdev/vector

TLS `server_name` override can be wrongly skipped when a direct destination shares an authority with an HTTPS proxy

Open
#25,914 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type: tech debt
Dominant language
Rust
Stars
22.6k
Forks
2.3k
Avg merge
1d 7h
Merged PRs (30d)
146

Description

Context

Follow-up to the tls.server_name OpenSSL fixes in #25881 and #25899.

To keep tls.server_name from being applied to the TLS connection to an HTTPS forward proxy (which must verify the proxy's own certificate against the proxy host), build_https_connector skips the server_name override when the per-connection callback's target authority matches a configured https:// proxy authority (ProxyAuthorities::matches, src/http.rs).

Problem

The connector callback only sees the target host:port of the connection it is dialing. A connection to a given authority can be either:

  • a legitimate TLS connection to the proxy (override should be skipped), or
  • a direct connection to a destination that happens to share the exact same host:port as the proxy — e.g. a no_proxy bypass, or an https:// destination not routed through a proxy that only intercepts a different scheme (override should be applied).

Both produce identical callback inputs but require opposite decisions, so when a direct destination's authority collides exactly with a configured https:// proxy authority, server_name is skipped and certificate verification falls back to the URL host — the very hostname mismatch this option is meant to avoid.

This is a pathological configuration (a data endpoint sharing the exact host:port with the forward proxy), but the behavior is silent.

Why it isn't easily fixed

  • The ambiguity is fundamental at the connector-callback layer: hyper-proxy reuses one inner connector for both proxy and direct (no_proxy) connections, and the destination URI is not known until request time.
  • Bringing no_proxy into the check does not disambiguate: the same authority can serve as both a proxy target and a no_proxy destination in the same config.
  • Early failure at init is not feasible centrally: build_proxy_connector / HttpClient::new do not know destination URIs at construction (they arrive per-request). The destination authority is only known inside each individual sink/source, so any early-fail check would have to be added per-component and would need to re-implement no_proxy / scheme-based routing to decide whether a given endpoint would be dialed directly — scattered, incomplete (dynamic/multiple endpoints), and not worth it for a pathological config.

Possible directions

  • Narrow the tracked authorities to proxy.https only (an https:// URL in the proxy.http field only tunnels plaintext http destinations, for which server_name is meaningless), removing one concrete slice of the problem.
  • Consider architectural options that make proxy vs. direct connections distinguishable at the TLS layer (e.g. separate connectors, or threading per-request intent into the callback).
  • Optionally, per-sink init-time validation/warning when a sink's endpoint authority collides with a configured proxy authority while tls.server_name is set.

References

  • PR #25899 (proxy handling for tls.server_name)
  • PR #25881 (initial tls.server_name OpenSSL verification fix)
  • src/http.rs: build_https_connector, ProxyAuthorities, tls_proxy_authority

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/http.rs at build_https_connector, ProxyAuthorities::matches, and tls_proxy_authority; read PRs #25881 and #25899 for the existing TLS override behavior. Determine an architectural direction that distinguishes proxy TLS connections from direct destinations with the same authority, while preserving proxy certificate verification; done means the collision no longer silently skips the intended server_name override.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
networking, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.