Create SSL Certificates
by John Vincent
Posted on August 9, 2018
This is part of a series of discussions regarding Deploying to a Digital Ocean Droplet. For more details, please see Overview of johnvincent.io website
Create SSL Certificates
Get SSL cert for:
johnvincent.io
andwww.johnvincent.io
music.johnvincent.io
andwww.music.johnvincent.io
mygithub.johnvincent.io
andwww.mygithub.johnvincent.io
rijksmuseum.johnvincent.io
andwww.rijksmuseum.johnvincent.io
internet-resources.johnvincent.io
andwww.internet-resources.johnvincent.io
peg-solitaire.johnvincent.io
andwww.peg-solitaire.johnvincent.io
omnifood.johnvincent.io
andwww.omnifood.johnvincent.io
images.johnvincent.io
andwww.images.johnvincent.io
jekyll.johnvincent.io
andwww.jekyll.johnvincent.io
linkedin.johnvincent.io
andwww.linkedin.johnvincent.io
test.johnvincent.io
andwww.test.johnvincent.io
Certificates are build by document root. As each domain has it’s own document root, there will be 5 sets of certificates.
Ensure all are forwarding to the correct ip.
Install letsencrypt
sudo apt-get update
sudo apt-get install letsencrypt
Obtain an SSL Certificate
We'll show you how to use the Webroot plugin to obtain an SSL certificate.
How Webroot Plugin Works
The Webroot plugin works by placing a special file in the /.well-known
directory within your document root, which can be opened (through your web server) by the Let's Encrypt service for validation. Depending on your configuration, you may need to explicitly allow access to the /.well-known
directory.
sudo vi /etc/nginx/sites-available/default
Note root directive, this is webroot-path
root /var/www/html;
After location block, add:
location ~ /.well-known {
allow all;
}
Check your configuration for syntax errors:
sudo nginx -t
If no errors are found, restart Nginx with this command:
sudo systemctl restart nginx
Now that we know our webroot-path, we can use the Webroot plugin to request an SSL certificate with these commands. Here, we are also specifying our domain names with the -d option. If you want a single cert to work with multiple domain names (e.g. example.com and www.example.com), be sure to include all of them. Also, make sure that you replace the highlighted parts with the appropriate webroot path and domain name(s):
email address:
Should see:
IMPORTANT NOTES:
- If you lose your account credentials, you can recover through
e-mails sent to jv@johnvincent.io.
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/johnvincent.io/fullchain.pem. Your
cert will expire on 2017-05-31. To obtain a new version of the
certificate in the future, simply run Let's Encrypt again.
- Your account credentials have been saved in your Let's Encrypt
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Let's
Encrypt so making regular backups of this folder is ideal.
Files are in:
/etc/letsencrypt/archive/johnvincent.io
Files are:
cert1.pem, chain1.pem, fullchain1.pem, privkey1.pem
However, Let's Encrypt creates symbolic links to the most recent certificate files in the /etc/letsencrypt/live/your_domain_name directory. Because the links will always point to the most recent certificate files, this is the path that you should use to refer to your certificate files.
see:
/etc/letsencrypt/live/johnvincent.io
Script file
Create script file ~/bin/encrypt-ssl
#!/bin/sh
#
# script to create or renew SSL certs
#
domain_encrypt() (
echo "****************************************************"
echo "**** Encrypt domain www.johnvincent.io";
echo "****************************************************"
sudo letsencrypt certonly -a \
webroot --webroot-path=/var/www/johnvincent.io/html \
-d johnvincent.io \
-d www.johnvincent.io;
)
#
subdomain_encrypt() (
FILE="$1";
if [ -z "$FILE" ]; then
return;
fi;
echo "****************************************************"
echo "**** Encrypt subdomain $FILE";
echo "****************************************************"
sudo letsencrypt certonly -a \
webroot --webroot-path=/var/www/$FILE/html \
-d $FILE.johnvincent.io \
-d www.$FILE.johnvincent.io;
)
cd
#
echo "Create or renew SSL certificates"
#
domain_encrypt
#
subdomain_encrypt jekyll
subdomain_encrypt images
subdomain_encrypt music
subdomain_encrypt mygithub
subdomain_encrypt rijksmuseum
subdomain_encrypt internet-resources
subdomain_encrypt peg-solitaire
subdomain_encrypt omnifood
subdomain_encrypt linkedin
subdomain_encrypt test
echo "Restarting Nginx"
nginx-restart
#
echo "Completed"
Add SSL for Domain and Subdomains
encrypt-ssl`
Generate Strong Diffie-Hellman Group
To further increase security, you should also generate a strong Diffie-Hellman group. To generate a 2048-bit
group, use this command:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
This may take a few minutes but when it's done you will have a strong DH group at
/etc/ssl/certs/dhparam.pem
Configure TLS/SSL on Web Server (Nginx)
Now that you have an SSL certificate, you need to configure your Nginx web server to use it.
Create a Configuration Snippet Pointing to the SSL Key and Certificate
First, let's create a new Nginx configuration snippet in the /etc/nginx/snippets
directory. This is done for each domain and subdomain.
sudo vi /etc/nginx/snippets/ssl-johnvincent.io.conf
add:
ssl_certificate /etc/letsencrypt/live/johnvincent.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/johnvincent.io/privkey.pem;
sudo vi /etc/nginx/snippets/ssl-music-johnvincent.io.conf
add:
ssl_certificate /etc/letsencrypt/live/music.johnvincent.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/music.johnvincent.io/privkey.pem;
and repeat for all subdomains.
Create a Configuration Snippet with Strong Encryption Settings
The parameters we will set can be reused in future Nginx configurations, so we will give the file a generic name:
sudo vi /etc/nginx/snippets/ssl-params.conf
add:
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now. You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
Adjust the Nginx Configuration to Use SSL
Now that we have our snippets, we can adjust our Nginx configuration to enable SSL.
Adjust the Firewall
Check if SSL enabled:
sudo ufw status
To additionally let in HTTPS traffic, we can allow the "Nginx Full" profile and then delete the redundant "Nginx HTTP" profile allowance:
sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
sudo ufw status
Set Up SSL Certificates Auto Renewal
To trigger the renewal process for all installed domains, run this command:
cd
cd tmp (just in case)
sudo letsencrypt renew