Written September 15, 2021
Zero Trust or BeyondProd approaches require authenticated and encrypted communications everywhere. TLS is the cryptographic protocol that powers encryption for all your technologies. For TLS, you need certificates. This practitioner's tutorial provides instructions for automating Nginx TLS certificate renewal and enabling server-side encryption.
Before you can configure Nginx TLS, you will need a certificate issued by a trusted certificate authority (CA). If you already have a certificate, private key, and CA root certificate from your organization's existing CA, you can skip to the Nginx TLS configuration section below. If you need to generate a certificate, you can:
step-ca
To request a certificate from your CA using the step
CLI, bootstrap your CA with step ca bootstrap
and run the following command (sub the server name for the actual name / DNS name of your Nginx server).
step ca certificate "myserver.example.net" server.crt server.key
Your certificate and private key will be saved in server.crt
and server.key
respectively.
Request a copy of your CA root certificate, which will be used to make sure each application can trust certificates presented by other applications.
step ca root ca.crt
Your certificate will be saved in ca.crt
.
In your Nginx configuration's server block, enable ssl
for the listening socket and specify the locations of the server's certificate and private key. We'll also tell Nginx to use TLS protocols and our preferred ciphers:
server {
listen 443 ssl;
server_name myserver.example.net;
ssl_certificate /path/to/server.crt;
ssl_certificate_key /path/to/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# ...
}
Send a reload
signal to Nginx to apply your new configuration:
nginx -s reload
To make sure Nginx is presenting a valid certificate, you can use the curl
command, passing it your root certificate for use in verifying the server.
$ curl --cacert ca.crt https://myserver.example.net
HTTP/2 200
...
Smallstep CAs use provisioners to authenticate certificate requests using passwords, one-time tokens, single sign-on, and a variety of other mechanisms.
step
CLI and do not require a local network agent. The instructions below focus on the JWK provisioner, but can be repurposed with small tweaks to operationalize all non-ACME provisioners.To learn more, see Configuring step-ca
Provisioners.
The right provisioner depends on your operational environment.
The JWK provisioner is the most general-purpose provisioner. It supports password and one-time token-based authentication. To add a JWK provisioner called nginx
to a hosted Certificate Manager authority (if you haven't already), run:
step ca provisioner add nginx --type JWK --create --x509-default-dur 720h
For instructions on adding provisioners to open source step-ca
, or to learn more about other provisioner types, see Configuring step-ca
Provisioners.
We've created a systemd
-based certificate renewal timer that works with step
. Check out our documentation on Renewal using systemd timers for background on how these timers work.
To install the certificate renewal unit files, run:
cd /etc/systemd/system
sudo curl -sL https://files.smallstep.com/cert-renewer@.service \
-o cert-renewer@.service
sudo curl -sL https://files.smallstep.com/cert-renewer@.timer \
-o cert-renewer@.timer
The renewal timer will check your certificate files every five minutes and renew them after two-thirds of their lifetime has elapsed.
The cert-renewer@.service
and cert-renewer@.timer
files define a service unit template. Templates are never run directly, but we will run an instance of them for Nginx certificate renewals. That service will be called cert-renewer@nginx.service
, which parallels the nginx.service
unit name used by Nginx on systemd-based Linux distributions. Because the two units share this value in their name, the cert-renewer@nginx.service
renewer will attempt to reload or restart nginx.service
after it renews the certificate.
To start the renewal timer, run:
sudo systemctl daemon-reload
sudo systemctl enable --now cert-renewer@nginx.timer
You'll see that the timer is active, by checking the output of systemctl list-timers
.
Once Nginx TLS is configured, you'll need to make sure that clients know to trust certificates signed by your CA. For certificates signed by a public CA (like Let's Encrypt), most clients already include the CA root certificate in their trust stores for certificate verification. But, for a private CA, you will need to explicitly add your CA's root certificate to your clients' trust stores.
The step
CLI includes a utility command for this purpose on many systems:
step certificate install ca.crt
Rather than manually running the above for each machine that needs to trust your CA, most teams will use some form of automation to distribute the root certificate. Depending on your needs and your IT or DevOps team's approach, this may be a configuration management tool (like Ansible or Puppet), a Mobile Device Management (MDM) solution, or something else. Some examples:
ca.crt
directly to the ca-ceritficates
bundle on linux VMs so running applications trust the API servers they callca.crt
directly into base Docker images for gRPC so gRPC clients can always reference the trusted CAca.crt
in a Kubernetes Secret
and inject it into an environment variable for access from application codeca.crt
in the trust stores of every employee Macbook so their web browsers trust internal websitesstep certificate install ca.crt
on target machines that want curl
to implicity trust the CAca.crt
in a Kubernetes ConfigMap
and mount it to pods for reference on the filesystemAlternatively, many clients support passing the CA root certificate as a flag or argument at runtime.
The Practical Zero Trust project is a collection of living documents detailing TLS configuration across a broad spread of technologies. We'd love to make this document better. Feel free to contribute any improvements directly on GitHub.
Unsubscribe anytime. See our privacy policy.
© 2023 Smallstep Labs, Inc. All rights reserved.