How to Generate LetsEncrypt Wildcard Certificates
Using certbot to generate a wildcard certificate.
There is pretty good documentation on how to generate LetsEncrypt SSL certificates for $0 and install them quickly. I was skeptical at first, but once I started using LetsEncrypt, I would never go back.
First, you have to install the CLI utility. certbot
, which can be downloaded from this URL, assuming you are running nginx on Ubuntu. You can also choose your personalized combination in case you are using a different web server and/or operating system.
Once you get certbot
Utility running on your server, for wildcard certificates you need to authenticate with your DNS provider additionally.
I happen to be using DnsMadeEasy, but you can choose from many supported providers from this URL.
When I read about the DnsMadeEasy plugin, I see that I can run the following commands once I install the plugin:
certbot certonly \
--dns-dnsmadeeasy \
--dns-dnsmadeeasy-credentials ~/.secrets/certbot/dnsmadeeasy.ini \
-d example.com \
-d www.example.com
This does require you to obtain API keys from your DNS provider, and in the case of DnsMadeEasy we can store them in the following file:
~/.secrets/certbot/dnsmadeeasy.ini
Which looks like this (the keys in this example are not real):
dns_dnsmadeeasy_api_key = 394u398f-f322-af32-ee98-34989023984
dns_dnsmadeeasy_secret_key = ac4c3b45-83745-aab8-d8f7-fag8987709
The last trick with wildcard DNS is that you typically have to specify the actual domain without the wildcard and the one with it.
Assuming my desired domain is “apps.dev”, and its DNS is hosted by DnsMadeEasy, and I copied my API keys into the credentials file, here is the command line that generates the keys:
certbot certonly \
--dns-dnsmadeeasy \
--dns-dnsmadeeasy-credentials ~/.secrets/certbot/dnsmadeeasy.ini \
-d apps.dev \
-d '*.apps.dev'
This generates the certificates into the following folder on Ubuntu, and the certificates will work for both https://foo.apps.dev
as well as https://apps.dev
/etc/letsencrypt/live/apps.dev-0001/fullchain.pem
/etc/letsencrypt/live/apps.dev-0001/privkey.pem
The final step is adding the certificate info into the nginx config file for this domain. Assuming you are storing it in nginx/sites-enabled/start.apps.dev.conf
it should look like this:
server {
listen 443;
server_name apps.dev;
server_name *.apps.dev;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_certificate /etc/letsencrypt/live/apps.dev-0001/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/apps.dev-0001/privkey.pem;
client_max_body_size 50M;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Request-Start "t=${msec}";
location / {
root your-html-directory;
}
}
Do not forget to verify that the configuration is valid before restarting nginx:
❯ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
And after that, you should be able to restart the nginx service and have your domain work with the new certificate:
sudo systemctl restart nginx
Connect to https://foo.apps.dev/ and https://apps.dev and ensure you get a valid certificate, no warnings, and all is well.
Happy certificate hunting, and I hope this post saved somebody a bit of time.
Very best,
Konstantin
June 2024.