TLS Termination¶
Real traffic is almost never plain HTTP. Nginx is typically the place the TLS handshake actually happens — the app behind it often never sees an encrypted connection at all.
TL;DR — in 30 seconds:
- When nginx terminates TLS, it completes the client's handshake itself and talks to the app behind it in plain HTTP over a trusted internal network — the app never holds a certificate.
- Three directives in a
serverblock do it:listen 443 ssl,ssl_certificate, andssl_certificate_key. - Redirecting HTTP → HTTPS needs its own
serverblock on port 80 — a TLS-only listener can't accept the unencrypted connection needed to issue that redirect.
1. What "terminating TLS" means¶
When nginx terminates TLS, it is the endpoint the client's TLS handshake actually completes with: nginx decrypts the incoming HTTPS connection, and from that point on can talk to the app behind it in plain HTTP over a trusted internal network. The app itself never has to hold a certificate or handle a handshake at all.
sequenceDiagram
participant Client
participant N as nginx
participant App as Upstream app
Client->>N: TLS handshake (HTTPS)
N-->>Client: Encrypted connection established
N->>App: Plain HTTP request
App-->>N: Plain HTTP response
N-->>Client: Encrypted response
2. The directives that make it possible¶
| Directive | What it does |
|---|---|
listen 443 ssl |
Opens an HTTPS listener on this server block |
ssl_certificate |
Path to the certificate (public key) presented to the client |
ssl_certificate_key |
Path to the matching private key |
These three directives, inside a server block, are the minimum needed for that server block to
terminate TLS for incoming connections.
3. The HTTP → HTTPS redirect¶
A plain-HTTP server block on port 80 exists purely to send clients on to HTTPS — it accepts the
unencrypted connection first (a TLS-only listener can't even receive it), then issues a redirect:
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
This is a separate server block, not a directive added to the port-443 one — the redirect has to be
served over plain HTTP, before any TLS handshake with that block could even begin.
4. How this connects¶
- Once TLS is terminated, what nginx does with the now-decrypted request is exactly the routing and proxying covered in Reverse proxy & static content and the next page, Proxying & load balancing.
- The TLS handshake itself sits on top of the TCP handshake covered in the Networking module's HTTP/TCP/SSH
page — nginx's
listen 443 sslis doing, at the application layer, what that page described in the abstract.
You can defend this when you can explain what changes for the app behind nginx once TLS is terminated
at nginx (rather than passed through), and why the HTTP→HTTPS redirect needs its own server block.