nginx sends the client everything in the ssl_certificate file — that is where the chain goes.
HTTPS in nginx takes three lines in a server block:
listen 443 ssl is port 443 with TLS on it, ssl_certificate is the certificate file, and ssl_certificate_key is its private key.
A certificate in a file is written as PEM text — a block from -----BEGIN CERTIFICATE----- to -----END CERTIFICATE-----. A full chain file is such blocks one after another: the site certificate first, then the intermediate. The root does not go into the file: the client already has it. nginx matches the key from ssl_certificate_key against the first certificate in the file.
cat joins the file, and sudo tee writes it to /etc/nginx/tls, where only root can write — >/dev/null hides the copy tee prints to the screen:
From there it is like any nginx edit: the new file's path in ssl_certificate, sudo nginx -t and sudo systemctl reload nginx. reload returns before the new nginx processes start answering, so run the check as a separate command.
Serve the whole chain
Make nginx serve the site's certificate together with the intermediate one, /etc/nginx/tls/lab-issuing-ca.crt, for app.lab.test. The site's configuration is /etc/nginx/sites-available/app, the certificates are in /etc/nginx/tls.
Goals · 0 of 2
- Build a chain file and point nginx to it not done yet
- Open app.lab.test over HTTPS without an error not done yet
A colleague built the chain file in reverse order — cat lab-issuing-ca.crt app.crt — and pointed ssl_certificate to it. What will sudo nginx -t answer?
-
It never gets to curl:
nginx -trejects the file — the site's key does not match the first certificate, Lab Issuing CA. -
nginx matches the key from
ssl_certificate_keyagainst the file's first certificate. Lab Issuing CA comes first, while the key belongs to the site.
nginx checks the key against the file's first certificate, which is why the site's certificate goes first.