IMPORTANT: acme.sh now supports deploying to cPanel, so my method is deprecated. Please use the official acme.sh method instead.
If you want to use Let’s Encrypt free certificates with some virtual shared hosting providers such as Namecheap, you could find that there is no official support.
While using the certificates is not a problem, as it is possible from the WebUI, having then renewed and automatically installed can be a different story.
In my case, one of the providers is Namecheap, an they decided not to integrate Let’s Encrypt support into cPanel because (they say) it requires a big amount of changes to their infrastructure.
I am happy enough with their service, given the features I get for the money I pay. So despite my first idea was to switch to another hosting, I decided to see if I could automate all the needed parts, to renew the certificate and uploaded it to cPanel.
And as a result cp-installssl was born.
The steps to install it and getting to work are not really that hard:
1. Get SSH access to your shared hosting.
Usually you just need to contact your tech support and request it. Then at cPanel you need to configure your SSH public key, and then access with your preferred client.
You can get cp-installssl working even without SSH access, but then you will need to preconfigure everything somewhere else, and then uploading using the highly insecure FTP protocol.
2. Get and configure acme.sh
acme.sh is a bash script able to use the ACME protocol to verify domain and subdomain ownership and create Let’s Encrypt certificates.
The main benefit is that it does not need any external dependencies and, at least for me, it works at Namecheap without doing anything special.
I suggest you create a git folder outside your public_html folder, to place the git repositories we are going to create, so…
cd ~
mkdir git
cd git
git clone https://github.com/Neilpang/acme.sh.git
cd acme.sh
Then you need to configure acme.sh (check acme.sh help and documents), so it can verify ownership for the domains or subdomains that you will include at your certificate(s).
Keep in mind that the way you create the certificates will be important later (it’s not the same if you want a single certificate for domain1.com and www.domain1.com or of you want separate certificates).
Also keep in mind that if you are following acme.sh installation instructions, –install parameter will create a crontab job that you need to remove:
0 0 * * * “/home/user/.acme.sh”/acme.sh –cron –home “/home/user/.acme.sh” > /dev/null
We will install later a new crontab job to call my script, that will call acme.sh to renew certificates when its needed.
Regarding the method using for validation, it is up to you. But this is my recomendation:
In the past I used DNS method, but keep in mind that you won’t be able to use it if any of the subdomains is a CNAME (see RFC1912 section 2.4 for reference). Besides: a TXT record needs to be renewed and if you want this automated it requires extra configuration for acme.sh (provided your DNS service is supported!).
Now I am using the WEBROOT method. If you are redirecting all HTTP traffic to HTTPS, you will need to change your .htaccess configuration file so the path /.well-known is NOT redirected to HTTPS.
In my case, this is achieved with the following configuration:
RewriteRule ^(.well-known)($|/) – [L]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.juliogonzalez.es/$1 [R,L]
And I issued the certificates as follows:
acme.sh –issue -w /home/uosieg/www/juliogonzalez.es/ -d juliogonzalez.es -d www.juliogonzalez.es
acme.sh –issue -w /home/uosieg/www/sidrarusa.org/ -d sidrarusa.org -d www.sidrarusa.org
3. Get and configure cp-installssl
Time to clone my scripts:
cd ~
cd git
git clone https://github.com/juliogonzalez/cp-installssl.git
cd cp-installssl
Configure cp-installssl by copying the file .cp-installssl.ini to your home:
cp .cp-installssl.ini ~/
Change the content of the file (it will contain the credentials to connect to cPanel)
edit ~/.cp-installssl
Open the crontab configuration:
crontab -e
And add a new line similar to the next one:
0 0 * * * ${HOME}/git/cp-installssl/wrapper/cp-installssl-wrapper -d ‘[@.,www.,www2.]domain1.com [@.,www.,www2.]domain2.com’ -a ~/.acme.sh/ -c ~/git/cp-installssl/ > /dev/null
Note that you will need to adjust the time, and the content of -d parameter, according to the domains and subdomains you have. You can also consider redirecting all the standard output to a file.
Have a look at cp-installssl-wrapper help for reference.
git/cp-installssl/wrapper/cp-installssl-wrapper -h
In my case, this is my crontab line:
0 0 * * * ${HOME}/git/cp-installssl/wrapper/cp-installssl-wrapper -d ‘[@.,www.]juliogonzalez.es [@.,www.]sidrarusa.org’ -a ~/.acme.sh/ -c ~/git/cp-installssl/ >> ${HOME}/ssl.log
As we saw during the previous step, acme.sh is configured to create two certificates:
- One for juliogonzalez.es and www.juliogonzalez.es
- One for sidrarusa.org and www.sidrarusa.org
Finally, run cp-installssl-wrapper similar to what we have at the crontab job but adding -f parameter to force certificate renewal, and without any redirection, so we can see the output. This is required to check that cp-installssl-wrapper is able to renew and install certificates.
In my case:
${HOME}/git/cp-installssl/wrapper/cp-installssl-wrapper -d ‘[@.,www.]juliogonzalez.es [@.,www.]sidrarusa.org’ -a ~/.acme.sh/ -c ~/git/cp-installssl/ -f
You will notice how cp-installsslwrapper will call acme.sh to renew the certificate, and then will install it.
5. Enjoy!
From this point my scripts will take care of trying to renew the SSL certificates with the schedule you configured at CRON.
Note that the certificates are only renewed when needed.
6. Extras
For the most tech-savvy, notice that there are two scripts at my git repository
- cp-installssl is a PHP script which takes care of installing SSL certificates to cPanel using its JSON API. It’s based on code by Rob Parham.
- cp-installssl-wrapper is a BASH script will take care of calling acme.sh to renew the certificates when needed, and if a renewal happened will install them using cp-installssl
Finally, please note that you don’t really need to manage certificate issues and renewals at the same machine where
Hi, thanks for your work with this, I’ve got acme.sh running and have successfully issued certs, but I’m having a couple problems so far with integrating it properly. Firstly in your readme file it says that a requirement is “cPanel installations supporting the JSON API v2” and I can’t find any info about what versions of cpanel do support that. (The only info I can find about my cpanel version is “cPanel Pro 1.0 (RC1)”).
My second problem is in the details needed for setting up cp-installssl.ini – being on shared hosting, I’m unsure what to enter regarding the “host” field. I can access cpanel via mydomain.com/cpanel is that what its looking for? Sorry for dumb questions and thanks for any help!
Hi,
About the JSON API v2, you should ask your hosting provider.
But Anyway you can try to login using your web browser and you will see an URL such as https://myserver:myport/cpsessXXXXXXXXXX/frontend/paper_lantern/index.html
so if you replace everything after cpsessXXXXXXXXXX with /json-api/cpanel (your URL will look like https://myserver:myport/cpsessXXXXXXXXXX/json-api/cpanel) you should get the following error if the JSON API v2 is available:
{"cpanelresult":{"apiversion":"2","error":"The “cpanel_jsonapi_module” parameter is required.","data":{"reason":"The “cpanel_jsonapi_module” parameter is required.","result":"0"},"type":"text"}}
Note that this output is already JSON, and apiversion is 2.
Regarding your second question, host is the hostname you use to access cpanel, but not from mydomain.com/cpanel (which most likely is a redirection as in my case).
Try to login and take note of the hostname.
In my example above, I see https://myserver:myport/cpsessXXXXXXXXXX/frontend/paper_lantern/index.html so host is ‘myserver’.
is there any video abt this cuz i didn’t understand anything 🙁
Hi Tonialde.
I am afraid there are no videos, but let me know what you did not understand exactly and I will try to help.
If you want to use this stuff you will need at least some basic knowledge about SSL, Let’s Encrypt, bash, cron, git and cPanel.
When you’re saying changing the content of cp-installssl.ini, what content are you speaking of? It’s empty and I have absolutely no idea what to add.
Hi Dylan,
I noticed that it’s a typo, and I already corrected it.
The correct name for the file you need to edit is ~/.cp-installssl.ini with a dot at the beginning of the filename (~/ represents your home directory).
Additionally, can the crontab command be added in the cpanel cron jobs section? I’m having some weird difficulty with putty and adding the command. Yeah I’m completely new to this but I like learning
Yes, you should be able to use cpanel cron jobs as well.
I added my jobs using the shell but I can see them at cpanel as well, so I guess it should work fine.
What is the ‘g’ for at the end of your example -d parameter?
It was a typo, and thanks to you it is corrected now 🙂
Thanks for your script, unfortunately I couldn’t get it to work, cpanel responded with “A critical error occurred while parsing the ASN.1 data: Cpanel::Encoding::BER: corrupt data? data appears truncated” to the “installssl” call.
I finally figured out that acme.sh actually supports deploying to cpanel. I simple call to
acme.sh –deploy -d –deploy-hook cpanel_uapi
does the trick. I used acme.sh –install before the issue and deploy, so the cron job should do the automatic renewal.
Hello Markus,
It is strange, maybe it is something related with the Cpanel version on your server, or the setup itself.
Anyway it is good to see that finally acme.sh added the support, so it means my script is not really needed it anymore.
I will give it a try at my server, and if it works fine, will create a new post and will mark this one and my git repository as deprecated.
Thanks for the heads up!
Good day. Please I don’t really understand this. Is this a tutorial for automatic renewal of certificate or its a tutorial of getting the certificate itself? Because I’m searching for one to get the certificate and also automate it.
Hi Bonty,
The tutorial covers both, but keep in mind it’s only useful when the certificate is installed at cpanel.
There are several ways of getting the certificate, but I suggest you use the webroot method and get the initial certificate as explained on step 2.
I’m having trouble getting the certificates to install. The wrapper seems to be issuing the certificates, but they aren’t getting installed.
The output I get looks like:
CONFIG_FILE => /home/user/.cp-installssl.ini
HOST:PORT => :
DOMAIN => mydomain.com
CERTIFICATE => /home/user/.acme.sh/mydomain.com/mydomain.com.cer
PRIVATE_KEY => /home/user/.acme.sh/mydomain.com/mydomain.com.key
CABUNDLE =>
I suspect that something is wrong with my config file because the ‘HOST:PORT’ part is blank, but I don’t get any kind of error message. I do have the ‘.cp-installssl.ini’ in my home folder. I’ve tried two different domains for host- my domain directly and ‘server114.web-hosting.com’ which seems to be the namecheap server, but I get the same results either way.
Any help would be much appreciated!
It seems to me that you don’t have host and port at the .cp-installssl.ini file.
If you call cp-installssl without parameters, it will show you the correct format:
Since I see you are using neamecheap, host should be your main domain (if you have more than one, there’s one considered as ‘main’), and port will be 2083
I figured out my problem. I think because my password has a lot of nonalpha characters, the config file wasn’t parsing correctly.
I put quotes around the key values (i.e. host=”mydomain.com” etc), and now it’s working!
Thank you
Glad to hear it worked.
I really never fully tested if that script was able to parse the config file as it should, as it’s just a small change of another script (as the header explains).
I guess that in your case an equal was part of the password, and that provoked the problem.
Since another user commented that acme.sh now supports uploading the certificates directly to cpanel, I was thinking about stopping the development of cp-installssl.
I will see when I have some time to test that feature of acme.sh. If it’s working, I will deprecate cp-installssl, otherwise I will fix your issue.
In any case, thanks a lot for the feedback!
As another user reported the same problem, I changed the examples and the doc to always use double quotes for the values, and tell people not using them to update their INI files: https://github.com/juliogonzalez/cp-installssl/pull/6
Hi, can you explain why the initial cronjob created by the acme.sh installation is not sufficient by itself?
In the documentation it says it will check and renew any installed certificates, so why should we add your script as well?
Also, at what point is the }well-known” directory created? Does it need to be created manually?
Thanx for your effort.
Hi Rob,
AFAIK the cronjob from acme.sh will install the SSL certificate, key and intermediate certificate by copying and then reloading Apache, Nginx or whatever webserver you are using.
But if you are a cpanel user, most probably you are using a shared hosting service, which means you can’t do that, and that’s the reason cp-installssl was created.
Some users already mentioned that acme.sh supports deploying to cpanel (see https://github.com/Neilpang/acme.sh/blob/master/deploy/cpanel_uapi.sh), but still did not try it. I hope I will find some time to have a look, and if it works I will deprecate my solution.
As for the .well-known directory, it’s created by acme.sh in order to validate (using webroot method). It does not need to be created manually. But if you are redirecting ALL traffic from http to https, as I am doing, you will need to add an exception as showed at the instructions, so .well-known is served with http.
Hey, I can confirm that the deploy method worked for me on a Name Cheap shared hosting!
Thanks.