Self-hosting guides reach for the same move to put a service on the internet safely: a Cloudflare Tunnel, or a VPS running nginx or Caddy as a reverse proxy. Both work, both hide your home IP, and both are sold as "secure remote access" with no mention of the one question that decides whether your traffic is private: where does TLS get terminated? Whoever terminates it reads your plaintext. For most of these setups that is not you.

[INFO]
This is a mechanism explainer, not an argument against tunnels - they solve a real problem well. The point is to know, precisely, which party can read your traffic in each arrangement, so you choose it on purpose. The demo lets you flip between the common setups and watch the middle box switch between reading plaintext and relaying sealed ciphertext.
◈ interactive artifact
Where Does TLS Terminate?
Cloudflare Tunnel, Cloudflare Flexible, a VPS reverse proxy, and TCP passthrough - watch which hops carry plaintext and who in the middle can read it.

//Terminating TLS Means Reading the Plaintext

"Terminating TLS" means being the endpoint that decrypts the connection. HTTPS is encrypted between two parties, and the party that holds the private key and decrypts the stream sees everything inside it - URLs, headers, cookies, request bodies, responses. When a middlebox terminates your visitors' TLS, there are really two separate encrypted connections - visitor to middlebox, and middlebox to origin - with the middlebox in the clear between them. That is not a flaw; it is how a reverse proxy does caching, routing and filtering. It just means the middlebox is a party that reads your traffic.

//The Cloudflare Tunnel, Specifically

A Cloudflare Tunnel runs cloudflared on your box, which makes an outbound-only connection to Cloudflare's edge. Nothing listens for inbound connections on your origin, and you can close every inbound port on your router - a genuine and large security win, and the reason the tunnel is popular. Your home IP never appears in DNS; visitors only ever reach Cloudflare.

But the visitor's HTTPS session terminates at Cloudflare's edge. Cloudflare decrypts your traffic there to proxy and cache it, then opens a second encrypted connection to your origin (in Full or Full Strict mode). In between, Cloudflare sees your plaintext. This is documented behaviour, not a secret - it is how the product provides its features - but it is the thing the "secure tunnel" framing elides. The honest one-liner: a Cloudflare Tunnel hides your service from everyone except Cloudflare.

[WARNING]
Cloudflare's Flexible SSL mode is the one to avoid. The edge terminates TLS as usual, but the hop from Cloudflare to your origin is plain, unencrypted HTTP across the internet. The visitor sees a padlock and assumes end-to-end encryption; the second half of the path has none. If you use Cloudflare in front of an origin, use Full (Strict). (This matters less with a Tunnel, where the cloudflared connection is encrypted regardless, and more with a bare proxied A record.)

//A VPS Reverse Proxy Is the Same Trust Shape

Fronting your service with a VPS running nginx or Caddy puts the TLS endpoint on the VPS. It decrypts every request before forwarding it, so it reads your plaintext exactly as Cloudflare's edge does. The difference is custody: you own and operate the VPS, which is better if you secure it well and worse if you do not - a small internet-facing box you forget to patch is now a machine that sees all your traffic and has a public IP of its own.

//The One Arrangement Where Only You Read It

If you want the middle to be unable to read your traffic, it must not terminate TLS. In a TCP passthrough setup - HAProxy in TCP mode, or SNI-based routing without decryption - the middlebox reads only the server name from the handshake to know where to forward, then relays the still-encrypted stream. A reverse SSH tunnel carrying an already-TLS connection has the same shape. Only your origin holds the keys, so only your origin sees plaintext.

The cost is that you lose everything that needs to see inside the request at the edge: caching, a web application firewall, path-based routing, header rewriting, HTTP/2 multiplexing. Passthrough is the right call when end-to-end confidentiality past the middlebox matters more than edge features - and the wrong call when you actually wanted those features and assumed you could have them and privacy too.

[TECHNICAL NOTE]
The decision is not "which tunnel is best" but "who do I accept as a reader of my plaintext, in exchange for what." Cloudflare Tunnel: Cloudflare reads it, you get a hidden origin and no open ports. VPS proxy: you read it, you run another box. Passthrough: nobody in the middle reads it, you give up edge features. All three can be the right answer; none of them is "nobody can see my traffic."

//Sourcing and Framing

The cloudflared outbound-only connection model, the no-open-ports and hidden-origin properties, and the two-connection SSL-mode architecture (visitor to edge, edge to origin, with Flexible leaving the origin leg unencrypted) are from Cloudflare's own developer documentation. The TLS-termination reasoning - that the party holding the key reads the plaintext - is standard TLS, and the HAProxy SNI-routing / TCP-passthrough behaviour is from HAProxy's documented modes. The framing is this site's recurring one: these tools relocate who can see your traffic, and the useful literacy is naming that party on purpose rather than inheriting it from a tutorial.