Cybersecurity/Networking

TLS Termination at the Reverse Proxy vs End-to-End Encryption Inside Your Network

6 min read by DebuggedIt

Quick answer

Most web architectures put a reverse proxy or load balancer in front of the application and let it handle HTTPS. Traffic is encrypted between the user and the...

Most web architectures put a reverse proxy or load balancer in front of the application and let it handle HTTPS. Traffic is encrypted between the user and the proxy, then travels in plain HTTP to the backend. That setup is simple and common, but it raises a fair question for anyone thinking about security: is unencrypted traffic inside your own network acceptable? The honest answer depends on your threat model, your environment, and your compliance obligations.

The Three Common Patterns

With TLS termination, the proxy holds the certificate, decrypts incoming traffic, and forwards plain HTTP to the backend. With TLS passthrough, the proxy forwards the encrypted stream without decrypting it, so the backend terminates TLS itself. With re-encryption, sometimes called TLS bridging, the proxy decrypts the request, inspects or routes it, and opens a new TLS connection to the backend.

These patterns differ in what the proxy can see and do. Only termination and re-encryption allow the proxy to read HTTP, which is required for path-based routing, header manipulation, caching, compression, rate limiting, and web application firewall rules. Passthrough works at the connection level, so routing is limited to what is visible in the TLS handshake, such as the server name.

What Termination Gives You

Terminating at the edge centralizes certificate management. You renew and deploy certificates in one place rather than on every service, which removes a frequent cause of outages: an expired certificate on a forgotten backend. It also offloads cryptographic work, keeps application code simpler, and lets you apply consistent TLS settings such as minimum protocol versions and cipher suites.

For many small and medium deployments, where the proxy and the application run on the same host or in a tightly controlled private network, this is a reasonable and widely used design. The risk is real but narrow: anyone who gains a foothold on that internal network segment could observe or tamper with traffic between proxy and backend.

Why Teams Encrypt Internal Traffic Too

The perimeter model, where everything inside the network is trusted, has weakened as architectures moved to shared cloud networks, containers, and many internal services. Modern guidance often follows a defense-in-depth idea: assume an attacker may eventually reach the internal network, and limit what they can do there. Encrypting internal hops reduces the value of eavesdropping, and authenticating both sides prevents a rogue service from impersonating a legitimate one.

  • Shared infrastructure: if other tenants or teams share the network, or the network crosses data centers or availability zones, plain HTTP exposes data to more parties than you control.
  • Sensitive data: credentials, tokens, personal data, and payment information deserve protection on every hop, not only at the edge.
  • Compliance: some frameworks and contracts expect encryption of sensitive data in transit, including internal links. Read the specific requirements that apply to you rather than assuming.
  • Lateral movement: mutual TLS between services makes it harder for a compromised host to call other services freely.

Re-Encryption and Mutual TLS in Practice

The most common upgrade from plain termination is re-encryption: keep the proxy's ability to inspect traffic, but connect to backends over TLS and verify their certificates. The verification step is essential. Encrypting without verifying the backend certificate protects against passive eavesdropping only, and an active attacker could still impersonate the backend.

location / {
    proxy_pass https://app_backend;
    proxy_ssl_server_name on;
    proxy_ssl_name app.internal.example;
    proxy_ssl_verify on;
    proxy_ssl_trusted_certificate /etc/ssl/internal-ca.pem;

    # optional: present a client certificate for mutual TLS
    proxy_ssl_certificate     /etc/ssl/proxy-client.pem;
    proxy_ssl_certificate_key /etc/ssl/proxy-client.key;
}

Internal certificates usually come from a private certificate authority you operate or a managed one. The operational cost is the real obstacle: issuing, distributing, rotating, and revoking certificates for many services. Short-lived certificates with automated renewal reduce the damage of a leaked key, and automation through standard protocols or a service mesh keeps the workload manageable. If you cannot automate renewal, expect eventual expiry incidents.

Details That Break When You Terminate at the Proxy

When TLS ends at the proxy, the application no longer sees HTTPS directly. It must learn the original scheme from headers such as X-Forwarded-Proto, and it should only trust such headers when they come from your proxy, otherwise a client can spoof them. Misconfigured scheme detection causes redirect loops, insecure absolute URLs, and cookies that are not marked secure.

Review these items after any termination setup:

  • Set the Secure flag on session cookies and verify the application treats requests as HTTPS.
  • Send an HTTP Strict Transport Security header from the proxy once you are sure HTTPS works everywhere.
  • Make sure the backend is not reachable directly from the internet, so nobody can bypass the proxy and its protections.
  • Restrict backend access with network rules so only the proxy can connect.

Choosing for Your Situation

For a single host or a small private network with low sensitivity data, terminating at the proxy with strict network isolation can be adequate. For multi-tenant clouds, regulated data, or microservices with many internal calls, encrypting internal traffic and verifying identities is the safer default. Passthrough fits cases where the backend must see the client's raw TLS session or where you cannot let the proxy hold private keys.

Whatever you choose, document it as a conscious decision. A plain HTTP hop that is accepted with reasoning and compensating controls is far better than one nobody remembers exists.

Frequently Asked Questions

Is plain HTTP between a proxy and backend on the same host safe?

Traffic over a local loopback interface is not exposed to the network, so the risk is low. The remaining risk is other processes on that host, which you handle with host hardening and access controls.

Does re-encryption hurt performance?

There is extra handshake and encryption work, but connection reuse and keepalive make the overhead small for most workloads. Measure before assuming it is a problem.

Do I need mutual TLS everywhere?

Not necessarily. It is valuable where services must authenticate each other, but it adds certificate management work. Start with the most sensitive paths.

Can the proxy inspect traffic in passthrough mode?

No. In passthrough it cannot read the encrypted HTTP content, so features like WAF rules and header-based routing are unavailable at the proxy.

Summary

TLS termination at the reverse proxy is simple and centralizes certificate management, but leaves a plaintext hop inside your network. Re-encryption with certificate verification, and mutual TLS where services must authenticate each other, close that gap at the cost of more certificate operations. Choose based on data sensitivity, network trust, and compliance needs, and confirm configuration details in the documentation for your proxy and certificate tooling.