Describe the feature you'd like
Topology / motivation
We run a single cloudflared connector on a shared edge/bastion host, deliberately not on every origin:
- no direct inbound path to the origins (they're only reachable from the connector over the internal network)
- we don't want to deploy/maintain the
cloudflared binary on every service host
- a single connector is a centralized chokepoint for traffic monitoring and egress control -- connection/flow logs, destinations, traffic volumes, and tunnel/connector health observed in one place, instead of scattered across every origin host
The connector reaches internal services over HTTPS; those services carry their own self-signed / internally-issued certificates.
Problem
For a public hostname with service: https://internal-host, cloudflared acts as an L7 reverse proxy: it terminates the request, sees the full plaintext, then re-encrypts to the origin. So the connector host holds cleartext for all proxied traffic. If that shared host is compromised, passive capture and active MITM are trivial -- which is exactly the blast radius we were trying to avoid by not co-locating the connector with each origin.
We are fine with Cloudflare's edge terminating the public TLS (we want edge WAF/Access/cache). What we want is to stop extending that plaintext trust to the connector VM we operate.
service: tcp:// makes the connector blind, but the hostname is then no longer reachable directly from a browser (it needs cloudflared access/WARP on the client side), which breaks the "just open the URL" UX for a public hostname.
Desired outcome
A mode where:
- the public HTTPS hostname stays browser-accessible (TLS terminated at the CF edge, as today -- edge L7 features still apply)
- the edge->origin leg is end-to-end TLS that transits the connector as opaque ciphertext --
cloudflared forwards bytes to the configured internal destination without decrypting
- the origin presents a self-signed or Cloudflare-issued cert (a la Cloudflare Origin CA), and certificate validation for that leg happens at the CF edge (Full / Full-strict semantics), not at the connector
Net effect: a compromised connector host can no longer read or MITM application payloads (edge-side cert validation also prevents redirect-MITM), while origins stay non-internet-exposed and browser-direct access is preserved.
This stays compatible with the centralized-monitoring goal above: as a blind relay the connector still sees connection-level metadata (source flow, destination host:port, byte counts, timing) for flow logging and egress policy -- only the payload bytes become opaque, not the visibility into which flows go where.
One possible mechanism (just one option -- the right design is Cloudflare's to make):
- a per-rule
originRequest mode, e.g. tlsPassthrough: true, or a service: https+passthrough://internal-host:443 scheme -- the hostname->destination mapping from ingress is preserved
- data plane: instead of the cloudflared-facing edge sending a decoded HTTP request over the tunnel, it originates the origin-side TLS itself (validating the origin cert via an uploaded CA / CF Origin CA) and relays that TLS stream over the tunnel as an opaque stream (reusing the existing TCP/stream path).
cloudflared dials the rule's destination and pipes bytes -- no RoundTrip, no TLS termination at the connector
- conceptually: "Full (Strict) SSL for Tunnel origins, with the connector as a transparent relay" -- bring the existing Origin CA / Full-strict trust model to a tunneled origin while taking the connector out of the payload trust boundary
Honest trade-offs / open questions:
- This is not a connector-only change -- it needs Cloudflare Edge support. Today the connector receives structured HTTP over the tunnel; making it blind requires the edge to originate origin-side TLS and relay opaque bytes. A change in
cloudflared alone is insufficient.
- Connector-side L7 features are lost for such hostnames: per-path ingress routing within a hostname, HTTP-level Access middleware applied at the connector, header injection, connector request logs. Edge-side WAF/cache/Access/edge-logs are unaffected (the edge still terminates the public TLS). Per-hostname routing is fine (known at registration); per-path is not.
- Trust boundary: origin-cert validation must happen at the edge for the guarantee to hold (the connector is blind and can't validate) -- operators configure the origin CA exactly as with classic Origin CA / Full-strict today.
- Residual risk: this protects payload confidentiality/integrity against a compromised connector host and blocks redirect-MITM, but a compromised connector can still observe metadata (timing, byte counts, destination/SNI), cause DoS, or attempt credential/registration abuse. It reduces blast radius; it is not full isolation.
Describe alternatives you've considered
service: tcp:// + cloudflared access / WARP-to-Tunnel (private network routing): blind, end-to-end encrypted, supports self-signed origins -- but requires a client (WARP or cloudflared access) on the consumer side. Not browser-direct for a public hostname. Fails the "just open the URL, no client" requirement
- Classic Full (Strict) + Cloudflare Origin CA: gives exactly the desired edge<->origin trust model, but requires the origin to be directly reachable from Cloudflare's edge -- which defeats the "no direct inbound to origin, connector-only ingress" requirement
- Run
cloudflared on each origin host: keeps plaintext local to the origin, but defeats the "one connector, don't deploy the binary everywhere" operational goal and enlarges the maintenance/attack surface
--no-tls-verify / caPool / originServerName: only affect the connector->origin leg; they don't change the fact that the connector still sees plaintext
Additional context
Related / adjacent issues:
Prior art inside Cloudflare: Spectrum already relays opaque TLS for L4 apps; this asks for an analogous edge-validated, connector-blind relay for HTTP apps served via Tunnel, while keeping edge-side L7 intact.
Describe the feature you'd like
Topology / motivation
We run a single
cloudflaredconnector on a shared edge/bastion host, deliberately not on every origin:cloudflaredbinary on every service hostThe connector reaches internal services over HTTPS; those services carry their own self-signed / internally-issued certificates.
Problem
For a public hostname with
service: https://internal-host,cloudflaredacts as an L7 reverse proxy: it terminates the request, sees the full plaintext, then re-encrypts to the origin. So the connector host holds cleartext for all proxied traffic. If that shared host is compromised, passive capture and active MITM are trivial -- which is exactly the blast radius we were trying to avoid by not co-locating the connector with each origin.We are fine with Cloudflare's edge terminating the public TLS (we want edge WAF/Access/cache). What we want is to stop extending that plaintext trust to the connector VM we operate.
service: tcp://makes the connector blind, but the hostname is then no longer reachable directly from a browser (it needscloudflared access/WARP on the client side), which breaks the "just open the URL" UX for a public hostname.Desired outcome
A mode where:
cloudflaredforwards bytes to the configured internal destination without decryptingNet effect: a compromised connector host can no longer read or MITM application payloads (edge-side cert validation also prevents redirect-MITM), while origins stay non-internet-exposed and browser-direct access is preserved.
This stays compatible with the centralized-monitoring goal above: as a blind relay the connector still sees connection-level metadata (source flow, destination
host:port, byte counts, timing) for flow logging and egress policy -- only the payload bytes become opaque, not the visibility into which flows go where.One possible mechanism (just one option -- the right design is Cloudflare's to make):
originRequestmode, e.g.tlsPassthrough: true, or aservice: https+passthrough://internal-host:443scheme -- the hostname->destination mapping from ingress is preservedcloudflareddials the rule's destination and pipes bytes -- noRoundTrip, no TLS termination at the connectorHonest trade-offs / open questions:
cloudflaredalone is insufficient.Describe alternatives you've considered
service: tcp://+cloudflared access/ WARP-to-Tunnel (private network routing): blind, end-to-end encrypted, supports self-signed origins -- but requires a client (WARP orcloudflared access) on the consumer side. Not browser-direct for a public hostname. Fails the "just open the URL, no client" requirementcloudflaredon each origin host: keeps plaintext local to the origin, but defeats the "one connector, don't deploy the binary everywhere" operational goal and enlarges the maintenance/attack surface--no-tls-verify/caPool/originServerName: only affect the connector->origin leg; they don't change the fact that the connector still sees plaintextAdditional context
Related / adjacent issues:
Prior art inside Cloudflare: Spectrum already relays opaque TLS for L4 apps; this asks for an analogous edge-validated, connector-blind relay for HTTP apps served via Tunnel, while keeping edge-side L7 intact.