It's not uncommon for modern computer users to run a home server, or for hobbyists or enthusiasts to purchase an affordable VPS and run apps for a Personal Cloud. With great apps like the Ampache media server, and platforms like Own Cloud, this is easier than ever, and an ever more attractive an option. If this is you, or if you run a blog, a small bushiness or non-profit website where you collect sensitive information, you might want to consider encrypting and securing that traffic from prying eyes, especially if any personal or sensitive data is within it.
The way to do this is through the use of globally trusted and signed certificates, commonly referred to as SSL. You know when a site is using this technology if the beginning of the URL starts with a nice, green "https" instead of just "http". These trusted certificates are often very expensive, and the most of us have limited funds to address this costly and critical issue. This is where Let's Encrypt comes into the picture. Their mission is to provide quality, free certificates to anybody that wants them. They envision a web that is 100% encrypted, and appear to be well on their way.
It's worth noting that there are plenty of tools that enable you to create your own certificates, such as Open SSL. With Open SSL, you can create your own Certificate Authority, or CA, and use it to sign certificates which are then used to encrypt the traffic. The trick is to get the CA trusted by the whole of the interment, and Let's Encrypt are a trusted Certificate Authority, and will freely issue signed SSL certificates. So, we will just ask them to do that for us using an easy to install and configure program developed by the EFF called Certbot which does all of the complicated technical work for us.
Let's Get to work
Before we jump into it ...
A few things that this walkthrough assumes
- You are installing on a recent Ubuntu LTS distrobution of Linux
- Your webserver is apache
- You have an SSH server installed on your VPS (or home server if you are using a differnt computer to access it)
Installing Certbot (formerly letsencrypt)
If you are running Ubuntu LTS 14.04:
Certbot is not packaged for 14.04, so you will have to fetch it from git, which is easy.
After you are logged on locally, or via an open SSH session, execute the following commands to
Install git, the program that will obtain and manage your Certbot source.
Obtain the Certbot source code from Github.
Change to the Certbot folder, and fetch its dependencies, essentially installing the program.
$ sudo apt-get install git
$ sudo git clone https://github.com/certbot/certbot /opt/certbot
$ cd /opt/certbot
$ sudo ./certbot-auto --help
If you are running Ubuntu LTS 16.04:
Good news! Certbot is packaged for your system, and so you can use the previous method, or just execute the following command:
$ sudo apt-get install letsencrypt
According to the Certbot website, there are even more options to install. This way provides the most control and flexability, in my opinion, an will certainly get you started. From here on out, this walkthrough will assume you installed through git, if you installed installed via apt-get then just substitute
to execute Certbot commands when this walkthrough uses
Preparing Apache to fetch the certificates
The "Alias" folder...
You're going to want to install a special alias folder under apache to act as a global "catch-all" folder that Let's Encrypt and Certbot uses to authenticate your requests. This will save a lot of hassel later on, especially if you have multiple URLs, want to include sub-domains, are running a CMS like Drupal, and so on. It's a quick and painless process, so let's get it out of the way. Simply execute the following command to create the folder we are going to use.
$ sudo mkdir /var/www/LEwebroot/.well-known
Then open your favorite text editor and save the following contents into a file called ".htaccess" located in the ".well-known" folder that you just created.
Fix the folder/file permissions
$ sudo chown www-data:www-data /var/www/LEwebroot/.well-known
Save the floowing contents into a file at "/etc/apache2/conf-enabled/letsencrypt.conf" to enable to folder.
Alias /.well-known /var/www/LEwebroot/.well-known
Require all granted
Now enable the rewrite module and restart apache
$ sudo a2enmod rewrite
$ sudo service apache2 restart
Let's say you have the url example.com, and put the subdomains 1.example.com and 2.example.com as Virtual Hosts in apache. Each of those three domains will now have the location /.well-known as a valid location.
Fetching the Certificates
To obtain certificates for our three example domains, simply execute the following command
$ sudo /opt/certbot/certbot-auto certonly --webroot -w /var/www/LEwebroot -d example.com -d 1.exambple.com -d 2.example.com
Just make sure that for every domain or subdomain that you want to add, just use the -d flag and you're good to go, since we have that nice catch all alias. If everything is correct, then Certbot will give you a message that tells you exactly where your new certificates are located. Note this location.
Configuring apache to use the certificates
Tell each virtual machine in apache to use the new certificates.
the default Virtual Machine file is located at /etc/apache2/sites-available/000-default, set it up with the SSL section from line 3 to line 19 of the following example
Other than the obviose lines that need adjusting, be sure to adjust line 1, replacing 0.0.0.0 with your actual IP address, and lines 16, 17, and 18 to reflect the location you noted from Certbot above. When that is done, restart apache with
$ sudo service apache2 restart
And go to https:example.com to see success.
Forcing SSL redirects
There are many ways to force your visitors to use SSL, one easy way is to simply add a dedicated "redirect" virtual machine with the following lines at the top of your 000-default file and restartign apache.
Redirect permanent / https://example.com
Enabling OCSP stapling for added visitor security
We want our visitors' privacy to remain in tact. One way to do this is to add in OCSP stapling, you can read more on that here, but for now, let's just enable it by adding the follwoing lines to the bottom of the file "/etc/apache2/mods-available/ssl.conf" and restarting apache.
# OCSP Stapling settings
Setting up auto-renewal of certificates
Let's Encrypt certificates are only good for 90 days, so automating the rewal process is critical.
While the distribution package has it's own, slightly simpler mechanism for renewing, I prefer this way, as it provides more fine tuned control.
Add something like the following contents to a file located at either /etc/letsencrypt/cli.ini or /etc/certbot/cli.ini (you will probably have to create this file)
## This is an example of the kind of things you can do in a configuration file.
## All flags used by the client can be configured here. Run "Let's Encrypt" with
## "--help" to learn more about the available options.
## Use a 4096 bit RSA key instead of 2048
rsa-key-size = 4096
## Uncomment and update to register with the specified e-mail address
## email = firstname.lastname@example.org
## Uncomment to use a text interface instead of ncurses
## text = True
agree-tos = True
renew-by-default = True
authenticator = webroot
Create the update script
Create a file called update-cert.sh in your server user's home directory with the following contents, changing the locations and domains to suit your needs. As your domain requirements change, just update this script.
# Renew Let's Encrypt SSL cert
# Chenge the following lines to suit your needs
./certbot-auto certonly -c /etc/letsencrypt/cli.ini -w /var/www/LEwebroot -d example.com -d 1.example.com -d 2.example.com
echo -e "The Lets Encrypt Cert has not been renewed! \n \n" $ERRORLOG | mail -s "Lets Encrypt Cert Alert -" email@example.com
service apache2 reload
echo -e "Success! The Lets Encrypt Cert has been renewed!" | mail -s "Lets Encrypt Cert Alert +" firstname.lastname@example.org
One bonus of this method is that this script will email you with the result of the execution of this script. Make sure the script is allowed to be executed after saving.
Configure a time-based task to execute the renewals
Simply enter the following into a terminal
$ sudo crontab -e
And enter in the following line (adjusting for your path)
0 0 1 */2 * /home/your_user_name_here/update-cert.sh
This will update every two months, for good measure, and email you the result.
Congrats! You now have free, trusted SSL encrypted, secure websites with certificates that will auto-renew every two months and keep you updated with their status. You have forced your traffic to use encrypted only connections, and have set up a further step towards client protection with OCSP stapling. Don't forget to keep an eye on the Let's Encrypt forums and Certbot documentation for any new updates or problem solving.
One last note, when you want to add in a new virtual machine, make sure you run a new request for every single domain in addition to the new one, and not just a new request for only the new domain. This keeps things tidy.
Stay tuned for some client side SSL tricks, soon to come.
Thanks for reading!