Create Let’s Encrypt Wildcard Certificates in NGINX

Posted on

Create Let’s Encrypt Wildcard Certificates in NGINX

Let’s Encrypt is a free, automated, and open certificate authority (CA) that provides SSL/TLS certificates for enabling HTTPS on your website. Let’s Encrypt wildcard certificates allow you to secure unlimited subdomains under a base domain (e.g. *.example.com).

In this tutorial, we will show you how to use Certbot to generate Let’s Encrypt wildcard certificates and set up HTTPS on an Nginx web server. The ability to secure your entire domain and its subdomains with a single certificate significantly simplifies SSL/TLS management.

Prerequisites

Before following this guide, you’ll need:

  • A server running Ubuntu (or a similar Debian-based distribution).
  • Nginx installed.
  • Certbot installed.
  • DNS control panel access to your domain.

Install Nginx:

$ sudo apt install nginx

Install Certbot and the Nginx plugin:

$ sudo apt install certbot python3-certbot-nginx

Once you have met all the prerequisites, let’s move on to generating wildcard certificates.

Step 1 – Generating Wildcard Certificates

Certbot includes a certonly command for obtaining SSL/TLS certificates. To generate a wildcard certificate for *.example.com, run:

$ sudo certbot certonly --manual --preferred-challenges=dns --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d *.example.com

This tells Certbot to:

  • certonly: Obtain a certificate but don’t install it.
  • --manual: Use the manual authentication method.
  • --preferred-challenges=dns: Use DNS-01 challenge for validation.
  • --server: Specify the Let’s Encrypt ACME v2 server.
  • --agree-tos: Agree to the Let’s Encrypt terms of service.
  • -d *.example.com: Specify the domain to secure with a wildcard certificate.

You will be prompted to enter an email address for certificate expiration notifications. Enter your email and press Enter.

Next, Certbot will provide TXT records that need to be created in your domain’s DNS to validate control over the domain. Create these TXT records in your DNS control panel, then press Enter to continue. The DNS TXT records usually contain long alphanumeric strings. Make sure you copy them correctly. The exact steps to adding a DNS record depend on your DNS provider (e.g., GoDaddy, Cloudflare, Namecheap, etc.).

Certbot will wait for the DNS changes to propagate globally and verify the TXT records. If successful, the wildcard certificate (fullchain.pem) and private key (privkey.pem) will be saved under /etc/letsencrypt/live/example.com/.

Step 2 – Configuring Nginx

With the wildcard certificate generated, we can now configure Nginx.

First, create a new Nginx server block for the main example.com domain:

$ sudo nano /etc/nginx/sites-available/example.com

Add the following configuration:

server {
    listen 80;
    listen [::]:80;
    server_name example.com;
    return 301 https://$host$request_uri;
}
server {
   listen 443 ssl http2;
   listen [::]:443 ssl http2;
   server_name example.com;
   ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
   # Other SSL config
   ...
}

This configures HTTPS using the Let’s Encrypt certificate and redirects HTTP traffic to HTTPS. The return 301 directive tells the browser to permanently redirect HTTP requests to the HTTPS equivalent.

Next, create a server block for the wildcard subdomain *.example.com:

$ sudo nano /etc/nginx/sites-available/wildcard.example.com
server {
  listen 80;
  listen [::]:80;
  server_name *.example.com;
  return 301 https://$host$request_uri;
}
server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  server_name *.example.com;
  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
  # Other SSL config
  ...
}

This will handle all subdomains using the same wildcard certificate. The server_name *.example.com; directive tells Nginx to accept requests for any subdomain of example.com.

Activate the server blocks:

$ sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
$ sudo ln -s /etc/nginx/sites-available/wildcard.example.com /etc/nginx/sites-enabled/

Finally, test the Nginx configuration and reload it if successful:

$ sudo nginx -t
$ sudo systemctl reload nginx

Your wildcard certificate should now be working! Try accessing your site over HTTPS and various subdomains to confirm.

Automating Renewal

Let’s Encrypt certificates expire after 90 days, so you’ll need to renew them regularly.

You can automate renewal using Certbot’s renew command. Create a cron job to run daily:

$ sudo crontab -e

Add this line which will run Certbot daily and renew if certificates are expiring in less than 30 days:

0 0 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"

This will renew your certificates automatically before they expire! The --quiet option suppresses output. The --post-hook option executes a command after a successful renewal. In this case, it reloads Nginx to use the updated certificate.

Conclusion

That’s it! You should now have Let’s Encrypt wildcard certificates issued by Certbot set up for your domain. This allows you to enable HTTPS across your main domain and any subdomains with just a single certificate.

The certificates will renew automatically, providing ongoing HTTPS protection for your site. This offers your visitors security, trust, and SEO benefits.

As Let’s Encrypt issues trusted certificates for free, there’s no reason not to use HTTPS everywhere with wildcard certificates. Enjoy your secured site! Using Let’s Encrypt wildcard certificates provides a robust and cost-effective solution for securing your web applications.

Alternative Solutions for Obtaining Let’s Encrypt Wildcard Certificates

While the above method using Certbot’s certonly command and manual DNS challenge is effective, it can be somewhat cumbersome, especially when dealing with frequent renewals or multiple domains. Here are two alternative solutions that leverage DNS API integration for automated DNS challenge handling:

1. Using Certbot with DNS Plugins

Certbot offers plugins that automate the DNS challenge process by directly interacting with your DNS provider’s API. This eliminates the need for manual TXT record creation and verification.

Explanation:

Instead of the --manual flag, you would use a specific plugin for your DNS provider (e.g., --dns-cloudflare, --dns-digitalocean, --dns-route53, etc.). These plugins require you to provide API credentials so that Certbot can automatically create, verify, and delete the TXT records required for the DNS challenge.

Example (using the Cloudflare plugin):

First, install the Cloudflare plugin:

sudo apt install python3-certbot-dns-cloudflare

Next, you’ll need to configure Cloudflare API credentials. The exact method depends on the plugin, but typically involves creating a configuration file (e.g., cloudflare.ini) containing your Cloudflare email and API key:

# cloudflare.ini
dns_cloudflare_email = your_cloudflare_email@example.com
dns_cloudflare_api_key = YOUR_CLOUDFLARE_API_KEY

Then, run Certbot with the Cloudflare plugin:

sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /path/to/cloudflare.ini -d *.example.com --server https://acme-v02.api.letsencrypt.org/directory --agree-tos --email your_email@example.com

Certbot will now automatically handle the DNS challenge using the Cloudflare API. This significantly simplifies the process and makes automated renewal much easier. Remember to consult the specific plugin’s documentation for detailed instructions on configuration and usage.

2. Using ACME Clients with DNS API Support (e.g., acme.sh)

acme.sh is another popular ACME client that supports a wide range of DNS providers. It’s a simpler alternative to Certbot, as it’s a single shell script and doesn’t require a full Python environment.

Explanation:

acme.sh uses environment variables or configuration files to store your DNS API credentials. It then uses these credentials to automatically create, verify, and delete the TXT records for the DNS challenge.

Example (using acme.sh with Cloudflare):

First, install acme.sh:

curl https://get.acme.sh | sh

Source the acme.sh script to make it available in your current shell:

source ~/.acme.sh/acme.sh

Configure Cloudflare API credentials:

export CF_Key="YOUR_CLOUDFLARE_API_KEY"
export CF_Email="your_cloudflare_email@example.com"

Issue the wildcard certificate:

~/.acme.sh/acme.sh --issue --dns dns_cf -d example.com -d *.example.com

Install the certificate to Nginx:

~/.acme.sh/acme.sh --installcert -d example.com 
--key-file       /etc/nginx/ssl/example.com.key  
--fullchain-file /etc/nginx/ssl/example.com.crt 
--reloadcmd     "systemctl reload nginx"

acme.sh will automatically renew the certificate and reload Nginx.

These alternative methods greatly simplify the process of obtaining and renewing Let’s Encrypt wildcard certificates, especially when using a DNS provider with API support. They offer a more streamlined and automated experience compared to the manual DNS challenge method. Always choose the method that best suits your technical skills and infrastructure requirements. The key is to automate as much as possible for worry-free certificate management. The initial setup might take some time, but the long-term benefits of automation are significant.