2016-07-22

Hi there. I just went through a week of trying to put our free Let's Encrypt certificate on our Bluehost account and I want to share my experience.

I learned that our particular Bluehost account server is running CentOS 6. Since we are paying for a dedicated IP we have SSH access, but not root (admin) privileges. Bluehost uses cPanel and cPanel are currently in experimental phase of providing Let's Encrypt SSL certificates. I found this link, but couldn't implement the steps, because it requires root (admin) privileges: https://forums.cpanel.net/threads/how-to-installing-ssl-from-lets-encrypt.513621/

Next, I found that https://letsencrypt.org/docs/client-options/ mentioned https://gethttpsforfree.com as a non-SSH way to generate a Let's Encrypt SSL certificate. I went through the steps and successfully generated a Let's Encrypt SSL certificate and later learned that it mimics the same steps as the command-line certbot tool. However, I made a grave mistake, which cost me several days to fix: I generated a 4096 byte private key: Bluehost seems to work only with 2048 byte private keys! All the websites I visited to learn about SSL certificates pointed out that they recommend a 2048 byte key, but I thought I might as well go for a key that is twice as much secure - and totally useless! When I called Bluehost tech support and told them I was ready to install my shiny Let's Encrypt SSL certificate generated with a 4096 byte private key, they told me: "Your private key doesn't match your certificate." What? How could that possibly happen? I believe I actually confused the account key with the private key. I later found on https://www.sslshopper.com/certificate-key-matcher.html that the MD5 hash from the private key, the Certificate Signing Request and the certificate itself has to match. Once you successfully generate an SSL certificate, you can run the following commands to check whether the components' MD5 hashes match. For example, when I run these commands this is what I get:

$ openssl x509 -noout -modulus -in cert.pem | openssl md5
(stdin)= 16f96a4606acd0ac4ff094497a61ea62

$ openssl x509 -noout -modulus -in fullchain.pem | openssl md5
(stdin)= 16f96a4606acd0ac4ff094497a61ea62

$ openssl rsa -noout -modulus -in privkey.pem | openssl md5
(stdin)= 16f96a4606acd0ac4ff094497a61ea62

$ openssl req -noout -modulus -in bluehost_csr.asc | openssl md5
(stdin)= 16f96a4606acd0ac4ff094497a61ea62

However, the 4096 byte account key and subsequent certificate I generated produced MD5 hashes which didn't match. The only option I had was to revoke that certificate generated with the 4096 byte private key, because I didn't have the private key, but only the account key. I used a computer with Ubuntu 16.04 LTS (Xenial) and installed certbot on it using the steps outlined on https://certbot.eff.org/#ubuntuxenial-other and I revoked the certificate using the following command:

$ sudo letsencrypt revoke -d mydomain.com -d www.mydomain.com --cert-path signed.cert --key-path account.key

Next, I was checking the status of my old certificate using https://certificate.revocationcheck.com - it took one day for my old certificate to become revoked. I had shot myself in the foot with the 4096 byte private key.

Great. So, how to do it right? Here are the steps that worked for me:

Use a Linux machine where you have root (admin) privileges and install certbot. In my case, I had an Ubuntu 16.04 LTS (Xenial) machine and ran the following commands:
$ sudo apt-get install letsencrypt

Generate a Let's Encrypt SSL certificate with the default 2048 byte private key. Since we are generating the certificate on one machine and will be using it on another, we cannot use the automatic web server (for example Apache) configuration that certbot offers; instead we will have to use the manual option, since we will manually configure our web server. Actually, the Bluehost tech support will configure the web server for us. Also, it's always a good idea to test whether you will successfully generate the certificate by doing a dry-run, like so:
$ sudo letsencrypt --dry-run --manual certonly

Next, certbot will ask you: "Please enter in your domain name(s) (comma and/or space separated)". Enter something similar to this: mydomain.com,www.mydomain.com and select OK using the down arrow button and press Enter.

Next, certbot will ask you: "NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you're running letsencrypt in manual mode on a machine that is not your server, please ensure you're okay with that. Are you OK with your IP being logged?" Select Yes and press Enter.

Next, certbot will say something similar to this: "Make sure your web server displays the following content at http://mydomain.com/.well-known/acme-challenge/mQrV3E4d5vIUrrmhs41ppa8drh66F409ZvE6QtAadJk"
mQrV3E4d5vIUrrmhs41ppa8drh66F409ZvE6QtAadJk.FblC_wtJqZv9yb8fLvTD4p8z1ilpeBUZ0E-ligwgsR8
Now you have to switch from your Linux machine to your Bluehost file system. Don't touch anything on your Linux machine; you must first generate the random web page requested by certbot before pressing Enter on the Linux machine. Use FTP or SSH to access your Bluehost account file system and go to the directory where the particular web site is hosted. In my case it was something like this: /home3/username/public_html/mydomain
Here you have to create the directory .well-known and please make sure it begins with a period, because that's very important. Go inside .well-known and here create the directory acme-challenge. Go inside acme-challenge and create a file with the filename as per certbot, in my case the filename was mQrV3E4d5vIUrrmhs41ppa8drh66F409ZvE6QtAadJk and next open the file and enter the one line as per certbot, which in my case was mQrV3E4d5vIUrrmhs41ppa8drh66F409ZvE6QtAadJk.FblC_wtJqZv9yb8fLvTD4p8z1ilpeBUZ0E-ligwgsR8
Now open up your browser and make sure you can go to the web page as per certbot, which in my case was http://mydomain.com/.well-known/acme-challenge/mQrV3E4d5vIUrrmhs41ppa8drh66F409ZvE6QtAadJk
If that worked, switch to your Linux machine where certbot is waiting for you to create the web page to prove ownership of the domain and hosting, before it generates a certificate for you. You are now ready to press Enter to continue. Note that certbot will ask you to generate a random web page for each domain you enter; since I entered mydomain.com and www.mydomain.com it asked me to generate two random web pages.
If certbot could access your newly created web page(s), it will say that the dry-run was successful and you can now successfully generate your Let's Encrypt SSL certificate by repeating steps 2-5 without using the --dry-run switch on the command line, like so:
$ sudo letsencrypt --manual certonly
Your new certificate will reside at the /etc/letsencrypt/live/mydomain.com directory on your Linux machine. You can also check whether the components' MD5 hashes match by using the commands at the beginning of my post.
Otherwise, if certbot couldn't access your newly created web page, it will report an error, and you have to repeat the process again from step 2.

Copy the files in /etc/letsencrypt/live/mydomain.com from your Linux machine to your Bluehost account via FTP or SSH - no root (admin) privileges needed, just remember the path where you copied these files, for example /home3/username/letsencrypt/live/mydomain.com. You should find the following files in /etc/letsencrypt/live/mydomain.com on your Linux machine: the generated private key privkey.pem, the certificate cert.pem and the CA bundle fullchain.pem.

Also, upload the private key privkey.pem, the certificate cert.pem and the CA bundle fullchain.pem to your Bluehost account's SSL/TLS Manager, and fill out the Certificate Signing Request using the uploaded Let's Encrypt private key. First, the private key privkey.pem should be uploaded on the "Private Keys (KEY)" section of your Bluehost account's SSL/TLS Manager web page; give it a meaningful name, such as "mydomain.com Let's Encrypt private key generated on my Linux machine". Second, go to the "Certificate Signing Requests (CSR)" section of your Bluehost account's SSL/TLS Manager web page and generate a new Certificate Signing Request using your Let's Encrypt private key you just uploaded, called "mydomain.com Let's Encrypt private key generated on my Linux machine". You only have to fill-in the required fields on the Certificate Signing Request, but it is strongly recommended to enter an important email address. Press Generate and go back to the main SSL/TLS Manager web page. Third, the certificate cert.pem and the CA bundle fullchain.pem should be uploaded on the "Certificates (CRT)" section of your Bluehost account's SSL/TLS Manager web page.

Call Bluehost tech support and tell them you have generated a 3rd party SSL certificate and uploaded it to both your account's file system at, let's say, /home3/username/letsencrypt/live/mydomain.com and uploaded it to your account's SSL/TLS Manager web page. They should be able to help you out.

Here's a much easier way:
Go to https://zerossl.com click on Online Tools and click Start on the "FREE SSL Certificate Wizard" section. Now there are three major steps:

Details: Enter your email in the Email field, enter the domain(s) in the Domains field (for example: mydomain.com,www.mydomain.com), check the "Accept ZeroSSL TOS" checkbox and the "Accept Let's Encrypt SA (pdf)" checkbox, leave the radio button on the default option "HTTP verification" and click Next. ​Copy the generated CSR locally, for example, call it csr.txt and click Next. Copy the account key locally, for example, call is accountkey.txt and click Next.

Verification: Create the directory path .well-known/acme-challenge/ on your Bluehost account as explained in step 5 in the above example, and create the file with filename as per the File field, and contents as per the Text field. You can click on the link in the File field to verify that you have successfully generated the random web page. Once you have verified that, click Next.

Certificate: Write down your account ID generated by zerossl.com as they provide a service to restore a lost account key. Download or copy your domain certificate, in this case a bundle of several certificates, by clicking the down arrow icon above the text in the top box; its filename is domain-crt.txt equivalent to the fullchain.pem generated by certbot. Download or copy your domain key, by clicking the down arrow icon above the text in the bottom box; its filename is domain-key.txt equivalent to the privkey.pem generated by certbot. Note down the instructions on the Certificate page, they are very useful.

I hope this helps.

Best regards,
Denis

Show more