Using Free SSL/TLS Certificates from Let’s Encrypt with NGINX

Let’s Encrypt is a new certificate authority (CA) offering free and automated SSL/TLS certificates. Certificates issued by Let’s Encrypt are trusted by most browsers in production today, including Internet Explorer on Windows Vista. Simply download and run the Let’s Encrypt client to generate a certificate (there are a few more steps than that, of course, though not many).

Before issuing a certificate, Let’s Encrypt validates ownership of your domain. First, the Let’s Encrypt client running on your host creates a temporary file (a token) with the required information in it. The Let’s Encrypt validation server makes an HTTP request to retrieve the file and validates the token, which serves to verify that the DNS record for your domain resolves to the server running the Let’s Encrypt client.

The Let’s Encrypt client does not yet officially support NGINX and NGINX Plus (support is in beta), but you can still get started right away using Let’s Encrypt with NGINX and NGINX Plus. (This blog applies to both NGINX and NGINX Plus, but for ease of reading we’ll refer only to NGINX Plus from now on.) All you need is the webroot plug‑in from Let’s Encrypt, and a few small changes to your NGINX Plus configuration.

This blog details the steps for configuring NGINX Plus, obtaining certificates, and setting up automatic renewal of the certificates.

Downloading the Let’s Encrypt Client

The first thing you need to do is download and install the Let’s Encrypt client, certbot. You can access the complete documentation at Let’s Encrypt, but in summary the commands are:

$ sudo apt-get update
$ sudo apt-get install -y git
$ sudo git clone /opt/letsencrypt

Note: All required dependencies are installed along with certbot, including Augeas, gcc, Python, and full CA certificates. Please verify that this complies with your security policy. The definitive list of installed dependencies is in the certbot source code.

Creating a Template for the Let’s Encrypt Temporary File

The Let’s Encrypt client creates a temporary file in webroot-path/.well-known/acme-challenge/ containing the token used by the Let’s Encrypt server to verify that you own the domain you are attempting to get a free ssl certificate for. The webroot‑path in our example is /var/www/letsencrypt.

We first create a template file with the values that Let’s Encrypt needs to issue a certificate, using this GitHub Gist. Without the template, we would have to specify the values on the Let’s Encrypt command line.

  1. Create the directory where Let’s Encrypt stores the temporary file, and set the required permissions:

    $ cd /var/www
    $ mkdir letsencrypt
    $ sudo chgrp www-data letsencrypt
  2. Create the file /etc/letsencrypt/configs/my-domain.conf, where my‑domain is your fully qualified domain name (for example, Copy in the Gist contents and set the appropriate values in the domains (again, the fully qualified domain name), rsa‑key‑size, server (full URL with scheme), and email fields.

    # the domain we want to get the cert for;
    # technically it's possible to have multiple of this lines, but it only worked
    # with one domain for me, another one only got one cert, so I would recommend
    # separate config files per domain.
    domains = my-domain

    # increase key size
    rsa-key-size = 2048 # Or 4096

    # the current closed beta (as of 2015-Nov-07) is using this server
    server =

    # this address will receive renewal reminders
    email = my-email

    # turn off the ncurses UI, we want this to be run as a cronjob
    text = True

    # authenticate by placing a file in the webroot (under .well-known/acme-challenge/)
    # and then letting LE fetch it
    authenticator = webroot
    webroot-path = /var/www/letsencrypt/

Allowing Let’s Encrypt to Access the Temporary File

Now we modify the NGINX Plus configuration to allow Let’s Encrypt to access the temporary file.

  1. Add this location block to the virtual server for HTTP traffic:

    server {
    listen 80 default_server;
    server_name my-domain;

    location /.well-known/acme-challenge {
    root /var/www/letsencrypt;


  2. Verify the configuration file is syntactically valid and restart NGINX:

    $ sudo nginx -t && sudo nginx -s reload

Requesting the Certificate

Now that everything is set up we request the certificate. The highlighted message confirms that we successfully obtained a certificate and associated files for NGINX, which Let’s Encrypt stores in /etc/letsencrypt/live/my-domain. The files of interest are fullchain.pem and privkey.pem.

$ cd /opt/letsencrypt
$ ./certbot-auto --config /etc/letsencrypt/configs/my-domain.conf certonly
Updating letsencrypt and virtual environment dependencies......
Requesting root privileges to run with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt --config /etc/letsencrypt/configs/my-domain.conf certonly

- Congratulations! Your certificate and chain have been saved at
Your cert
will expire on date. To obtain a new version of the
certificate in the future, simply run Let's Encrypt again.

Pointing NGINX Plus to the Certificate

  1. Add the certificate and key to the server block for HTTP traffic:

    server {
    listen 443 ssl default_server;
    server_name my-domain;

    ssl_certificate /etc/letsencrypt/live/my-domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/my-domain/privkey.pem;


  2. Verify the configuration file is syntactically valid and restart NGINX Plus to load the new certificates:

    $ sudo nginx -t && sudo nginx -s reload

Automating Renewal of Let’s Encrypt Certificates

Let’s Encrypt certificates are only valid for 90 days, after which they need to be renewed. Luckily this process can be easily automated using a cron job.

  1. Create a simple script like the following (obtained from this thread) to renew the certificate and restart NGINX Plus if successful. Save it as renew‑ in a directory that cron has permissions for.


    cd /opt/letsencrypt/
    ./certbot-auto --config /etc/letsencrypt/configs/my-domain.conf certonly

    if [ $? -ne 0 ]
    ERRORLOG=`tail /var/log/letsencrypt/letsencrypt.log`
    echo -e "The Let's Encrypt cert has not been renewed! \n \n" \
    nginx -s reload

    exit 0

  2. Create /var/log/letsencrypt/ if it doesn’t exist.

  3. Run crontab -e and enter this string to run the script every two months:

    0 0 1 JAN,MAR,MAY,JUL,SEP,NOV * /path/to/


There are several alternative ways to combine NGINX and NGINX Plus with Let’s Encrypt to automate free ssl certificate generation and renewal. The steps presented in this blog are just one way to go about it. We’re interested in your approach – tell us about it (or any other issues) in the comments section below.

NGINX is open source software that’s supported by NGINX Plus, our commercial&#8209grade application delivery platform. Learn about the advanced features in NGINX Plus and try it free for 30 days.

NGINX recognized by Gartner in 2016 Magic Quadrant for Application Delivery Controllers

Everything you need to know about choosing the right ADC