lets encrypt, with Centos 6.
Posted on December 5, 2015 • 8 minutes • 1700 words • Suggest Changes
**Note : **There are alternatives ways of getting lets encrypt to work in non-default environments, one is described in my new article : Let’s Encrypt on … any Linux distro
Let’s encrypt the web, an easy, automated and free method to get https for your website. I already explained how you could install letsencrypt on centos 6.7, but things on the interwebz go fast. So fast that in fact the tutorial is already deprecated. Since *beta* support has been added for Python 2.6, now Centos 6.X should work out of the box. Spoiler : it doesn’t yet. (hence the beta label by letsencrypt) This guide should help to get https in a not yet fully supported environments (such as Centos 6). As you might have noticed, also svennd.be is now running on https! (not cause its really necessary, but it is cool isn’t it ? :P)
My start point
- I have a Centos 6.X configured and yum-cron updated nightly
- I have apache (http) running multiple domains and is a bit configured
- I have 0 experience with SSL setup in http (Trust me, I have never done this before, successfully)
Getting the certificate
The first part is easy, the docs help out allot and since we all read them just after the terms and services. Right guys/gals ?
# copy the software cd /opt git clone git clone https://github.com/letsencrypt/letsencrypt cd letsencrypt
Now the next part would be to start the tool and it should help you there, the problem is, this requires to bind to port 80, which is obviously in use, by apache (httpd). So that won’t work, also if you run this with Python 2.6 (Centos 6X) you will get a warning and it won’t wanne do anything without you telling it to go in –debug
mode.
There is however an alternative plugin included, which uses the webroot of the domain (in Apache words : DocumentRoot). Now Let’s Encrypt does not give out wildcard certificates, which means that you do not get *.svennd.be validated, instead you can get www.svennd.be, svennd.be, alfa.svennd.be, beta.svennd.be, … just remember that you have to request those at the same time when you request the certificate, if you repeat the process, they won’t work. Since we aim to automate, I like to use as little as possible command line arguments, so I made a config file.
create /etc/letsencrypt/cli.ini
# the default is 2048 (more is better) rsa-key-size = 4096 # plugin authenticator = webroot # webroot webroot-path = /var/www/svennd/ # domains domains = svennd.be,www.svennd.be # flags # renew is good for automation renew-by-default
Note : change the domain names to your domain name(s).
Now we can run the tool :
/opt/letsencrypt/letsencrypt-auto --config /etc/letsencrypt/cli.ini --debug certonly
Since I am on a not supported system I need the –debug
flag. If everything goes as planned you should be congratulated as followed :
Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/www.svennd.be/fullchain.pem. Your cert will expire on 2016-03-04. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - If like Let's Encrypt, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
**Possible errors
** Since It already took me some time to get here know that these errors are also rather common;
error:connection
The following 'urn:acme:error:connection' errors were reported by the server:
Which means it has no access to the server in general, best start point would be to check firewall or connection setting. The server should be publicly accessible during the webroot challenge.
error:unauthorized
FailedChallenges: Failed authorization procedure. cert.svennd.be (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://cert.svennd.be/.well-known/acme-challenge/SOME_HASH [128.199.41.151]: 404
I banged my head on this one, I received this error when I moved my website and configuration from http to https, this made the location unreachable. But it would be something you would also receive if your webroot is different from normal and you just copy-pasted the config. The webroot is the directory where users get their “index.php/html/asp/…” page from. For allot users thats somewhere here : /var/www/public_html/my_domain/ If you are not sure, its _DocumentRoot in the configuration of Apache. Another way to know is to create a file “test.html” and go to your website : domain.ext/test.html a 404 means its not in the right directory. (you expect an empty white page) Be sure that yourdomain.ext/.well-known/* is accessible ! T_hx to Luis for pointing this out.
error:rateLimited
Error: urn:acme:error:rateLimited :: There were too many requests of a given type :: Error creating new cert :: Too many certificates already issued for: svennd.be
This happens when you have played to much with them 😀 The solution is simple and hard, its called : wait it out. As long as the beta is in, they will rateLimit rather strongly, I believe not to many people will see this, after the initial beta period.
error code 1 in cryptography
Command "/root/.local/share/letsencrypt/bin/python2.7 -c "import setuptools, tokenize;__file__='/tmp/pip-build-cAuqmP/cryptography/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-rhCaoe-record/install-record.txt --single-version-externally-managed --compile --install-headers /root/.local/share/letsencrypt/include/site/python2.7/cryptography" failed with error code 1 in /tmp/pip-build-cAuqmP/cryptography
This happened due to limited resources during cryptokey generation. The solution was to create more free memory, although one should never go straight to production server without testing SSL first.
Errno 22
OSError: [Errno 22] Invalid argument: ‘/etc/letsencrypt/live/cert.pem’ letsencrypt
It only happened during a server move, see the post.
Activate the SSL in Apache
Now I assume somehow you got to the point where you got congratulated and created the certificate. This would mean that you got four new files in /etc/letsencrypt/live/www.svennd.be/
, you would see cert.pem, chain.pem, fullchain.pem, privkey.pem.
I have Apache 2.2.15 (yum info httpd
) and by default it won’t listen to port 443. So we need to add this :
In /etc/httpd/conf/httpd.conf
find Listen 80
and add
Listen 443
After that you can adapt your virtualhost website configuration, I work with _VirtualHost *:80. _My config looked like this :
<VirtualHost *:80> # server setup ServerName svennd.be ServerAlias www.svennd.be ServerAdmin webmaster@svennd.be DocumentRoot /var/www/svennd <Directory "/var/www/svennd"> AllowOverride All Order allow,deny Allow from all </Directory> </VirtualHost>
I wanted to have both http and https running and after that is working (you want to check if everything works in https first)! Permanently redirect all traffic to https. To do that pretty much copy the virtualhost 80 to virtualhost 443. (full example, change to your domain!)
LoadModule ssl_module modules/mod_ssl.so <VirtualHost *:443> # server setup ServerName svennd.be ServerAlias www.svennd.be ServerAdmin webmaster@svennd.be DocumentRoot /var/www/svennd # ssl setup SSLEngine ON SSLProtocol all -SSLv2 -SSLv3 SSLHonorCipherOrder On SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4" SSLCertificateFile /etc/letsencrypt/live/www.svennd.be/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/www.svennd.be/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/www.svennd.be/chain.pem <Directory "/var/www/svennd"> AllowOverride All Order allow,deny Allow from all </Directory> </VirtualHost> <VirtualHost *:80> # server setup ServerName svennd.be ServerAlias www.svennd.be DocumentRoot /var/www/svennd <Directory "/var/www/svennd"> AllowOverride All Order allow,deny Allow from all </Directory> </VirtualHost>
I also added that httpd has to load the ssl module, on default installation however ssl module is not installed! Fix that with : yum install mod_ssl
. After that remove /etc/httpd/conf.d/ssl.conf
or comment it.
Now you have to restart your httpd service, before doing so test if the config is right : service httpd configtest
You expect : Syntax OK. If that is the case restart your webserver :
service httpd restart
Now both http and https should be available; If its not, first check if your firewall allows connections on 443. For me it did not, I filter on INPUT rules, so I only had to add it there :
# add it iptables -I INPUT -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT # save it service iptables save
Then my WordPress took both https and http. Next part is probably only for WP owners, so you can skip that.
Getting WordPress to play nice with Lets-encrypt ssl
Adapting WordPress itself is rather easy, in wp-admin -> Settings -> General -> change WP address and site address to both https:// domain.ext. After that, I noticed most of my images where broken due to using http:// (note : you would get mixed error, I already adapted my .htaccess) You could change that using MySQL query (source):
UPDATE wp_posts SET post_content = ( Replace (post_content, 'src="http://', 'src="//') ) WHERE Instr(post_content, 'jpeg') > 0 OR Instr(post_content, 'jpg') > 0 OR Instr(post_content, 'gif') > 0 OR Instr(post_content, 'png') > 0;
That’s all !
All http request redirected to https, except for _.well-known _for renewal
I had to allow .well-known to be served over http, otherwise we can’t renew the certificate. This is my .htaccess (from WP), this is useful tool for testing .htaccess files.
RewriteEngine On # HTTP REDIRECT # its a http page request RewriteCond %{HTTPS} off # its not .well-known RewriteCond %{REQUEST_URI} !\.well-known # perm redirect to https version RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R,L] # WORDPRESS REDIRECT RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>
note : Change R to R=301 once you have tested this configuration. (that is permanent)
Now add a cron, I added this /etc/cron.weekly/certificate
#!/bin/sh /opt/letsencrypt/letsencrypt-auto --config /etc/letsencrypt/cli.ini --debug certonly EXITVALUE=$? if [ $EXITVALUE != 0 ]; then /usr/bin/logger -t letsencrypt "ALERT exited abnormally with [$EXITVALUE]" fi exit 0
This should update you’re SSL certificate every week, this leaves enough time for you to see if something is not running as expected. If you should miss it don’t worry, let’s encrypt has you’re email adres for just that case. You get a nice e-mail warning you :
Hello, Your certificate (or certificates) for the names listed below will expire in 13 days (on 2016-02-03 12:18:00 +0000 UTC). Please make sure to renew your certificate before then, or visitors to your website will encounter errors. example.ext For any questions or support, please visit https://community.letsencrypt.org/. Unfortunately, we can't provide support by email. Regards, The Let's Encrypt Team
After you moved over, dump your url in ssllabs to see your SSL rating, some tweaks might be needed to get you to A+, but I believe its definitely worth it! (svennd.be is now A+)
Encrypted a tiny part of the web !