Automate Wildcard SSL on Nginx with Certbot & Cloudflare: A 2025 Guide

Secure your Nginx server with automated wildcard SSL certificates using Certbot and Cloudflare. This guide details the DNS-01 challenge, secure credential management, and automatic renewal for *.yourdomain.com.

Automated wildcard SSL certificate setup for Nginx using Certbot and Cloudflare.
Securing your web infrastructure with automated wildcard SSL certificates is crucial for modern online operations.

In the modern web, HTTPS is non-negotiable. It secures user data, builds trust, and is a recognized factor in search engine rankings. While obtaining an SSL certificate for a single domain is straightforward with Let's Encrypt, managing certificates for multiple subdomains (www, api, blog, etc.) can quickly become a tedious chore. The definitive solution is a wildcard certificate, which secures your root domain and all its subdomains with a single stroke.

This guide provides a comprehensive, step-by-step walkthrough for setting up a fully automated wildcard SSL certificate on an Ubuntu server running Nginx. We will leverage the power of Certbot, the security of the Cloudflare API, and the robust DNS-01 challenge method. By following this tutorial, you will build a "set-and-forget" system that handles SSL issuance and renewal automatically, freeing you to focus on your applications.

Prerequisites

Before we begin, ensure you have the following in place:

  • An Ubuntu Server: This guide is tested on Ubuntu 22.04 LTS and 24.04 LTS, but should work on other recent versions.
  • Nginx Installed: You must have Nginx installed and configured with a server block for your domain.
  • A Domain Managed by Cloudflare: Your domain's DNS must be managed through Cloudflare, as we will use its API for verification.
  • Sudo Access: You will need sudo privileges to install software and modify configuration files.
  • DNS Records: Your root domain (e.g., yourdomain.com) and at least one subdomain (e.g., www.yourdomain.com) should have A or AAAA records pointing to your server's public IP address.

The "Why": Understanding the DNS-01 Challenge

To issue a certificate, Let's Encrypt must verify that you control the domain. The two most common verification methods, or "challenges," are HTTP-01 and DNS-01. For our goal, the choice is critical.

  • HTTP-01 Challenge: Let's Encrypt asks your server to host a specific file at a specific URL on your domain. This works well for single domains but cannot be used for wildcard certificates. A wildcard like *.yourdomain.com represents an infinite number of potential hostnames, and it's impossible to place a file on all of them.
  • DNS-01 Challenge: Let's Encrypt gives you a unique token and asks you to place it in a TXT record in your domain's DNS settings. Because you can create a TXT record for _acme-challenge.yourdomain.com, you can prove control over the entire domain and all its subdomains. This is the only method that supports wildcard certificates.

By using the Cloudflare API, we can automate this DNS-01 challenge. Certbot will programmatically create the required TXT record, get the certificate, and then clean up the record afterward.

Step 1: Install Certbot and the Cloudflare DNS Plugin

We will use snap to install Certbot, as this is the method recommended by the EFF and ensures you always have the latest version.

First, if you have any old Certbot packages installed via apt, it's crucial to remove them to avoid conflicts.

sudo apt-get remove certbot

Next, install the core Certbot snap package.

sudo snap install --classic certbot

Now, prepare Certbot for use by creating a symbolic link to its executable. This makes the certbot command available system-wide.

sudo ln -s /snap/bin/certbot /usr/bin/certbot

Finally, install the specific plugin that allows Certbot to interact with the Cloudflare API.

sudo snap install certbot-dns-cloudflare

Verification: Run certbot --version to confirm the installation was successful. You should see the installed version number.

Step 2: Create a Cloudflare API Token and Secure Credentials

Certbot needs permission to modify your domain's DNS records. We will create a restricted API token in Cloudflare that has only the necessary permissions. This is far more secure than using your global API key.

  1. Log in to your Cloudflare dashboard.
  2. Navigate to My Profile > API Tokens.
  3. Click Create Token.
  4. Find the "Edit zone DNS" template and click Use template.
  5. Configure the token with the following settings:
    • Token name: Give it a descriptive name, like certbot-dns-yourdomain.com.
    • Permissions: The template automatically selects Zone:DNS:Edit. This is what we need.
    • Zone Resources: Select Specific zone and choose the domain you want to secure from the dropdown list. This is a critical security step that limits the token's power to only one domain.
  6. Click Continue to summary, then Create Token.

Cloudflare will display your new API token. Copy this token immediately and store it somewhere safe. You will not be able to see it again.

Now, back on your server, create a directory to store the Cloudflare credentials file.

sudo mkdir -p /etc/letsencrypt/cloudflare

Create a new file for your credentials.

sudo nano /etc/letsencrypt/cloudflare/cloudflare.ini

Add the following line to the file, replacing YOUR_CLOUDFLARE_API_TOKEN with the token you just copied.

# Cloudflare API token
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN

Save and close the file (Ctrl+X, Y, Enter).

Finally, and most importantly, secure this file by setting strict permissions so that only the root user can read it.

sudo chmod 600 /etc/letsencrypt/cloudflare/cloudflare.ini

Step 3: Obtain the Wildcard SSL Certificate

With the setup complete, we can now request the wildcard certificate from Let's Encrypt. We will request a certificate that covers both the root domain (yourdomain.com) and all subdomains (*.yourdomain.com).

Run the following command, replacing yourdomain.com with your actual domain name.

sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/cloudflare.ini \
  -d yourdomain.com \
  -d "*.yourdomain.com" \
  --preferred-challenges dns-01 \
  --server https://acme-v02.api.letsencrypt.org/directory

Let's break down this command:

  • certonly: Tells Certbot to obtain the certificate but not install it in Nginx automatically just yet. This gives us more control.
  • --dns-cloudflare: Specifies that we are using the Cloudflare DNS plugin for verification.
  • --dns-cloudflare-credentials: Points to the secure credentials file we created.
  • -d yourdomain.com -d "*.yourdomain.com": Specifies the hostnames to include in the certificate. Including both ensures the root domain and all subdomains are covered.
  • --preferred-challenges dns-01: Explicitly tells Certbot to use the DNS challenge method.
  • --server ...: Forces the use of the ACMEv2 protocol, which is required for wildcard certificates.

Certbot will now connect to the Cloudflare API, create the necessary TXT records, wait for them to propagate, and complete the challenge. If successful, you will see a message indicating that your certificate and key have been saved in /etc/letsencrypt/live/yourdomain.com/.

Step 4: Configure Nginx to Use the Wildcard Certificate

Now that we have the certificate, we need to tell Nginx to use it. Open your Nginx server block configuration file for your domain. It's typically located in /etc/nginx/sites-available/.

sudo nano /etc/nginx/sites-available/yourdomain.com

Your configuration should be modified to look similar to this. This example sets up two server blocks: one to redirect all HTTP traffic to HTTPS, and another to handle the secure HTTPS traffic for both the root domain and all subdomains.

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name yourdomain.com *.yourdomain.com;
    return 301 https://$host$request_uri;
}

# Main HTTPS server block for the domain and all subdomains
server {
    listen 443 ssl http2;
    server_name yourdomain.com *.yourdomain.com;

    # SSL Configuration
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    # Include recommended SSL security settings
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    # Your other configuration (root, location blocks, etc.)
    root /var/www/yourdomain.com/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

Key Directives:

  • listen 443 ssl http2;: Tells Nginx to listen for secure traffic on port 443 and enable HTTP/2 for better performance.
  • server_name yourdomain.com *.yourdomain.com;: This is crucial. It tells Nginx that this server block should handle requests for both the root domain and any subdomain.
  • ssl_certificate: Points to the full certificate chain file provided by Certbot.
  • ssl_certificate_key: Points to the private key for your certificate.
  • include /etc/letsencrypt/options-ssl-nginx.conf;: Certbot provides a file with strong, up-to-date SSL security parameters. Including it is highly recommended.

After saving the file, test your Nginx configuration for syntax errors.

sudo nginx -t

If the test is successful, reload Nginx to apply the changes.

sudo systemctl reload nginx

Verification: Open your browser and navigate to https://yourdomain.com and https://www.yourdomain.com (or any other subdomain). You should see the padlock icon, indicating a secure connection.

Step 5: Verify Automatic Renewal

Let's Encrypt certificates are valid for 90 days. The snap package for Certbot automatically creates a systemd timer that runs twice a day to check for certificates that are due for renewal (typically within 30 days of expiry).

You can verify that the renewal process will work correctly by performing a "dry run".

sudo certbot renew --dry-run

This command will simulate the renewal process, including the DNS-01 challenge with Cloudflare. It will not actually renew your certificate, but it will confirm that your credentials and setup are correct for automation. If the dry run completes without errors, your system is fully configured for automatic, hands-off SSL renewal.

Conclusion and Next Steps

Congratulations! You have successfully secured your Nginx server with a wildcard SSL certificate that will renew automatically. You no longer need to worry about manually issuing or renewing certificates for new subdomains. As long as a subdomain's DNS record points to this server, it will be automatically covered by the wildcard certificate.

From here, you can further enhance your server's security by:

  • Implementing HTTP Strict Transport Security (HSTS): Add an add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; directive to your HTTPS server block to instruct browsers to only communicate with your server over a secure connection.
  • Regularly Auditing Security: Use tools like SSL Labs' SSL Test to periodically check your server's SSL configuration and ensure it remains A+ rated.

By automating this critical piece of security infrastructure, you've built a more robust, secure, and low-maintenance web presence.

Subscribe to Root Logic

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe