sodcalculator

10 Tech How-To

Setup Let’s Encrypt Nginx Ubuntu

Guide 10-9126 · Updated · Step by step

To set up Let’s Encrypt on Nginx running on Ubuntu, you install Certbot, obtain a certificate for your domain, and configure Nginx to use it. This guide walks through the standard process using Certbot’s Nginx plugin, which automates certificate issuance and web server configuration.

Prerequisites

Before you begin, ensure you have:

  • Ubuntu 20.04 or 22.04 (the steps are similar on other versions)
  • Nginx installed and running (sudo apt install nginx)
  • A domain name pointing to your server’s public IP address
  • Port 80 (HTTP) open to the internet – Let’s Encrypt uses HTTP-01 challenges by default
  • SSH access to the server with sudo privileges

Install Certbot

Certbot is the official client for Let’s Encrypt. On Ubuntu, it’s available in the default repositories. Install it along with the Nginx plugin:

  1. Update the package list: sudo apt update
  2. Install Certbot and the Nginx plugin: sudo apt install certbot python3-certbot-nginx

This installs the certbot command and the plugin that automatically edits your Nginx configuration.

Obtain and Install the Certificate

Run Certbot with the Nginx plugin. It will detect your server blocks and ask which domain(s) to enable HTTPS for:

  1. Run sudo certbot --nginx
  2. Follow the prompts: enter your email address, agree to the terms, and select the domain(s) you want to secure (usually just your main domain and www).
  3. Choose whether to redirect HTTP to HTTPS – selecting 2 (redirect) is recommended for security.

Certbot will automatically obtain a certificate, install it in your Nginx configuration, and reload Nginx to apply the changes. You should see a success message like Congratulations! You have successfully enabled HTTPS.

Verify and Test Renewal

Let’s Encrypt certificates are valid for 90 days, so automatic renewal is essential. Certbot installs a systemd timer that runs twice a day and renews any certificate within 30 days of expiry.

  1. Test the renewal process with sudo certbot renew --dry-run. This simulates renewal without actually changing anything.
  2. Check the timer status: systemctl status certbot.timer

If the dry run succeeds, your automatic renewal is working. If it fails, check the logs in /var/log/letsencrypt.

Common Problems and Solutions

  • DNS not resolving: Ensure your domain’s A record points to your server’s public IP. Use dig example.com to check.
  • Port 80 blocked: Let’s Encrypt needs port 80 open. Check your firewall (UFW) with sudo ufw status and allow HTTP: sudo ufw allow 'Nginx Full'.
  • Nginx server block missing: Certbot needs a server block for your domain. Create one in /etc/nginx/sites-available/ and enable it with a symlink to /etc/nginx/sites-enabled/ before running Certbot.
  • Rate limits: Let’s Encrypt has rate limits (e.g., 5 duplicate certificates per week). If you hit them, wait or use the staging environment for testing.
  • Certificate not renewing: Check the timer and logs. Sometimes the renewal fails because the Nginx configuration was edited manually after issuance.

Manual Configuration (Optional)

If you prefer to configure Nginx manually, you can obtain a certificate with the webroot method:

  1. Run sudo certbot certonly --webroot -w /var/www/html -d example.com
  2. Then edit your Nginx server block to point to the certificate files:
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    # ... rest of config
}

This gives you more control but requires you to handle renewal hooks and configuration reloads yourself.

Security Considerations

HTTPS encrypts data in transit, but it’s not a complete security solution. Keep your system updated (sudo apt upgrade), use strong SSH passwords or keys, and consider a firewall. For production, you may also want to enable HSTS (HTTP Strict Transport Security) to force browsers to use HTTPS. Certbot can add this with sudo certbot --nginx --hsts, but be aware it’s a permanent commitment – once enabled, browsers will refuse to connect via HTTP for the specified period.

Frequently Asked Questions

How long does a Let’s Encrypt certificate last?

Let’s Encrypt certificates are valid for 90 days. Certbot automatically renews them when they are within 30 days of expiry, so you don’t need to worry about manual renewal as long as the timer is running.

Can I use Let’s Encrypt with a wildcard domain?

Yes, but it requires DNS-01 challenge, which Certbot does not automate with the Nginx plugin. You need to use certbot certonly --manual --preferred-challenges dns and manually create a TXT record, or use a DNS plugin if your provider supports it.

What if my domain uses a CDN or reverse proxy?

If your domain is behind a CDN (like Cloudflare) or a reverse proxy, the HTTP-01 challenge may fail because the request goes to the CDN, not your server. You can either temporarily disable the CDN, use DNS-01 challenge, or configure the CDN to forward the challenge to your origin server.

How do I force HTTPS on all requests?

Certbot’s Nginx plugin can add a redirect for you. If you chose not to, you can manually add a redirect in your server block: return 301 https://$host$request_uri; in a server block listening on port 80.

Is it safe to run Certbot automatically?

Yes, Certbot is the official client from the Let’s Encrypt project. It only modifies your Nginx configuration when you ask it to, and it creates backups. Automatic renewal is safe and recommended.

What if I already have a certificate from another provider?

You can replace it with a Let’s Encrypt certificate. Just run sudo certbot --nginx and it will install the new certificate. You may need to remove the old certificate files manually, but Certbot will handle the Nginx configuration.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →