« Some Thoughts on Demanding Passwords at Borders | Is it hard to install PGP on a Mac? » |
Getting a Let's Encrypt certificate without root on a cPanel domain
system, hacks, open source, privacyI'm a big fan of my friends and colleagues at Let's Encrypt, an effort to make it easier to encrypt the web by offering web encryption certificates for free, for ever.
At first, free Let's Encrypt (LE) certificates were not so easy to obtain... you had to be essentially a coder and administer your own server to get it all to work. Not so, anymore! Now the number of ACME clients (the underlying protocol that Let's Encrypt uses) has exploded.
So, while I am only a bit of a coder, I wanted to see if it could be possible for someone with minimal system administration skills to actually get an LE cert and install it. The answer is yes, it is relatively easy to do!
My task: I wanted to see if a non-root (non-adminstrative) owner of a website using the cPanel hosting software could get an LE cert. To follow this, you need to be reasonably familiar with the command-line, but not much else.
You'll need to be able to login to the command line of your domain's server. Then, you'll want to make sure both openssl and python are installed (likely yes):
% which openssl /usr/bin/openssl % openssl version OpenSSL 1.0.1e-fips 11 Feb 2013 % which python /usr/bin/python % python --version Python 2.6.6
(Pay attention to that Python version as it throws a wrinkle into this later.)
We'll be using the acme-tiny python script from Daniel Roesler. You can follow those instructions, but I'll repeat them here. You'll need a private account key to identify yourself with LE (this generates a 4096-bit RSA key pair,
account.key
, that contains both the private and public keys). You'll also want a keypair for your domain (domain.key
):openssl genrsa 4096 > account.key openssl genrsa 4096 > domain.key
Be very careful with these files as they contain the private keys to the kindgom! You can extract the public key from the key pair by:
openssl rsa -in account.key -pubout > account.pub
While you can generate the keys on another system (like your laptop), you'll need to copy them over to your server and then run the rest of these commands on that server.
You'll now need to create a certificate signing request (CSR) that asks LE to sign your public key.
#for a single domain openssl req -new -sha256 -key domain.key -subj "/CN=yoursite.com" > domain.csr #for multiple domains (use this one if you want both www.yoursite.com and yoursite.com) openssl req -new -sha256 \ -key domain.key \ -subj "/" \ -reqexts SAN \ -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com")) \ > domain.csr
(sorry, this gets cut off so copy and paste it into a text editor before doing anything with it.)
And note that the line that reads
cat /etc/ssl/openssl.cnf
is specific to Debian flavors of linux. You'll need to change to something like the following depending on the system you're running:#change "/etc/ssl/openssl.cnf" as needed: # Debian: /etc/ssl/openssl.cnf # RHEL and CentOS: /etc/pki/tls/openssl.cnf # Mac OSX: /System/Library/OpenSSL/openssl.cnf
Now, you need to make a directory that your user account on the server can write to in a very specific place that ACME/LE expects it to be:
mkdir -p /foo/www/.well-known/acme-challenge/
Where
/foo/www/
is the path on your server to your root web directory.Here's where the magic happens. You'll now want to use acme-tiny to send the CSR under your LE account key to the LE to do the challenge (prove that you're on the domain that you claim):
#run the script on your server python acme_tiny.py --account-key ./account.key \ --csr ./domain.csr \ --acme-dir /foo/www/.well-known/acme-challenge/ \ > ./signed.crt
This will result in a file called
signed.crt
that is the LE-signed certificate for your domain!Note: if you are running Python earlier than 2.7 you don't have the
argparse
module. In that case, you'll want to add the directory you're in to thePYTHONPATH
variable and then install argparse inside your account with:easy_install --install-dir=. argparse
If you are running the nginx webserver, you'll need to add an intermediate certificate to your cert before you install it... but it doesn't hurt to just add the intermediate anyway:
#NOTE: For nginx, you need to append the Let's Encrypt intermediate cert to your cert wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem cat signed.crt intermediate.pem > chained.pem
Cool! The file
chained.pem
is the certificate you'll want to install in cPanel.Now you have an LE cert and a private key and you'll want to add both of these in cPanel and then install the certificate itself. To do this, log in to cPanel and navigate to the "Security" section and click "SSL/TLS". Click on "Private Keys" and then in "Upload a New Private Key" select the
domain.key
file you generated above and submit it. Return to SSL/TLS Manager.Now, click on "Certificates" and in the "Upload a New Certificate" section, select the
chained.pem
file you created above and submit it. Return to SSL/TLS manager.Finally, click on "Install and Manage SSL for your site (HTTPS)" and click "browse certificates" and install the one you just submitted above.
You should be able to navigate to
https://yoursite.com
and click on the lock to verify that you are encrypted against an LE cert!