Install Wildcard Certs From Let's Encrypt in Nginx on Ubuntu 19.04

Published on: Fri, Aug 23, 2019 at 11:17 am EST
Security Ubuntu Web Servers

In March 2018 Let's Encrypt added support for wildcard certificates. Wildcard certificates let you secure all first-level subdomains of a domain with a single certificate. Wildcard certificates are only obtainable through ACMEv2, which is an updated version of the ACME protocol. To utilize ACMEv2 for a wildcard or non-wildcard certificates, you'll need a client that has been updated to support ACMEv2. One such client is acme.sh, which is an ACME/ACMEv2 protocol client written purely in Shell (Unix shell) language without any dependencies. Furthermore, wildcard domains must be validated using the DNS-01 challenge type. That implies that you need to modify DNS TXT records to prove control over a domain to obtain a wildcard certificate.

In this guide, we explain how to obtain and deploy free wildcard certs from Let's Encrypt on Ubuntu 19.04 by using acme.sh client, Lexicon tool for automatic manipulation of DNS records by consuming Vultr API and deploy certs to the Nginx web server.

Requirements

  • Freshly deployed Ubuntu 19.04 Vultr cloud server.
  • You have a registered domain name. This guide uses example.com as an example domain.
  • Make sure you have set A/AAAA and CNAME DNS records for your Fully Qualified Domain Name (FQDN). You may wish to consult Introduction to Vultr DNS tutorial if you need to familiarize yourself with DNS concepts.
  • Vultr API Access enabled in your Vultr account control panel.

Before you begin

Check the Ubuntu version.

lsb_release -ds
# Ubuntu 19.04

Create a new user account with sudo access and your preferred username and switch to it. We use johndoe.

adduser johndoe --gecos "John Doe"
usermod -aG sudo johndoe
su - johndoe

NOTE: Replace johndoe with your username.

Set up the timezone.

sudo dpkg-reconfigure tzdata

Ensure that your Ubuntu system is up to date.

sudo apt update && sudo apt upgrade -y

Install the necessary packages.

sudo apt install -y git wget curl socat

Install Nginx

Install the Nginx web server.

sudo apt install -y nginx

Check the version.

sudo nginx -v
# nginx version: nginx/1.15.9 (Ubuntu)

Install Python and Lexicon

As a first step in the process of obtaining wildcard certificates from Let's Encrypt using acme.sh and Vultr API, you need to install Python and Lexicon. Lexicon is a Python package that provides a way to manipulate DNS records on multiple DNS providers in a standardized way.

Install Python if not already installed on your system.

sudo apt install -y python3

Confirm the installation by verifying the version.

python3 --version
# Python 3.7.3

Install the Lexicon tool. A lexicon is a Python tool that allows you to manipulate DNS records on various DNS providers in a standardized way.

sudo apt install -y lexicon

Check the Lexicon version.

lexicon --version
# lexicon 3.0.8

Install acme.sh client

Acme.sh is an ACME protocol client written purely in Shell (Unix shell) language that automates the process of getting a signed certificate via Let’s Encrypt. It supports ACME v1 and ACME v2, and most importantly it supports ACME v2 wildcard certs. In this section, we install an Acme.sh script.

NOTE: It is recommended to use root user to install acme.sh, although it does not require root/sudo access.

Switch to root user from the regular user if you have created it.

sudo su - root

Download and install acme.sh.

git clone https://github.com/Neilpang/acme.sh.git
cd acme.sh
./acme.sh --install --accountemail "your_email@example.com"
source ~/.bashrc
cd

Check the version.

acme.sh --version
# v2.8.2

Obtain wildcard certs from Let's Encrypt

To obtain a wildcard cert, we can only use the DNS validation method. We use Lexicon and Vultr DNS API to manipulate TXT DNS records.

Obtain RSA and ECC wildcard certs for your domain.

# Configure your API key and username
export PROVIDER=vultr
export LEXICON_VULTR_USERNAME="your_vultr_email@example.com"
export LEXICON_VULTR_TOKEN="XXXXXXXXXXXXXXX"

# RSA 2048
acme.sh --issue --dns dns_lexicon -d example.com -d '*.example.com' --keylength 2048
# ECC 256
acme.sh --issue --dns dns_lexicon -d example.com -d '*.example.com' --keylength ec-256

NOTE: Don't forget to replace example.com with your domain name, and replace the Vultr API placeholder values with your own.

After running the preceding commands, your certificates and keys are in:

  • For RSA: ~/.acme.sh/example.com directory.
  • For ECC/ECDSA: ~/.acme.sh/example.com_ecc directory.

NOTE: You should not use the cert files in ~/.acme.sh/ folder, they are for internal usage only, the directory structure may change in the future.

To list your certs, you can run:

acme.sh --list

Create a folder to store your certs in production. We use /etc/letsencrypt directory.

sudo mkdir -p /etc/letsencrypt/example.com
sudo mkdir -p /etc/letsencrypt/example.com_ecc

Install/copy certificates for production use on your server.

# RSA
acme.sh --install-cert -d example.com \
        --cert-file /etc/letsencrypt/example.com/cert.pem \
        --key-file /etc/letsencrypt/example.com/private.key \
        --fullchain-file /etc/letsencrypt/example.com/fullchain.pem \
        --reloadcmd "sudo systemctl reload nginx.service"

# ECC/ECDSA
acme.sh --install-cert -d example.com --ecc \
        --cert-file /etc/letsencrypt/example.com_ecc/cert.pem \
        --key-file /etc/letsencrypt/example.com_ecc/private.key \
        --fullchain-file /etc/letsencrypt/example.com_ecc/fullchain.pem \
        --reloadcmd "sudo systemctl reload nginx.service"

Now that we have successfully obtained wildcard certs from Let's Encrypt, we need to configure Nginx web server. All the certs are renewed automatically every 60 days.

After obtaining and installing certs to your preferred location, you can log out from root user to a regular sudo user and continue to manage your server by using sudo if required.

exit

Configure Nginx web server

Run sudo vim /etc/nginx/sites-available/example.com.conf and populate the file with the following content. Substitute all occurrences of example.com with your own domain name.

server {

  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  server_name example.com *.example.com;
  root /var/www/example.com;

  # RSA
  ssl_certificate /etc/letsencrypt/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/example.com/private.key;
  # ECDSA
  ssl_certificate /etc/letsencrypt/example.com_ecc/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/example.com_ecc/private.key;

}

Activate the new example.com.conf configuration by linking the file to the sites-enabled directory.

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

Test Nginx configuration.

sudo nginx -t

Reload Nginx.

sudo systemctl reload nginx.service

That's it. We deployed wildcard certs to Nginx, using acme.sh, Lexicon, and Vultr API. Wildcard certs can be useful when you want to secure multiple first level subdomains generated dynamically.

Want to contribute ?

You could earn up to $300 by adding new articles