February 21, 2017 tim 0Comment

Let’s Encrypt is a free, automated, and open certificate authority (CA), run for the public’s benefit. It is a service provided by the Internet Security Research Group (ISRG). More details can be found here https://letsencrypt.org/how-it-works/

This tutorial assumes you already have an existing website hosted with FreeBSD and an nginx reverse proxy. If you are using apache read this https://www.debarbora.com/Let’s-encrypt-SSL-Certificate-with-FreeBSD-&-Apache

We start by installing https://certbot.eff.org/

# pkg install -y py27-certbot

Request and download an SSL certificate by running the following command.

temporarily stop nginx

# service nginx stop
# certbot certonly

Select option 2) spin up a temporary webserver (standalone) and answer the remaining questions.

Our certificate have been downloaded to /usr/local/etc/letsencrypt/live/ourdomain.tld
or in my case /usr/local/etc/letsencrypt/live/www.debarbora.com

Next we will need to configure our nginx vhost

upstream website {
    server; #backend webserver and port

server {
    listen 80;
    server_name www.debarbora.com debarbora.com 
    return         301 https://$server_name$request_uri;

 server {

       listen         443 ssl;
       server_name    www.debarbora.com debarbora.com; 
	location ~phpmyadmin* {
	proxy_set_header X-Real-IP  $remote_addr;
	proxy_set_header X-Forwarded-For $remote_addr;
	proxy_set_header Host $host;
	proxy_pass http://owncloud;

      ssl_certificate /usr/local/etc/letsencrypt/live/www.debarbora.com/fullchain.pem;
      ssl_certificate_key /usr/local/etc/letsencrypt/live/www.debarbora.com/privkey.pem;
      ssl_session_cache  builtin:1000  shared:SSL:10m;
      ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
      # the list of ciphersuits should all fit on the same line
      ssl_prefer_server_ciphers on;
      ssl_dhparam /usr/local/etc/nginx/certs/dhparams.pem;
      #add more option if using cert from CA see SSL hardening https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-load-balancing-with-ssl-termination

    location / {

        proxy_pass http://website;
	proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_cache my_cache;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 3;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        proxy_cache_lock on;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

note: the above vhost is pretty generic but depending on the app or website you are hosting, some tweaking in both the vhost and web app may need to be done, such as so with wordpress see here for additional steps https://blog.virtualzone.de/2016/08/howto-https-ssl-wordpress-behind-proxy-nginx-haproxy-apache-lighttpd.html

start nginx

# service start nginx

Let’s Encrypt certificates last for 90 days before expiring, so we will need create a simple bash script that utilizes the certbot renew option. I like to keep all of my scripts in /root/scripts, create this directory if you don’t already have a location for your bash scripts.

# mkdir /root/scripts
# cd /root/scripts

lets create our bash script

# nano renew_lets_encrypt_certs.sh

/usr/local/bin/certbot renew 

save and exit

Make the script executable

# chmod +x renew_lets_encrypt_certs.sh

Test the script to make sure it runs

# sh renew_lets_encrypt_certs.sh
Saving debug log to /var/log/letsencrypt/letsencrypt.log

Processing /usr/local/etc/letsencrypt/renewal/www.ypcr.com.conf
Cert not yet due for renewal

The following certs are not due for renewal yet:
  /usr/local/etc/letsencrypt/live/www.ypcr.com/fullchain.pem (skipped)
No renewals were attempted.

Processing /usr/local/etc/letsencrypt/renewal/www.debarbora.com.conf
Cert not yet due for renewal

The following certs are not due for renewal yet:
  /usr/local/etc/letsencrypt/live/www.debarbora.com/fullchain.pem (skipped)
No renewals were attempted.

now we will setup a cron job to run daily

Set nano as the default editor for easy editing

# setenv EDITOR /usr/local/bin/nano

Now open crontab

# crontab -e

Add the following lines

@daily sh /root/scripts/./renew_lets_encrypt_certs.sh

Your site should now be accessible over https and any http requests made to your site should be redirected to https. If it’s working great! However it’s not enough for SSL to be configured for your site, it needs to be configured correctly, lets head over to https://www.ssllabs.com/ssltest/ and test our configuration.

You want at-least an A, an A plus is not always possible if your website visitors need to use older browsers. If you score a B or lower, ssllabs.com will provide easy to follow documentation so you can up the score.