Setting up a wildcard SSL with Let's Encrypt and Nginx
Tags: tutorial, https, webdev, ssl
Published: 2021-05-29 00:00:00

---
title: "Setting up a wildcard SSL with Let's Encrypt and Nginx"
date: "2021-05-29"
categories: ["nginx", "ssl", "webdev", "tutorial", "https"]
---

Let's Encrypt has been a fantastic resource for any independent developer trying to stand up
a website on their own with the smallest amount of hassle. Some years ago SSL wasn't the default
choice and the process was expensive, tricky, and generally reserved for the companies who could
devote time and resources to actually figuring it out. Let's Encrypt along with its CLI tool,
`certbot` allow for the simple method of obtaining and retrieving a SSL site for your website.

The default instructions are aimed at setting up SSL for specific sites that you manage. However,
if you have multiple sites all under the same domain, and running on or proxied through the same 
server, it can save a lot of time to have a wildcard certificate. This means that the SSL cert will
apply to any subdomain of your overall domain without having to update the certificate. 

Unfortunately, `certbot` is unable to handle automagically configuring your webserver to apply 
the certificates because you have to prove you have ownership of the domain through some DNS 
challenge entries. Since domains are managed in a number of ways and require an additional layer
of authentication it's a manual process to update these certificates, which has to be done every 
90 days.

## Generating Certificates

The first step to setting up wildcard certs is installing `certbot`.
This can be done be following the instructions on [`certbot`'s site](https://certbot.eff.org/lets-encrypt/).

The software choice does not really matter because we'll be using a manual challenge method as opposed to
the automatic methods that can be used with those specific web server options.

Once `certbot` is installed the method of generating certs is:
```
sudo certbot certonly --manual --preferred-challenges=dns --server https://acme-v02.api.letsencrypt.org/directory -d \*.buzby.dev -d buzby.dev
```
For your own server, you'll want to replace the `*.buzby.dev` and `buzby.dev` with your own domain.

During this process `certbot` will pause to allow you to add TXT records to your domain with a specified key.
There will be two - one for each of the domain options specified. One thing to note is that the name of the 
TXT records will be your domain in both cases. This is ok because DNS allows you to configure multiple records 
with the same name by design.

Ensuring these have a short TTL (time-to-live) will help to make sure they get created / updated quickly
for the `certbot` authorization process.

Once this process is complete there will be new certificate files located in
`/etc/letsencrypt/live/<your domain>/` ready to use!

## Configuring Web Server

Now, since we had to run `certbot` in a manual process we have to configure the web server.
Nginx is one of the most popular, and one that I've been using for the last few years.

For your `server` blocks in Nginx sites you'll need four new fields to configure the site
with SSL.
```
server {

        listen 443 ssl; # Make sure the 'ssl' is added here as well

        ssl_certificate /etc/letsencrypt/live/buzby.dev/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/buzby.dev/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

        ...

}
```
(again replacing `buzby.dev` with your own domain)

If you additionally want to force redirect the server's HTTP port 80 traffic you can configure
a second server to redirect to the HTTPS server.

```
server {
        listen 80;
        
        server_name kyle.buzby.dev;

        if ($host = kyle.buzby.dev) {
                return 301 https://$host$request_uri;
        }
}
```

Now all the configuration is set - restart the server and you'll have a wildcard SSL certificate
active on your server!

```
sudo service nginx restart
```