DEV Community

Akash for MechCloud Academy

Posted on

The Ultimate Guide to Let's Encrypt Wildcard SSL on Ubuntu (2026)

πŸ‘‹ Introduction

In the web infrastructure landscape of 2026, HTTPS is no longer just a "best practice" - it is a strict requirement. With browsers now aggressively blocking non-secure content and search engines penalizing HTTP sites, securing your data in transit is the first step in any deployment.

However, as your architecture scales, so does the administrative burden. You might start with a simple landing page at example.com. But soon, your ecosystem grows. You need api.example.com for your backend, dashboard.example.com for your customers, staging.example.com for your developers, and auth.example.com for identity management.

Managing individual SSL certificates for 10, 20, or 50 subdomains is a SysAdmin’s nightmare. It involves tracking dozens of expiry dates, managing multiple validation tokens, and cluttering your Nginx or Apache configurations with endless lines of certificate directives.

The Solution? The Wildcard Certificate.

In this comprehensive guide, we will walk through exactly how to generate a Let's Encrypt Wildcard Certificate using the latest Certbot 5.x on Ubuntu 24.04 LTS. We won't just run commands; we will dive deep into how the ACME protocol works, why we use specific validation methods, and how to automate the entire process to future-proof your infrastructure against shrinking certificate lifetimes.

🧐 What is a Wildcard Certificate?

Before we open the terminal, it is crucial to understand the cryptographic distinction of the asset we are creating.

A standard SSL certificate is strictly bound to a specific Fully Qualified Domain Name (FQDN). If you generate a certificate for example.com, it protects example.com and usually www.example.com (if specifically requested). It does not protect mail.example.com or shop.example.com. To secure those, you would traditionally need to generate separate certificates or append them as Subject Alternative Names (SANs) - a process that becomes unmanageable quickly.

A Wildcard Certificate, denoted by an asterisk (*), secures the domain and all its first-level subdomains with a single pair of cryptographic keys.

The Scope of Protection

If you generate a certificate for *.example.com, it covers:

  • www.example.com
  • api.example.com
  • blog.example.com
  • v1.example.com

Important Nuance: A wildcard certificate typically covers only one level of depth. It does not automatically cover nested subdomains like db.internal.example.com. Additionally, the wildcard *.example.com does not strictly cover the root domain example.com itself in many browser implementations, so standard practice is to request both example.com and *.example.com in the same certificate request.

Why Let's Encrypt?

In the legacy web, wildcard certificates were premium products costing hundreds of dollars per year per domain. Let's Encrypt, the free, automated, and open certificate authority (CA) run by the ISRG, changed the industry by offering free wildcard certificates via the ACME v2 protocol.

As of 2026, Let's Encrypt protects hundreds of millions of websites, and with the release of Certbot 5.x, the tooling has become more robust, handling edge cases and newer Python environments (like Python 3.12+) with greater stability.

πŸ›  Prerequisites

To follow this tutorial efficiently, ensure you have the following ready:

  1. Ubuntu Server: This guide is optimized for Ubuntu 24.04 LTS (Noble Numbat), though steps remain compatible with 22.04 and 20.04.
  2. Root/Sudo Access: You need administrative privileges to install snaps, open ports, and modify configuration files in /etc/.
  3. A Registered Domain: You must own the domain you are trying to secure.
  4. Access to DNS Records: This is the most critical requirement. Unlike standard certificates which can be validated via HTTP (uploading a file to your web root), wildcard certificates require DNS-level verification. You must be able to add TXT records to your domain's DNS zone (e.g., via Cloudflare, AWS Route53, Namecheap, or DigitalOcean).

πŸ“¦ Step 1: Installing Certbot 5.x (The Modern Way)

Certbot is the official Electronic Frontier Foundation (EFF) client for Let's Encrypt. While you can technically install Certbot via apt or pip, the Certbot team and the EFF strongly recommend using snap.

Why Snap in 2026?
OS package managers often "freeze" package versions for stability. Ubuntu 24.04's default repositories might host an older version of Certbot (e.g., 2.x or 3.x). However, the SSL landscape evolves rapidly. By using Snap, you ensure you are running the latest Certbot 5.2+, which includes critical fixes for modern Python environments and updated ACME compliance standards.

1. Update your system

First, ensure your package index is fresh to avoid conflicts.

sudo apt update && sudo apt upgrade -y
Enter fullscreen mode Exit fullscreen mode

2. Install Snapd

On Ubuntu 24.04, snapd is pre-installed. If you are on a stripped-down cloud image or a different distribution, install it manually:

sudo apt install snapd
Enter fullscreen mode Exit fullscreen mode

3. Remove legacy Certbot versions

If you have previously installed certbot using apt or python3-certbot-nginx, remove them. Mixing installation methods often leads to "command not found" errors or version mismatches.

sudo apt-get remove certbot
Enter fullscreen mode Exit fullscreen mode

4. Install Certbot via Snap

Now, install the classic snap package. The --classic flag is required because Certbot needs full access to the system to modify web server configurations and write to root-owned directories.

sudo snap install --classic certbot
Enter fullscreen mode Exit fullscreen mode

5. Prepare the command

Snap installs binaries in /snap/bin/. To ensure you can run the certbot command from any directory, create a symbolic link.

sudo ln -s /snap/bin/certbot /usr/bin/certbot
Enter fullscreen mode Exit fullscreen mode

6. Verify the Version

Check that you are running the modern release series.

certbot --version
Enter fullscreen mode Exit fullscreen mode

Expected Output:

certbot 5.2.1
Enter fullscreen mode Exit fullscreen mode

(Or higher, depending on when you run this).

🧠 Step 2: The Mechanics of the "DNS Challenge"

This is where many developers get confused. It is vital to understand why we are performing the next steps.

When you ask Let's Encrypt for a standard certificate (e.g., just www.example.com), Certbot usually performs an HTTP-01 Challenge.

  1. Certbot creates a token file.
  2. It places this file in your web root (.well-known/acme-challenge/).
  3. Let's Encrypt downloads it via http://www.example.com.
  4. Success implies server control.

Wildcard Certificates are different.

Because a wildcard certificate allows you to secure any subdomain - even ones that don't exist yet - Let's Encrypt requires a higher level of trust. You must prove you control the entire domain zone, not just a specific web server.

This is done via the DNS-01 Challenge.

  1. Certbot provides a random alphanumeric string.
  2. You place this string in a DNS TXT Record.
  3. Let's Encrypt queries your domain's authoritative name servers.
  4. If the string matches, the certificate is issued.

πŸš€ Step 3: Generating the Certificate (Manual Method)

We will start with the manual method to understand the process. Later, we will discuss the automated method (which is recommended for production).

Run the following command. Replace yourdomain.com with your actual domain.

sudo certbot certonly \
  --manual \
  --preferred-challenges=dns \
  --email admin@yourdomain.com \
  --server https://acme-v02.api.letsencrypt.org/directory \
  --agree-tos \
  -d *.yourdomain.com \
  -d yourdomain.com
Enter fullscreen mode Exit fullscreen mode

Breaking down the command:

  • certonly: Tells Certbot to obtain the certificate files but not edit your Nginx/Apache config.
  • --manual: Indicates that we will perform the validation steps (adding DNS records) by hand.
  • --preferred-challenges=dns: Forces the DNS-01 challenge type, required for wildcards.
  • -d *.yourdomain.com: The wildcard domain.
  • -d yourdomain.com: The root domain. It is best practice to bundle these.

πŸ›‘ Step 4: The Validation Phase

Certbot will initialize and then pause, displaying instructions like this:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.yourdomain.com with the following value:

82j8_RandomStringHere_9921

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
Enter fullscreen mode Exit fullscreen mode

⚠️ STOP! Do not press Enter yet.

If you press Enter now, the validation will fail because the record does not exist yet.

Adding the DNS Record

  1. Log in to your DNS Provider (Cloudflare, GoDaddy, Namecheap, etc.).
  2. Navigate to DNS Management.
  3. Add a New Record:
    • Type: TXT
    • Host: _acme-challenge
      • Note: Most modern providers append your domain automatically. If you type _acme-challenge.yourdomain.com, the provider might save it as _acme-challenge.yourdomain.com.yourdomain.com. Usually, entering just _acme-challenge is correct.
    • Value: Paste the random string from Certbot.
    • TTL: Set to "Automatic" or 60 seconds.

Step 5: Verify DNS Propagation

DNS propagation is not instant. While Cloudflare is fast (seconds), other providers can take minutes.

Open a new terminal window (keep Certbot open in the first one) and verify the record is visible to the world.

Using dig:

dig _acme-challenge.yourdomain.com TXT +short
Enter fullscreen mode Exit fullscreen mode

Using nslookup:

nslookup -q=TXT _acme-challenge.yourdomain.com
Enter fullscreen mode Exit fullscreen mode

What to look for:
You should see the random string you pasted. If you see no output or an old string, wait 60 seconds and try again.

Only when the output matches the string provided by Certbot should you return to the first terminal and press Enter.

πŸŽ‰ Step 6: Success & File Locations

If the validation succeeds, Certbot 5.x will display a success message:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/yourdomain.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/yourdomain.com/privkey.pem
Enter fullscreen mode Exit fullscreen mode

These are your assets:

  1. fullchain.pem: The public certificate + intermediate chain. This is what you show to the world.
  2. privkey.pem: The private key. Keep this secret.

Security Warning: These files are owned by root. Do not change their permissions to 777. If your application (e.g., Node.js or Java) runs as a non-root user, consider using access control lists (ACLs) or copying the certs to a dedicated application directory with restricted ownership.

βš™οΈ Step 7: Configuring Web Servers (2026 Standards)

Now we must configure the web server to use the new wildcard certificate.

Option A: Nginx Configuration

In 2026, we prioritize TLS 1.3 and strong ciphers.

Edit your Nginx config (/etc/nginx/sites-available/default):

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

server {
    listen 443 ssl;
    # Enable HTTP/2 for performance (or http3 if configured)
    http2 on; 

    server_name yourdomain.com *.yourdomain.com;

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

    # Modern Security Settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305";

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
Enter fullscreen mode Exit fullscreen mode

Test and reload:

sudo nginx -t && sudo systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

Option B: Apache Configuration

Edit your VirtualHost file:

<VirtualHost *:443>
    ServerName yourdomain.com
    ServerAlias *.yourdomain.com

    DocumentRoot /var/www/html

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem

    # Modern Protocols
    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
</VirtualHost>
Enter fullscreen mode Exit fullscreen mode

πŸ”„ The Critical Part: Automating Renewal

Here is the "gotcha" with the manual method.

Let's Encrypt certificates are valid for 90 days.
Because we used --manual, Certbot cannot automatically renew this certificate. It cannot log into your DNS dashboard and update the TXT record for you.

If you leave it like this, your site will show a security warning in 90 days unless you manually repeat Step 3.

The Solution: DNS Plugins

To achieve "Set and Forget" automation, you must use a Certbot DNS Plugin. These plugins utilize your DNS provider's API to add the TXT record automatically.

Example: Automating with Cloudflare

  1. Install the Cloudflare Plugin:
    Since we used Snap, we install the plugin via Snap too:

    sudo snap set certbot trust-plugin-with-root=ok
    sudo snap install certbot-dns-cloudflare
    
  2. Get your API Token:

    Log in to Cloudflare -> My Profile -> API Tokens -> Create Token -> Template: "Edit Zone DNS".

  3. Create a Credentials File:
    Create ~/.secrets/certbot/cloudflare.ini:

    dns_cloudflare_api_token = YOUR_LONG_API_TOKEN_HERE
    

    Secure the file:

    chmod 600 ~/.secrets/certbot/cloudflare.ini
    
  4. Run Certbot (Automated Mode):

    sudo certbot certonly \
      --dns-cloudflare \
      --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
      -d *.yourdomain.com \
      -d yourdomain.com
    

Now, Certbot handles everything. The background timer (systemctl list-timers) will check twice a day and renew your wildcard cert automatically when it gets close to expiry.

πŸ› Troubleshooting

1. "Plugin not found"
If you installed Certbot via apt but the plugin via snap (or vice versa), they cannot see each other. Ensure you remove all apt versions and strictly use snap for both core and plugins.

2. "NXDOMAIN" Errors during validation
This means Let's Encrypt tried to verify your domain before the DNS change propagated. Increase the delay or ensure your DNS provider's TTL is set to the minimum (60s).

3. "Certificate Mismatch"
If you visit api.yourdomain.com and get a warning, check the certificate details in the browser. If the "Subject Alternative Name" (SAN) only lists yourdomain.com and not *.yourdomain.com, you missed the wildcard flag during generation.

🏁 Conclusion

Generating a Wildcard SSL certificate with Certbot 5.x on Ubuntu 24.04 is a powerful skill. It simplifies your operational overhead, allowing you to spin up new environments (dev.app.com, test.app.com) without ever thinking about SSL issuance again.

While the manual method is excellent for learning, automation via DNS plugins is the standard for production. With the industry moving toward potentially shorter certificate lifetimes in the future, mastering the automated DNS challenge is essential for any modern DevOps engineer.


About the Author:
Content from MechCloud Academy. We simplify DevOps, Cloud, and Linux for developers. Follow us for more tutorials on Docker, Kubernetes, and System Administration.

Top comments (0)