Setup and Install SSL, Gratis

UPDATE as of 4/15/16:

I had to renew my certificate and noticed a few things had changed for me. Firstly, the generated files seem different, so cert.pem goes in CRT, privkey.pem goes in key. Finally, I was unable to update with only that information so I had to use chain.pem in my CABUNDLE.


Secure Socket Layer (SSL), which enables the HTTPS protocol is becoming more the norm these days, even for sites that won’t be dealing with your personal information. Banks, Paypal, Facebook and other businesses that deal with sensitive information have been using SSL for years. Privacy should be the default online and it’s never been easier to get your site rolling with SSL, for free, using Let’s Encrypt.

This will work for any website, but my specific setup is a WordPress site on shared hosting. I’m also running OS X so some instructions may differ for you if you’re on Windows. All you need to get this up and running is access to your web server’s Control Panel (ideally SSH, but that isn’t necessary) with access to upload SSL certificates and comfort in using the command-line.

Installing Let’s Encrypt Locally

The easiest way I’ve found to handle generating the certificate is to run the entire process locally while SSH’ing into the web server to place the generated authentication files, and finally, upload the completed certificate via the Control Panel. To start, you need to get to the command-line and install Let’s Encrypt. Boot up Terminal or your favorite command-line interface and run, in the directory of your choosing:

					git clone

This will pull down the Let’s Encrypt bootstrapping scripts to get started. Next, cd into that directory and begin the certificate generation process:

					./letsencrypt-auto certonly -a manual --rsa-key-size 4096 -d -d

The official instructions on the Let’s Encrypt website have alternatives but I’m generating locally and will move the certificate, key, and keychain, it’s best to use the manual option.

I ran to a bit of trouble with the Python setup in that last step due to some weirdness with Homebrew and permissions. I wound up needing to chown my /usr/local and /Library/Caches/Homebrew directories, linking Python, and finally installing pip and virtualenv outside of Homebrew. If that doesn’t make any sense then your system may have dealt with the install with more grace than mine. The bootstrapper for Let’s Encrypt is still in beta and this is likely the culprit for some of the issues I faced. If you find you’re self facing these same issues, try the following.

Issue: Warning: python-x.x.xx already installed, it’s just not linked

					sudo chown -R "$USER":admin /usr/local
sudo chown -R "$USER":admin /Library/Caches/Homebrew
brew link python

Issue: pip Not Installed

					sudo easy_install pip

Issue: virtualenv Not Installed or an Exception w/ Traceback and an error IOError: [Errno 13] Permission denied: ‘/Library/Python/x.x/site-packages/’

					sudo pip install virtualenv

Once these issues are resolved, you can once again run the ./letsencrypt-auto command above and you should get through.


All we have left to do is input an email address, agree to the terms & conditions and finally create either one or two authentication files on the live web server if you’re using both www and a non-www address for your site, which is recommended. Following the instructions presented in your terminal is the way to go here, but for more clarity, Let’s Encrypt needs to check you are who you say you are and so, you’ll need to prove it. The only way to do this is to have you create the directory .well-known/acme-challenge with a random string file name and random string of data in it. This file must be accessible via your browser or this will fail. Before hitting ‘Enter’ on the terminal window after creating this file, visit the URL to make sure it loads and you don’t get a 404 error or another issue. If you do, and press enter on the Let’s Encrypt you’ll need to run the first command again and start over.

If you have www, you’ll be asked to create another file after creating the first one.

Once you hit enter, it could take a few seconds to a minute and you’ll eventually see either an error notice/screen telling you it was inaccessible and therefore invalid, or a success screen:

SSL Cert Success

Final Steps

Go visit /etc/letsencrypt/live/<>/ (or /private/etc/letsencrypt/archive/<> as it’s a symlink) and get your info. If you can’t access the directory, just chmod it. You can erase it afterward when you’re done uploading the data to your web server. Run this in the archive directory:

					sudo chmod -R 755 *

After getting into the directory named after your domain, you should see four files: cert1.pem, chain1.pem, fullchain1.pem, and privkey1.pem. You’ll want to copy the contents of cert1.pem to CA or CABUNDLE, and privkey1.pem to KEY. Depending on your hosting setup, this may be all you need to do, making sure to assign it to the correct domain.

If you are running a WordPress site, you’ll want to also make sure you’ve updated your WordPress URL and Site Address in Settings > General to use https instead of http.

I also needed to head into the .htaccess file and add in a forced client-side SSL redirection, but only for my top-level domain. I have other sub-domains on my server that do not have SSL certificates and this would break them if I were to target all URLs on my server. Here’s what those blocks looked like in my .htaccess file:

# ----------------------------------------------------------------------
# Prevent SSL cert warnings
# ----------------------------------------------------------------------

# Rewrite secure requests properly to prevent SSL cert warnings, e.g. prevent
# when your cert only allows

<IfModule mod_rewrite.c>
RewriteCond %{SERVER_PORT} !^443
RewriteCond %{HTTP_HOST} ^$
RewriteRule ^{REQUEST_URI} [R=301,L]

# ----------------------------------------------------------------------
# Force client-side SSL redirection
# ----------------------------------------------------------------------

# If a user types "" in her browser, the above rule will redirect her
# to the secure version of the site. That still leaves a window of opportunity
# (the initial HTTP connection) for an attacker to downgrade or redirect the
# request. The following header ensures that browser will **only** connect to
# your server via HTTPS, regardless of what users type in the address bar.
Header set Strict-Transport-Security max-age=16070400;

Once that’s done, you should be up and running!

Leave a Reply

Your email address will not be published. Required fields are marked *