Migrating Your Website to SSL for Free

Created by josh
February 03, 2017 3:03:17 PM PST

Use LetsEncrypt.org - stop paying for certificate authorities but also avoid those clunky free solutions....

About a month ago, I moved my site (and a couple other sites I host on my server) to be served over SSL. Setting up SSL is usually a hassle because there are so many components between the server hosting the secured site and the user's device/browser.

Part of the hassle is dealing with a certificate authority, who serves as the "validation" party for your secure connection. Anyone can say they are Microsoft.com and your information is secure - but a third party certificate authority will be the one to validate this fact.


To begin migrating your website to SSL, be sure OpenSSL is installed and configured with your web server (i.e. Apache configured with mod_ssl). Your httpd.conf file will look like:

LoadModule ssl_module /usr/local/apache2/modules/mod_ssl.so

SSLEngine on
SSLCertificateFile /usr/local/apache2/ssl/jlrweb.crt
SSLCertificateKeyFile /usr/local/apache2/ssl/jlrweb.key


Also, you'll need the proper certificates and key files on your server, as provided by your certificate authority (CA). 


That does not mean you need to purchase a certificate from a Certificate Authority! And for the sake of humanity, do NOT go through free SSL cert providers like StartSSL. I guarantee your experience will be grim at best. It's 2017 - sites like LetsEncrypt.org and SSLForFree.com (which is essentially Lets Encrypt) are non-profit Certificate Authorities that are shaking up the world of commercialized security validation. The best part is, they make it easy too.


I like to keep my certificates and keys in an easy-to-find folder (for both Apache and me), and we'll get into what those are soon. In the mean time, create a folder on your server somewhere that makes sense to you such as /usr/local/apache2/ssl, and make sure that your Apache user exclusively has full permissions.



# sudo mkdir /usr/local/apache2/ssl && chown your_apache_user:your_apache_user -R /usr/local/apache2/ssl && chmod -R 700 /usr/local/apache2/ssl


If you visit LetsEncrypt.org's official "Getting Started" documentation (https://letsencrypt.org/getting-started/), the steps are pretty straight forward. They use Certbot, which these instructions link to and direct you to install and download.

Install Certbot (this is an example command for my installation of Apache 2.4 on Debian 8):

# sudo apt-get install python-certbot-apache -t jessie-backports


Follow the steps of the wizard (here are a couple screenshots of me running through the example site (jlrweb.us):

After Certbot finishes verifying your rig, it generates a few files in /etc/letsencrypt/. Well it definitely does in that directory if you're using Debian =). There are two files I copied into that SSL directory (referred to earlier in the tutorial) that I point to in my Apache config.


Since I use this directory for other sites on my server, I keep the basename of the ".crt" and ".key" file consistent with the hostname. You can either maintain a symlink to the generated crt/key files, or do this the hard way like I do:

# cp /etc/letsencrypt/live/jlrweb.us/fullchain.pem /usr/local/apache2/ssl/jlrweb.crt
# cp /etc/letsencrypt/live/jlrweb.us/privkey.pem /usr/local/apache2/ssl/jlrweb.key


For the final touch, I added this little check in one of my PHP boostrap files. This forces users who go to the non-secure (http) version of the site to redirect to the SSL secured (https) version. This is optional. I recommend at least forcing this on pages that require users to submit data (login pages, contact forms, etc). There are ways you can set up Apache to do this too, but I prefer to make this happen in PHP.

define('WEB_URL', 'https://my-domain');

if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on')) {

    header('HTTP/1.1 301 Moved Permanently');
    header('Location: ' . WEB_URL . $_SERVER['REQUEST_URI']);



Renew your certificates and keys automatically every month

You can skip the interactive steps above by creating a script and adding it to a monthly cron job:

# certbot certonly --renew-by-default --webroot -w "/usr/local/apache2/htdocs/jlrweb-webroot/" -d jlrweb.us,www.jlrweb.us

# cp /etc/letsencrypt/live/jlrweb.us/fullchain.pem /usr/local/apache2/ssl/jlrweb.crt
# cp /etc/letsencrypt/live/jlrweb.us/privkey.pem /usr/local/apache2/ssl/jlrweb.key

Save this file as /usr/local/bin/renew-certs.sh with executable permissions and add this to your crontab:

0 0 1 * * /usr/local/bin/renew-certs.sh