# Automating SSL/TLS Certificate Renewals in NGINX

> Automatically renew and install SSL/TLS certificates on NGINX from Windows ADCS or DigiCert. ITVA makes a new key, tests the config, and reloads with no downtime.

Section: PKI & CLM / Automation  
Source: https://www.itva.com/docs/automation/automating-ssl-tls-certificate-renewals-in-nginx  
Last updated: 2026-11-03

**In short:** to automate SSL/TLS certificate renewal in NGINX with ITVA, issue the certificate with a key generated on the server. Then add an SSH install that copies the key and certificate into place and runs `nginx -t && systemctl reload nginx`. Last, turn on Auto Renew.

This guide sets up hands-off certificate renewal for NGINX on Linux. When you finish, ITVA renews the certificate before it expires, installs the new certificate and key on the server, tests the NGINX configuration, and reloads NGINX. A reload starts new worker processes with the new certificate while the old workers finish their open connections.

For how installs work in general, see [How certificate installs work](https://www.itva.com/docs/automation/how-certificate-installs-work).

## Before you begin

- Add the NGINX server to ITVA as a device with SSH credentials and a probe. See [Add your first device](https://www.itva.com/docs/getting-started/add-your-first-device).
- Make sure the SSH account can run `sudo cp`, `sudo nginx -t`, and `sudo systemctl reload nginx` without a password prompt. The install script runs without a terminal, so it cannot answer a prompt.
- Create an enrollment for the site, with an enabled CA template. See [Set up certificate templates](https://www.itva.com/docs/pki-clm/set-up-certificate-templates).
- Find the certificate and key paths in your NGINX server block. This guide uses the paths below. Change them to match your server.

`/etc/nginx/sites-enabled/default`

```
ssl_certificate     /etc/nginx/ssl/pqc/itva_nginx.crt;
ssl_certificate_key /etc/nginx/ssl/itva_nginx.key;
```

## Step 1: Issue the certificate with a key generated on the server

Generate the key on the NGINX server so that it never leaves the server. ITVA then creates a new key at the same path at each renewal.

1. Open the enrollment and select **Issue**.
2. Select **Generate on Device**. In **Device**, select the NGINX server.
3. In **Private Key Path**, type `.itva/itva_nginx`. A relative path starts in the home folder of the SSH account. ITVA creates the folder if it does not exist.
4. In **Private Key Algorithm**, select an algorithm that the CA template allows.
5. Submit the request and wait for the certificate to issue.

To use a post-quantum ML-DSA key, the server needs OpenSSL 3.5 or later. NGINX must also be built with an OpenSSL version that supports ML-DSA. Check with `nginx -V`.

## Step 2: Add an install with the NGINX reload script

1. On the **Installs** card of the enrollment, select **Install**.
2. In **Format**, select **OpenSSL - PEM**. Keep **Include private key** off. The key is already on the server.
3. Turn on **Include certificate chain**. NGINX sends the intermediate certificates from the `ssl_certificate` file. ITVA writes the server certificate first and the chain after it, which is the order NGINX needs.
4. Make sure **Auto Install** is on.
5. Select **SSH**. In **Device**, select the NGINX server.
6. In **Path**, type `.itva/itva_nginx.crt`. The probe writes the certificate here.
7. In **Script**, paste the script below. Change the destination paths to match your server block.

```sh
sudo cp .itva/itva_nginx /etc/nginx/ssl/itva_nginx.key
sudo cp {{PATH}} /etc/nginx/ssl/pqc/itva_nginx.crt
sudo nginx -t && sudo systemctl reload nginx
```

8. Select **Save**. ITVA installs the current certificate immediately.

The script does three things:

- Copies the key that ITVA generated on the server to the path in `ssl_certificate_key`.
- Copies the new certificate to the path in `ssl_certificate`. ITVA replaces `{{PATH}}` with the value of **Path** before it runs the script.
- Tests the configuration with `nginx -t`, and reloads NGINX only if the test passes. If the test fails, NGINX keeps serving the old certificate, and the install job fails with the error.

## Step 3: Turn on auto renew

1. Open the enrollment.
2. Turn on the **Auto Renew** switch.

By default, ITVA renews the certificate 14 days before it expires. At each renewal, ITVA generates a new key at `.itva/itva_nginx`, gets the new certificate from the issuer, writes it to `.itva/itva_nginx.crt`, and runs the script. NGINX keeps using its own copies in `/etc/nginx/ssl` until the script replaces them together.

## Check that it worked

1. On the **Installs** card, make sure the latest job has the status **Completed**.
2. From any computer that can reach the site, check the certificate that NGINX serves. Replace `<HOSTNAME>` with the name of the site.

```sh
echo | openssl s_client -connect <HOSTNAME>:443 -servername <HOSTNAME> 2>/dev/null | openssl x509 -noout -subject -serial -enddate
```

3. Make sure the serial number and expiry date match the latest certificate of the enrollment.

**Caution:** if the last renewal failed, do not select **Reinstall**. The renewal may have replaced the key at `.itva/itva_nginx` without issuing a certificate for it. Fix the cause and renew again first. In other cases, **Reinstall** is a safe way to test the script.

## Troubleshooting

| Message or symptom | Cause and fix |
| --- | --- |
| The device '<name>' does not have a primary or secondary probe assigned. | Assign a probe to the NGINX server device. |
| Failed to install 'certificate' to '<device>' at '<path>'. | The probe could not write the file. Check the SSH credentials of the device and that the account can write to Path. |
| sudo: a terminal is required to read the password | The SSH account needs a password for sudo. Allow the commands in the script without a password in sudoers. |
| nginx: [emerg] ... key values mismatch | The key and certificate do not belong together, for example after a renewal that failed at the issuer. Renew the enrollment again. |
| The job is Completed but browsers still get the old certificate | The paths in the script do not match ssl_certificate and ssl_certificate_key. Fix the script, then select Reinstall. |
| Browsers report an incomplete chain | Include certificate chain is off. Edit the install, turn it on, and save. |
