[How-To] Installing SSL from Let's Encrypt

Status
Not open for further replies.

devilslore

Registered
Apr 5, 2016
1
0
1
Swansea
cPanel Access Level
Root Administrator
Ok, I did this 4 days ago and it was working great, but now I seem to be getting a error

Code:
Oh no! Peep had a problem while trying to do stuff. Please write up a bug report
with the specifics so we can fix it:

https://github.com/erikrose/peep/issues/new

Here are some particulars you can copy and paste into the bug report:

---
peep: (3, 1, 1)
python: '2.7.11 (default, Dec  7 2015, 11:26:11) \n[GCC 4.4.7 20120313 (Red Hat 4.4.7-16)]'
pip: '1.4.1'
Command line:  ['/tmp/tmp.XyjEek9Vwb/peep.py', 'install', '-r', '/tmp/tmp.XyjEek9Vwb/letsencrypt-auto-requirements.txt']
Traceback (most recent call last):
  File "/tmp/tmp.XyjEek9Vwb/peep.py", line 967, in <module>
    exit(main())
  File "/tmp/tmp.XyjEek9Vwb/peep.py", line 939, in main
    return commands[argv[1]](argv[2:])
  File "/tmp/tmp.XyjEek9Vwb/peep.py", line 884, in peep_install
    req.install()
  File "/tmp/tmp.XyjEek9Vwb/peep.py", line 652, in install
    run_pip(['install'] + other_args + ['--no-deps', '-U', archive_path])
  File "/tmp/tmp.XyjEek9Vwb/peep.py", line 206, in run_pip
    status_code = pip.main(initial_args)
  File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/pip/__init__.py", line 148, in main
    return command.main(args[1:], options)
  File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/pip/basecommand.py", line 169, in main
    text = '\n'.join(complete_log)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 36: ordinal not in range(128)
Looking at the GitHub of letsencrpyt this is down to a problem with Peep as it is a old version and they have updated to use PipStrap but is not in the release yet, but is in the bleeding-edge version
 

aichkg

Registered
Apr 9, 2016
2
1
3
Hong Kong
cPanel Access Level
Root Administrator
There is a paid cpanel plugin for let's encrypt, has anyone used it yet? Any reviews?
No but I have installed this free one and it seems to work OK. letsencrypt for cPanel/WHM - Linux - e-diary

But the bash script/cron job solution from cPanel support is pretty good. I will go with that.

A GUI is nice but then I have to install a third party add-on with root privs thus place tremendous trust in that third party. Better wait for official GUI support with version 58 or later.
 
Last edited by a moderator:
  • Like
Reactions: symster

massafiri

Member
Apr 8, 2016
10
1
3
Melbourne
cPanel Access Level
Root Administrator
Hi Mark,

There should be no issue with installing this to the service SSL and I would actually recommend having a signed SSL there. Just make sure you renew this every 90 days. In the event you don't however cPanel should generate self-signed certificates for the servers hostname to avoid any problem with those services ssl certificates.
Hey Matt, sorry for replying to an old comment.
If I had a shared hosting environment but wish to provide SSL for SMTP across multiple domains (eg: mail.example1.com, mail.example2.com) - how can this be done with cPanel and Let's encrypt?

I've tried to spin up a SSL certificate for mail.example.com, but I receive an error because http://mail.example.com cannot find the .well-known public directory.
 

rinogo

Member
Dec 6, 2007
5
0
51
How can the method and `installssl.pl` script in the first post in this thread be adapted to work for the "main" cPanel/WHM domain? That is, if my cPanel login is at https://host.myhostname.com:2083, how can I use this method to generate and install the script for host.myhostname.com?

I was able to generate the key and chain by modifying the `letsencrypt` command to use `--webroot-path
/usr/local/apache/htdocs/`. This allowed Let's Encrypt to successfully authenticate our ownership of host.myhostname.com.

However, `installssl.pl` fails with this error:

[email protected] [5966 15:06:30 ~/letsencrypt]# ../installssl.pl host.myhostname.com
{"metadata":{"version":1,"reason":"The domain “host.myhostname.com” is not managed on this server. You must specify an IP address to install SSL for “host.myhostname.com” or set up this domain on a new account, or create it as parked domain, a subdomain, or an addon domain of an existing account, and try again.","output":{"raw":"The domain “host.myhostname.com” is not managed on this server. You must specify an IP address to install SSL for “host.myhostname.com” or set up this domain on a new account, or create it as parked domain, a subdomain, or an addon domain of an existing account, and try again."},"result":0,"command":"installssl"}}

I know I can manually install the cert, but I don't want to do so every 3 months (and possibly even more frequently as the Let's Encrypt project matures). How can I adapt `installssl.pl` or use some other method to automatically install this cert?
 

Deventer

Registered
Apr 19, 2016
1
0
1
Netherlands
cPanel Access Level
Root Administrator
Hi,

I'm having some troubles with the Python version. Check the error below:

Code:
[email protected] [~/letsencrypt]# ./letsencrypt-auto --verbose
Bootstrapping dependencies for RedHat-based OSes...
yum is /usr/bin/yum
Geladen plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* base: centos.mirror.transip.nl
* epel: ftp.nluug.nl
* extras: centos.mirror.transip.nl
* ius: mirror.amsiohosting.net
* updates: centos.mirror.transip.nl
Pakket python-2.7.5-34.el7.x86_64 is reeds geïnstalleerd en de meest recente versie
Pakket python-devel-2.7.5-34.el7.x86_64 is reeds geïnstalleerd en de meest recente versie
Pakket python-tools-2.7.5-34.el7.x86_64 is reeds geïnstalleerd en de meest recente versie
Oplossen van afhankelijkheden
--> Transactiecontrole uitvoeren
---> Pakket python-pip.noarch 0:7.1.0-1.el6 wordt geïnstalleerd
--> Verwerking afhankelijkheid: python(abi) = 2.6 voor pakket: python-pip-7.1.0-1.el6.noarch
---> Pakket python-virtualenv.noarch 0:1.10.1-2.el7 wordt geïnstalleerd
--> Klaar met oplossen afhankelijkheden
Fout: Pakket: python-pip-7.1.0-1.el6.noarch (epel)
           Vereist: python(abi) = 2.6
          Geïnstalleerd: python-2.7.5-34.el7.x86_64 (@TransIP)
              python(abi) = 2.7
              python(abi) = 2.7
          Beschikbaar: python27-2.7.11-1.ius.el6.x86_64 (ius)
              python(abi) = 2.7
          Beschikbaar: python32-3.2.6-1.ius.el6.x86_64 (ius)
              python(abi) = 3.2
          Beschikbaar: python33-3.3.6-2.ius.el6.x86_64 (ius)
              python(abi) = 3.3
          Beschikbaar: python34u-3.4.4-2.ius.el6.x86_64 (ius)
              python(abi) = 3.4
          Beschikbaar: python35u-3.5.1-3.ius.el6.x86_64 (ius)
              python(abi) = 3.5
Je zou kunnen proberen met behulp van --skip-broken het probleem te omzeilen
Je zou kunnen proberen: rpm -Va --nofiles --nodigest
Geladen plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* base: centos.mirror.transip.nl
* epel: ftp.nluug.nl
* extras: centos.mirror.transip.nl
* ius: mirror.amsiohosting.net
* updates: centos.mirror.transip.nl
Oplossen van afhankelijkheden
--> Transactiecontrole uitvoeren
---> Pakket python27.x86_64 0:2.7.11-1.ius.el6 wordt geïnstalleerd
--> Verwerking afhankelijkheid: python27-libs(x86-64) = 2.7.11-1.ius.el6 voor pakket: python27-2.7.11-1.ius.el6.x86_64
---> Pakket python27-devel.x86_64 0:2.7.11-1.ius.el6 wordt geïnstalleerd
---> Pakket python27-pip.noarch 0:8.0.3-1.ius.el6 wordt geïnstalleerd
--> Verwerking afhankelijkheid: python27-setuptools voor pakket: python27-pip-8.0.3-1.ius.el6.noarch
---> Pakket python27-tools.x86_64 0:2.7.11-1.ius.el6 wordt geïnstalleerd
--> Verwerking afhankelijkheid: tkinter27 = 2.7.11-1.ius.el6 voor pakket: python27-tools-2.7.11-1.ius.el6.x86_64
---> Pakket python27-virtualenv.noarch 0:14.0.6-1.ius.el6 wordt geïnstalleerd
--> Transactiecontrole uitvoeren
---> Pakket python27-libs.x86_64 0:2.7.11-1.ius.el6 wordt geïnstalleerd
--> Verwerking afhankelijkheid: libgdbm.so.2()(64bit) voor pakket: python27-libs-2.7.11-1.ius.el6.x86_64
--> Verwerking afhankelijkheid: libffi.so.5()(64bit) voor pakket: python27-libs-2.7.11-1.ius.el6.x86_64
---> Pakket python27-setuptools.noarch 0:19.7-1.ius.el6 wordt geïnstalleerd
---> Pakket tkinter27.x86_64 0:2.7.11-1.ius.el6 wordt geïnstalleerd
--> Klaar met oplossen afhankelijkheden
Fout: Pakket: python27-libs-2.7.11-1.ius.el6.x86_64 (ius)
           Vereist: libffi.so.5()(64bit)
Fout: Pakket: python27-libs-2.7.11-1.ius.el6.x86_64 (ius)
           Vereist: libgdbm.so.2()(64bit)
Je zou kunnen proberen met behulp van --skip-broken het probleem te omzeilen
Je zou kunnen proberen: rpm -Va --nofiles --nodigest
Could not install Python dependencies. Aborting bootstrap!

[email protected] [~/letsencrypt]# whereis python
python: /usr/bin/python2.7 /usr/bin/python /usr/bin/python2.7-config /usr/lib/python2.7 /usr/lib64/python2.7 /etc/python /usr/include/python2.7 /usr/share/man/man1/python.1.gz
Any thoughs on this problem? I've got Python 2.7 installed, but Let's Encrypt is searching for Python 2.6 for some reason.

I'm Using CentOS 7.2.1511.
 

Brooky A

Member
Sep 16, 2015
20
4
53
UK
cPanel Access Level
Root Administrator
Can anyone help? As the script is run as root the files written to the web root have root file permissions. This means that a 404 not found is delivered back to letsencrypt instead of 200 with hash so authentication fails.

Can I either;
- Allow Apache to server files with root ownership
- Get Letsencrypt set the correct owner/group on the example.com/.well-known/acme-challenge/xxx file.
 
Last edited by a moderator:

cPanelMichael

Administrator
Staff member
Apr 11, 2011
47,910
2,213
363
Hello,

I'd like to note a thread regarding the official cPanel plugin for Let's Encrypt is open at:

Let's Encrypt Support

Anyone using the custom workaround on this thread may want to keep in mind the official plugin is planned for release when cPanel 58 hits the "Current" build tier, tentatively around two months from now.

Thank you.
 
  • Like
Reactions: eva2000

tss

Member
Aug 22, 2011
13
3
53
The problem I see with the above posted fix (if it works for you) is that .htaccess can get over-written any time Drupal is updated. You'd have to find away to preserve the .htaccess file when you upgrade or try to automate the line always getting inserted. I do believe the Drupal developers are working on a patch to allow stuff like letsencrypt-auto to work.

Support RFC 5785 by whitelisting the .well-known directory [#2408321] | Drupal.org
@Spork Schivago:

Thanks for the reference. The patch has been released and works like a charm. I know because my D7 sites didn't get renewed the first time I tried it. After I applied the patch everything was perfect. It can't get much easier than renewing all your domains with a single command:

[~/letsencrypt]# ./letsencrypt-auto renew

Perhaps other cPanel users that run Drupal will come across this very helpful thread.
 

tss

Member
Aug 22, 2011
13
3
53
How can the method and `installssl.pl` script in the first post in this thread be adapted to work for the "main" cPanel/WHM domain? That is, if my cPanel login is at https://host.myhostname.com:2083, how can I use this method to generate and install the script for host.myhostname.com?

I was able to generate the key and chain by modifying the `letsencrypt` command to use `--webroot-path
/usr/local/apache/htdocs/`. This allowed Let's Encrypt to successfully authenticate our ownership of host.myhostname.com.

However, `installssl.pl` fails with this error:

[email protected] [5966 15:06:30 ~/letsencrypt]# ../installssl.pl host.myhostname.com
{"metadata":{"version":1,"reason":"The domain “host.myhostname.com” is not managed on this server. You must specify an IP address to install SSL for “host.myhostname.com” or set up this domain on a new account, or create it as parked domain, a subdomain, or an addon domain of an existing account, and try again.","output":{"raw":"The domain “host.myhostname.com” is not managed on this server. You must specify an IP address to install SSL for “host.myhostname.com” or set up this domain on a new account, or create it as parked domain, a subdomain, or an addon domain of an existing account, and try again."},"result":0,"command":"installssl"}}

I know I can manually install the cert, but I don't want to do so every 3 months (and possibly even more frequently as the Let's Encrypt project matures). How can I adapt `installssl.pl` or use some other method to automatically install this cert?
I"d like to know too. Not only that, but how can we install certs for the "mail" subdomain? Also for all the cPanel and WHM instances of individual domains, and specifically for the https://domain.com:2096 webmail services? Currently, I can't access ANY email from these domains on my phone because the certs are untrusted and neither the mail client nor the browser allow me to view the certs and "trust" them anyway, like I can in my desktop browsers.
 
Last edited:

Chanadian

Registered
Oct 26, 2015
1
0
1
Baton Rouge, LA
cPanel Access Level
Root Administrator
I've made a few simple changes to the perl script to account for subdomains. It takes the previous suggestions about the root password into account, and adds a newline character to all output. I've also created some cron jobs for automatic renewal and installation for subdomains:

Perl Script

Code:
#!/usr/local/cpanel/3rdparty/bin/perl

use LWP::UserAgent;
use LWP::Protocol::https;
use MIME::Base64;
use IO::Socket::SSL;
use URI::Escape;

my $accesshash;

my $access_hash_file = '/root/.accesshash';
sysopen (my $access_hash_file_fh, $access_hash_file, O_RDONLY) or
die "unable to open root_access_hash_file $!\n";
while (<$access_hash_file_fh>) {
$accesshash .= $_;
}
close ($access_hash_file_fh);

$accesshash =~ s/\n//g;


my $user = "WHM root";
my $auth = $user . ":" . $accesshash;


my $ua = LWP::UserAgent->new(
    ssl_opts   => { verify_hostname => 0, SSL_verify_mode => 'SSL_VERIFY_NONE', SSL_use_cert => 0 },
);

my ($dom, $domdir) = @ARGV;

if (not defined $dom) {
  die "Please specify domain\n";
}

if (not defined $domdir) {
  $domdir = $dom;
}

my $certfile = "/etc/letsencrypt/live/$domdir/cert.pem";
my $keyfile = "/etc/letsencrypt/live/$domdir/privkey.pem";
my $cafile =  "/etc/letsencrypt/live/$domdir/chain.pem";

my $certdata;
my $keydata;
my $cadata;

open(my $certfh, '<', $certfile) or die "cannot open file $certfile\n";
    {
         local $/;
        $certdata = <$certfh>;
    }
    close($certfh);

open(my $keyfh, '<', $keyfile) or die "cannot open file $keyfile\n";
    {
         local $/;
        $keydata = <$keyfh>;
    }
    close($keyfh);

open(my $cafh, '<', $cafile) or die "cannot open file $cafile\n";
    {
        local $/;
           $cadata = <$cafh>;
    }
    close($cafh);

my $cert = uri_escape($certdata);
my $key = uri_escape($keydata);
my $ca = uri_escape($cadata);

my $request = HTTP::Request->new( POST => "https://127.0.0.1:2087/json-api/installssl?api.version=1&domain=$dom&crt=$cert&key=$key&cab=$ca" );
$request->header( Authorization => $auth );
my $response = $ua->request($request);
print $response->content . "\n";
Usage: /root/installssl.pl <domain (including subdomain)> [domain (letsencrypt directory name)]

If only the first argument is supplied, it will use that domain to find the directory. If both are supplied, it uses the first to install the certificate, and the second to find the directory.

Cron Jobs

Here are the cron jobs, which run once every 60 days:

Code:
0 0 */60 * * /root/.local/share/letsencrypt/bin/letsencrypt --text certonly --renew-by-default --webroot --webroot-path /path/to/your/webroot -d yourfirstdomain.com -d www.yourfirstdomain.com; /root/installssl.pl yourfirstdomain.com
0 0 */60 * * /root/.local/share/letsencrypt/bin/letsencrypt --text certonly --renew-by-default --webroot --webroot-path /path/to/your/webroot -d yourseconddomain.com -d www.yourseconddomain.com -d subdomaina.yourseconddomain.com -d subdomainb.yourseconddomain.com -d subdomainc.yourseconddomain.com -d subdomaind.yourseconddomain.com; /root/installssl.pl yourseconddomain.com
0 0 */60 * * /root/installssl.pl subdomaina.yourseconddomain.com yourseconddomain.com
0 0 */60 * * /root/installssl.pl subdomainb.yourseconddomain.com yourseconddomain.com
0 0 */60 * * /root/installssl.pl subdomainc.yourseconddomain.com yourseconddomain.com
0 0 */60 * * /root/installssl.pl subdomaind.yourseconddomain.com yourseconddomain.com
 

visskiss

Member
Jun 17, 2008
14
0
51
For some reason, the api command for installing an ssl certificate for a service does not install the cabundle. Any ideas? When I install via whm "service ssl certificates" the cabundle installs properly, but via api, it doesn't

Here is my script

Code:
#!/usr/local/cpanel/3rdparty/bin/perl

use strict;
use LWP::UserAgent;
use LWP::Protocol::https;
use MIME::Base64;
use IO::Socket::SSL;
use URI::Escape;
use Fcntl;

my $user = "root";
my $accesshash;

my $access_hash_file = '/root/.accesshash';
sysopen (my $access_hash_file_fh, $access_hash_file, O_RDONLY) or
die "unable to open root_access_hash_file $!\n";
while (<$access_hash_file_fh>) {
$accesshash .= $_;
}
close ($access_hash_file_fh);

$accesshash =~ s/\n//g;

my $auth = "WHM root:".$accesshash;

my $ua = LWP::UserAgent->new(
    ssl_opts   => { verify_hostname => 0, SSL_verify_mode => 'SSL_VERIFY_NONE', SSL_use_cert => 0 },
);

my $dom = $ARGV[0];
my $service = $ARGV[1];

my $certfile = "/etc/letsencrypt/live/$dom/cert.pem";
my $keyfile = "/etc/letsencrypt/live/$dom/privkey.pem";
my $cafile =  "/etc/letsencrypt/live/bundle.txt";

my $certdata;
my $keydata;
my $cadata;

open(my $certfh, '<', $certfile) or die "cannot open file $certfile";
    {
         local $/;
        $certdata = <$certfh>;
    }
    close($certfh);

open(my $keyfh, '<', $keyfile) or die "cannot open file $keyfile";
    {                                          
         local $/;
        $keydata = <$keyfh>;
    }
    close($keyfh);

open(my $cafh, '<', $cafile) or die "cannot open file $cafile";
    {
         local $/;
        $cadata = <$cafh>;
    }
    close($cafh);

my $cert = uri_escape($certdata);
my $key = uri_escape($keydata);
my $ca = uri_escape($cadata);

my $request = HTTP::Request->new( POST => "https://127.0.0.1:2087/json-api/install_service_ssl_certificate?api.version=1&service=$service&crt=$cert&key=$key&cab=$ca
" );
$request->header( Authorization => $auth );
my $response = $ua->request($request);
print $response->content;
My workaround is ignoring the cabundle and using fullchain.pem instead of cert.pem (which installs the full chain as the cert)
 

iSpeakVideo

Registered
Nov 14, 2012
3
0
1
cPanel Access Level
DataCenter Provider
Any help is appreciated. I installed SSL on several domains on cloud server with cpanel. They were fine. They expired and I tried to update. With renew. But they didn't update update in cpanel. So, I deleted and tried to reinstall with installssl.pl but I get this error:

{"cpanelresult":{"apiversion":"2","error":"Access denied","data":{"reason":"Access denied","result":"0"},"type":"text"}}

Thanks.
 

kitchin

Member
Sep 18, 2011
24
0
51
cPanel Access Level
Root Administrator
Might be worth mentioning that the hostname cert in WHM since cPanel 56 is fully valid and no longer causes a browser warning. It's issued by "cPanel, Inc. Certification Authority" instead of being self-signed.

I was surprised to see that when my Let's Encrypt for the hostname ran out after 90 days. Of course, if you are using Let's Encrypt for other domains, please ignore this slightly off-topic thread.
 

cPanelMichael

Administrator
Staff member
Apr 11, 2011
47,910
2,213
363
Has anyone faced any down sides for using this workaround?
It's important to keep in mind this is a third-party plugin. Users should consider waiting for cPanel version 58 (It includes free DV certificates from cPanel (through Comodo) and future support for "Let's Encrpyt" via an official plugin.

Thank you.
 
Status
Not open for further replies.