I had some trouble installing Let’s Encrypt SSL certs for my GoDaddy’s VPS server that runs WHM / cPanel on CentOS 6 so I thought maybe I’d write this how-to for others who might be struggling. These instructions should work for any WHM / cPanel installation, but I only have GoDaddy to try. I’ve modified a script posted by cPMatthewV in order to install the certs for the various WHM services.
First, login to your domain via SSH. There’s how-to’s on how to do this so I won’t cover it here. Next, make sure you’re root, make sure your system is fully updated, install git and a few extra packages.
sudo su yum -y update yum install git wget curl
If some of these packages are already installed, it’s okay, yum will tell you. Create a directory in your home directory and then clone the repository for Let’s Encrypt.
mkdir src cd src git clone https://github.com/letsencrypt/letsencrypt
Let’s Encrypt needs a few packages that aren’t available in the default repository. I manually installed them but there’s other ways to get these packages. If you prefer using a different method, go for it. I needed the development tools, Python2.7, pip and virtualenv.
The easiest way I found to get the development tools was to run the following command:
yum groupinstall -y development
If you’re running an older version of CentOS and this command fails, you might have to try this one instead:
yum groupinstall -y 'development tools'
Now we download some additional useful tools…
yum install -y zlib-dev openssl-devel sqlite-devel bzip2-devel xz-libs
CentOS requires Python2.6 to run properly so we install a copy along side, so it doesn’t mess anything up. There’s a few ways to co-install Python 2.7 on CentOS. I did it by manually downloading and installing the various packages. However, Eva2000 tells me that you can also use yum to install a community repository that provides Python 2.7, 3.3 and 3.4, in case you ever need those. I think his way is better, so I’ve included that instead of showing how I did it manually. If you experience problems, please let me know, because I haven’t tried this way personally.
yum -y install python27 python27-devel python27-pip python27-setuptools python27-virtualenv --enablerepo=ius
This is especially useful because yum can be used to update Python whenever a new version comes out.
Now it’s time to work on getting those SSL certs. Currently, WHM / cPanel doesn’t play nice with the Let’s Encrypt auto installer. I believe cPanel is working on implementing something to fix this. So far, the only way I’ve found to successfully install the certs for the WHM / cPanel stuff is to shut down Apache. You might want to make sure you properly setup a hostname for your server as well. I generated an SSL cert for my hostname but I don’t think this is required. So, let’s shut it down and run the Let’s Encrypt program. We’ll grab some test certificates first, to make sure we did everything correctly.
/etc/init.d/httpd stop cd letsencrypt ./letsencrypt-auto certonly --test-cert --standalone --email email@example.com -d yourdomain.com -d www.yourdomain.com -d yourhostname.yourdomain.com -d cpanel.yourdomain.com -d whm.yourdomain.com -d webmail.yourdomain.com -d webdisk.yourdomain.com -d cpcalendars.yourdomain.com -d cpcontacts.yourdomain.com cd ..
Be sure to replace firstname.lastname@example.org with your e-mail, at your domain. And replace all the yourdomain.com’s with your real domain name. Replace yourhostname with your server’s hostname. It seems that if you use capitalized letters for your domain, Let’s Encrypt will error out, so make sure you enter your domain in all lower case. If you have any sub-domains, make sure you add them with the -d option.
Here’s an example of how mine looked (minus my e-mail address).
./letsencrypt-auto certonly --test-cert --standalone --email email@example.com -d jetbbs.com -d www.jetbbs.com -d franklin.jetbbs.com -d cpanel.jetbbs.com -d whm.jetbbs.com -d webmail.jetbbs.com -d webdisk.jetbbs.com -d cpcalendars.jetbbs.com -d cpcontacts.jetbbs.com
If everything went okay, letsencrypt-auto should bring up a page asking you if you accept the terms of agreement. Read it and accept if you want to continue. Cancel if you don’t. If you cancel, you will not be able to get the certs from Let’s Encrypt. Once you’re back at the shell prompt, it’s time to start Apache again.
Now, we’re not using the certs yet. We still have to install them. The easiest way I found to do this is to actually use a perl script. Because this site doesn’t like new lines that much and the source code looks like crap without them, I’ve decided to host the script on my site. Just download it simply using wget.
mkdir -p /root/src/ssl wget https://www.JetBBS.com/installssl.tar.xz tar -Jxvf ./installssl.tar.xz mv installssl.pl /root/src/ssl/ chown root:root /root/src/ssl/install.pl chmod 770 /root/src/ssl/installssl.pl
Now, open the file up with your favourite text editor and in the beginning section, you should see something that says
my $pass = 'myrootpassword';
Change that to your root password. This is needed because we’re using cPanel / WHM API calls and the script needs to essentially “login” to WHM. There is away to do this using keys if you don’t want your root password in a script. I don’t know how to do it though. The chmod command makes it so only root can view / write / execute the file.
Now, we just need to make sure we have all the perl modules installed. On my system, I was missing one. If the script errors out, let me know and I’ll try to help you find the module.
yum install perl-IO-Socket-SSL
Run the script now and be sure to pass the name of your domain to it. For my site, it’d be like this:
perl /root/src/ssl/installssl.pl jetbbs.com
If you did everything correctly, it should show a bunch of text on the screen. It should also show some messages about trying to install certs for various services. If you get an error instead of this, it’s more than likely due to a missing module. If everything was successfully, restart Apache and try going to your domain.
Try going to places like webmail.yourdomain.com, whm.yourdomain.com, yourdomain.com, etc. Make sure you’re putting in https in the address bar. If you were currently at any of these sites before you ran the script, exit the tab or close your browser and open it back up. You should now see a nice red X through the https sign. Double click that. Click on the button that says something like Get certificate information. If it shows that it’s signed by the Happy Hacker, you’ve succeeded! If not, you did something wrong…double check all your steps to make sure you followed them exactly. Let me know if you figure out what went wrong.
You can verify that the test certs successfully installed by going to whm.yourdomain.com, and looking under Service Configuration -> Manage Service SSL Certificates. The test certs should show up.
If they do, it’s now time to install the real ones. So, delete the old certs. I did this by deleting the whole /etc/letsencrypt directory.
rm -rf /etc/letsencrypt
Rerun letsencrypt-auto, but this time for real certs!
/etc/init.d/httpd stop cd letsencrypt ./letsencrypt-auto certonly --standalone --email firstname.lastname@example.org -d yourdomain.com -d www.yourdomain.com -d yourhostname.yourdomain.com -d cpanel.yourdomain.com -d whm.yourdomain.com -d webmail.yourdomain.com -d webdisk.yourdomain.com -d cpcalendars.yourdomain.com -d cpcontacts.yourdomain.com cd .. /etc/init.d/httpd start
Again, remember to replace your_email with your real e-mail address, yourdomain.com with your real domain name and yourhostname with your real hostname. Don’t forget any subdomains you might have! Be sure to add them with the -d option.
If everything went good, rerun the installssl.pl perl script.
perl /root/src/ssl/installssl.pl jetbbs.com
Be sure to replace jetbbs.com with your actual domain name.
Now we just need to setup our crontab file so the certs renew automatically. What I did was write a little script that gets executed daily. If anyone is interested in it, I can post it. It just e-mails me every day telling me if letsencrypt-auto ran successful or not. For simplicity reasons though, we’ll just create a basic one here.
On GoDaddy’s Virtual Private Servers (or CentOS’s), there’s directories in the /etc/ directory. We have stuff like /etc/cron.d, /etc/cron.daily, etc/cron.weekly, etc.
We’ll put our script in /etc/cron.daily. So, in your favourite text editor, open up /etc/cron.daily/renew_certs. On my system, I used nano:
nano -w /etc/cron.daily/renew_certs
But you can use whatever editor you like.
Add the following:
#!/bin/bash letsencrypt="/home/yourhomedir/src/letsencrypt/letsencrypt-auto certonly --standalone --keep-until-expiring --agree-tos --email email@example.com -d yourdomain.com -d www.yourdomain.com -d cpanel.yourdomain.com -d whm.yourdomain.com -d webmail.yourdomain.com -d webdisk.yourdomain.com -d cpcalendars.yourdomain.com -d cpcontacts.yourdomain.com -d yourhostname.yourdomain.com" installssl="/root/src/ssl/installssl.pl yourdomain.com" # # Stop Apache so we can update letsencrypt certs /etc/init.d/httpd stop # # Call the letsencrypt-auto program eval $letsencrypt # # And store the exit code in a variable return_code=$? # # Check the exit status of the letsencrypt-auto program if [ $return_code = "0" ]; then /etc/init.d/httpd start # Update WHM / cPanel to reflect the new certs. If they're already there, this script will just return normally. eval $installssl else # Send an e-mail saying something went wrong... mailx -s "ERROR: SSL Cert Status" firstname.lastname@example.org << MSG_BODY_HERE command line: $letsencrypt # ERROR: Return Status: ($return_code). # Please check the log file /var/log/letsencrypt/letsencrypt.log for details. MSG_BODY_HERE /etc/init.d/httpd start exit 1 fi # exit 0
I had to put #'s for newlines because this website removes my new line characters for some reason. So, remove the #'s that are on the lines all by themselves. If there’s text on that line, regardless of what it is, leave the #! Only remove it if it’s all by itself.
Be sure to replace the youremail@yourdomain with your real e-mail address for the domain that you registered. Be sure to replace all the yourdomain.com with your real domain name. And be sure to replace yourhostname.yourdomain.com with your hostname and domain name.
Don’t forget also to replace yourdomain.com on the installssl line with your real domain as well.
Make sure to replace email@example.com with your real e-mail address that’s someplace other than your domain. That way if something goes wrong, you’ll get the e-mail.
And be sure to add any sub-domains you might have.
Once you save the file (if you’re using nano, CTRL-X), then make it executable:
chmod 774 /etc/cron.daily/renew_certs
On my system, the script kept failing and it took me a while to realize why. I’m pretty sure I figured it out. In your favourite editor, open up the file that calls your renew_certs cron file. For me, this was /etc/cron.d/dailyjobs
nano -w /etc/cron.d/dailyjobs
In the beginning, you’ll see something that looks like this:
Put a # in front of that to comment it out. Then below that, type a new PATH variable. For me, it was:
You can find what your PATH statement is by running the following command at the shell:
My real path had some stuff for X but the directories were invalid because I don’t have X-Windows installed. So I just shortened it. You could just copy my PATH variable and replace my username (spork) in /home/spork/perl5/bin with your username.
This should do it for you. You should have real SSL certs for your domain and they should also be configured and setup for all your cPanel / WHM stuff.
If you found this helpful, please let me know. If you had trouble with it, please let me know. If you have ideas on how I can make it better, please let me know. If you felt that I wasted my time writing it, please let me know. Thanks!