I’ve spent a while banging my head against this, so I thought I would share since I didn’t see any other place online that had everything I needed to know in one place.
I run a few other sites that require SSL for running credit card transactions or that form submissions be secure.
In the past, I’ve gone with paying for SSL certificates, but the new player in town, Let’s Encrypt, is free and automated, so once I have things set up, I don’t have to worry about renewing a certificate again and I can get it for free.
I’m running these sites on shared hosting plans that I have shell access to, so that will be a requirement for you if you want to play along too.
First, in order to get the easiest setup possible, I went with https://acme.sh/ for a client. Most importantly, it doesn’t require root access and you can download it to pretty much whatever shared hosting you are on. It’s quite easy to download into a directory on the server using git or downloading and unzipping a tarball. I don’t pipe scripts directly to the shell like they recommend. YMMV.
Second, like most hosting providers, I have cPanel access as well and there are some SSL certificates managed there for all of my websites. Acme.sh has a handy little interface to do all of the work for you of installing the certificate in the right place.
Once you’ve got those two things, the setup is pretty simple as long as you do a couple of checks first since acme.sh and Let’s Encrypt are pretty particular about how they want things set up. First, check your umask for your server. Mine was set a little more securely than usual and wasn’t allowing the web server to read the files generated by acme.sh.
$ umask 0077
If that’s the case for you, I recommend the standard Linux umask of 022, which gives read execute permissions to files for users and groups. That did the trick for me.
$ umask 022 0022
Now issue the certificate
$ acme.sh --issue -d example.com -w /home/username/public_html/example.com
One snag you may also run into is that you don’t have an .htaccess file for a new directory that gets set up. In our example above, you’ll get a new directory created under /home/username/public_html/example.com/.well-known/acme-challenge/ where you’ll see a bunch of files getting created, but you might be getting a message that you don’t have permissions to view these files. This is because the .htaccess file from WordPress is telling the server that this folder shouldn’t be accessed.
The solution is to add a new .htaccess file into this newly created folder and add in access rules that allow your server to serve these temporary validation files for Let’s Encrypt. You’ll need to modify the file path, but the .htaccess that gets created says to turn off the rewrite engine for this folder and allow any queries to succeed. This supersedes the .htaccess from the WordPress installation, so should work.
$ cat > /home/username/public_html/example.com/.well-known/acme-challenge/.htaccess <<'EOF' <IfModule mod_rewrite.c> RewriteEngine off </IfModule> Satisfy any EOF
If all of this works, you should get a success message from acme.sh and you’ll have a valid certificate!
Next, you’ll need to install that certificate. Fortunately, acme.sh has made this very easy recently. First, set your username so that you’ll be able to deploy to the right account.
$ export DEPLOY_cPanel_USER=username
Next, deploy using the cPanel API that most hosts have enabled.
$ acme.sh --deploy --deploy-hook cpanel_uapi --domain EXAMPLE.COM
There are some extra instructions on this page if you are doing multiple domains or other advanced things.
Finally, check that there’s a cron job set up so that your certs will automatically renew. If not, create that yourself through cPanel or using the shell.
$ crontab -l 56 0 * * * "/home/USERNAME/.acme.sh"/acme.sh --cron --home "/home/USERNAME/.acme.sh" > /dev/null
That’s it. Once this is done, you’ll be able to repeat this for each domain and have things set up nicely.