Linux NGINX

enabling https on centos+nginx with letsencrypt and certbot

CertBot is an easy-to-use client that fetches certificate from Let's Encrypt, a free, automated, and open Certificate Authority service provided by the Internet Security Research Group (members include EFF, Mozilla, and others). Before I start, I would like to state the definitive guide for this is at the Official EFF Certbot site. So for more updated instructions and explanation, I recommend visiting their site. Spefically for CentOS, the link is https://certbot.eff.org/#centos6-nginx.

I use Let's Encrypt to enable HTTPS on my website. It's free and open and it helps EFF's cause to encrypt the whole internet. At any rate, let's get down to business. The following is applicable for both CentOS 6.x and CentOS 7. I recently setup both versions (one in Google Compute and another with RAMNode) and I followed the same instructions. But first, here's my stack.

OS : CentOS 6.9 or CentOS 7
WebServer : NGINX 1.x
Python : at least 2.6 but recommended 2.7 or higher

Now, before you proceed, make sure that you have a working virtual host entries in your nginx config. That should be in /etc/nginx/conf.d/*.conf
Download and install CertBot

cd /usr/bin
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto
ln -s /usr/bin/certbot-auto /usr/bin/certbot

Stop your webserver.

service nginx stop

Fire up the certbot

certbot
  --nginx \
  --agree-tos \
  --domains www.kwatog.com,kwatog.com \
  --email webmaster@kwatog.com \
  --manual \
  --manual-public-ip-logging-ok 

The command above will fire up nginx to authenticate your server. If everything is fine, certbot will add some items in your nginx configuration. Here's how it looks. Take note the *#managed by Certbot*. Those are the lines added by Certbot needed to enable SSL

   listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/kwatog.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/kwatog.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


    if ($scheme != "https") {  # managed by Certbot
        return 301 https://$host$request_uri; # managed by Certbot
    } # managed by Certbot

At this point, you're ready set to go. All you have to do now is to restart the webserver.

service nginx start

Bonus -- Auto Renewal

Certificates have expiry and it's something that can be easily forgotten. Of course, Let's Encrypt sends an email a month prior to expiry but that can only remind you. Luckily for us, certbot has a auto-renew feature which you just need to run via cron. Here's my cron entry.

6 2,18 * * * certbot renew --renew-hook "service nginx restart"

Basically, it runs twice a day (0206H and 1806H). If no expiring certificate, it won't do anything. Otherwise, it will connect to Let's Encrypt to obtain a new certificate. The --renew-hook parameter will execute an nginx restart after a successful renewal only. Here's a better explanation from Certbot site.

Note: if you're setting up a cron or systemd job, we recommend running it twice per day (it won't do anything until your certificates are due for renewal or revoked, but running it regularly would give your site a chance of staying online in case a Let's Encrypt-initiated revocation happened for some reason). Please select a random minute within the hour for your renewal tasks.