Victor is a full stack software engineer who loves travelling and building things. Most recently
created Ewolo, a cross-platform workout logger.
This is a follow-on post from a previous entry where we setup multiple Node.js websites on a single machine with the help of Nginx. In this article we will add https to one of our domains thanks using free SSL certificates provided by Let's encrypt.
It is required to run the setup on the machine that we will be hosting the domain for which we will be requesting a certificate. Let's encrypt comes with tools that work best on a linux system and even have capabilities to auto-configure popular web servers like Apache and Nginx. We will ony be using it as a standalone application to get the SSL certificates :)
On a ubuntu system run the following:
sudo apt-get install software-properties-common sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install certbot
Run the following command and make sure to replace smalldata.tech with your domain name. Note that in our case, we have two domains that point to the same setup and therefore we have requested a combined certificate for both of them.
sudo certbot certonly --standalone --agree-tos -m admin@smalldata.tech -d smalldata.tech -d www.smalldata.tech -d smalldata.website -d www.smalldata.website
Your certificate should now be available at /etc/letsencrypt/live/smalldata.tech
.
sudo dd if=/dev/zero of=/swapfile bs=1024 count=524288 sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile
Command "/home/xxx/.local/share/letsencrypt/bin/python2.7 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-R5zGBV/cryptography/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-cf8qxj-record/install-record.txt --single-version-externally-managed --compile --install-headers /home/xxx/.local/share/letsencrypt/include/site/python2.7/cryptography" failed with error code 1 in /tmp/pip-build-R5zGBV/cryptography/You can also add the following line to
/etc/fstab
to have your swap enabled even after a reboot:
/swapfile1 none swap sw 0 0
If you followed the steps from the previous tutorial then you probably have a nginx server configuration for your domain : /etc/nginx/sites-available/smalldata.tech
. You will need to modify it as follows to use the ssl certificate:
server { listen 80 default_server; server_name smalldata.tech www.smalldata.tech smalldata.website www.smalldata.website; # redirect all urls to https return 301 https://$server_name$request_uri; } server { listen 443 ssl; server_name smalldata.tech www.smalldata.tech smalldata.website www.smalldata.website; # add Strict-Transport-Security to prevent man in the middle attacks add_header Strict-Transport-Security "max-age=31536000"; # ssl certificate config ssl_certificate /etc/letsencrypt/live/smalldata.tech/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/smalldata.tech/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/smalldata.tech/chain.pem; access_log /var/log/nginx/smalldata.tech.log; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_pass http://127.0.0.1:your-port; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
your-port
with the actual port number. Also, needless to say you will need to change the domain names as per your requirementssudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048Nginx can then be configured with the following (note the SSL security guidelines as mentioned above):
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_dhparam /etc/ssl/certs/dhparam.pem; ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security max-age=15768000;
Make sure to restart nginx for your changes to take effect.
sudo service nginx restart
SSL labs provides a free SSL audit which you can use to see that everything is working properly.
To be able to renew the certificates automatically we need to be able to let the authentication take place while Nginx is running. We can use the webroot
plugin which basically sets up a secret file under the root folder of the website that is being served via nginx to verify the domain name:
sudo certbot certonly --webroot --agree-tos --webroot-path=/home/ubuntu/server/public/ -d smalldata.tech -d www.smalldata.tech -d smalldata.website -d www.smalldata.website
Add the --force-renewal
option to force certificate renewal.
Once certificates have been renewed, the settings are saved in the renewal folder. For e.g. /etc/letsencrypt/renewal/smalldata.tech-0001.conf
:
# renew_before_expiry = 30 days cert = /etc/letsencrypt/live/smalldata.tech-0001/cert.pem privkey = /etc/letsencrypt/live/smalldata.tech-0001/privkey.pem chain = /etc/letsencrypt/live/smalldata.tech-0001/chain.pem fullchain = /etc/letsencrypt/live/smalldata.tech-0001/fullchain.pem version = 0.14.2 archive_dir = /etc/letsencrypt/archive/smalldata.tech-0001 # Options and defaults used in the renewal process [renewalparams] installer = None authenticator = webroot account = xxx [[webroot_map]] www.smalldata.tech = /home/ubuntu/server/public smalldata.tech = /home/ubuntu/server/public
This allows simply running the following to renew certificates:
sudo certbot renew
Add the --dry-run
option to see that everything is working before actually going ahead with the renewal.
We can now setup a simple cron job to perform the renwal:
sudo crontab -e 30 2 * * 1 certbot renew --renew-hook "/usr/sbin/service nginx reload"
/var/log/letsencrypt/letsencrypt.log
HackerNews submission / discussion
Back to the article list.
Subscribe to get articles as they are published direct to your inbox!