How to Secure Apache with Let’s Encrypt on CentOS 6

Robert AndresenProgramming, Tutorials Leave a Comment

Install the Let’s Encrypt client

$ git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt

I didn’t have git installed, so I just downloaded it from Github and added it under /opt/letsencrypt on the server.

 

So to the Centos 6 «fix»

You’ll need to run the client in Pyhon 2.7.

$ yum install centos-release-SCL
$ yum install python27

Your python version should still be 2.6.6.

$ python -V
Python 2.6.6

Run the client

$ scl enable python27 «/opt/letsencrypt/letsencrypt-auto –apache -d mydomain.no»

While installing you will get a config screen where you enter your mail and select the virtual host. As my Centos 6 apache does not have virtual host files like Centos7, the letsencrypt software only found default ssl.conf under /etc/httpd/conf.d/.

As I had my virtual hosts under /etc/httpd/conf/httpd.conf, i removed the created virtual host under ssl.conf and added the necessary info in my /etc/httpd/conf/httpd.conf, like this:

<VirtualHost *:443>
	SSLEngine on
	SSLProtocol all -SSLv2
	SSLCipherSuite DEFAULT:!EXP:!SSLv2:!DES:!IDEA:!SEED:+3DES
	SSLCertificateFile /etc/letsencrypt/live/mydomain.no/cert.pem
	SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.no/privkey.pem
	SetEnvIf User-Agent ".*MSIE.*" \
	     nokeepalive ssl-unclean-shutdown \
	     downgrade-1.0 force-response-1.0
	SSLCertificateChainFile /etc/letsencrypt/live/mydomain.no/chain.pem

	ServerName mydomain.no
	ServerAlias www.mydomain.no
	DocumentRoot /var/www/webpage/mydomain.no

	<Directory />
	    AllowOverride All
	</Directory>

	<Directory /var/www/webpage/mydomain.no>
	    AllowOverride All
	</Directory>

	ErrorLog /var/log/httpd/mydomain.no-error_log 
</VirtualHost>

Automate certificate renewal

Edit and add this to you /etc/crontab or crontab -e.

03 3 * * * root scl enable python27 «/opt/letsencrypt/letsencrypt-auto certonly –keep-until-expiring –agree-tos –quiet –webroot –webroot-path /var/www/webpage/mydomain.no -d mydomain.no»; /etc/init.d/httpd restart

Install additional certificates

[root@webserver]# scl enable python27 "/opt/letsencrypt/letsencrypt-auto certonly --webroot --webroot-path /var/www/webpage/subdomain.mydomain.no -d subdomain.mydomain.no"
Checking for new version...
Requesting root privileges to run letsencrypt...
   /root/.local/share/letsencrypt/bin/letsencrypt certonly --webroot --webroot-path /var/www/webpage/subdomain.mydomain.no -d subdomain.mydomain.no
Version: 1.1-20080819
Version: 1.1-20080819

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/subdomain.mydomain.no/fullchain.pem. Your cert
   will expire on 2016-08-02. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - If you 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

I got this error message on http restart:

[root@webserver]# /etc/init.d/httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd: [Wed May 04 15:52:50 2016] [warn] _default_ VirtualHost overlap on port 443, the first has precedence
                                                           [  OK  ]

…so I had to add «NameVirtualHost *:443» above «Listen 443» in the /etc/httpd/conf.d/ssl.conf

#
# This is the Apache server configuration file providing SSL support.
# It contains the configuration directives to instruct the server how to
# serve pages over an https connection. For detailing information about these 
# directives see <URL:http://httpd.apache.org/docs/2.2/mod/mod_ssl.html>
# 
# Do NOT simply read the instructions in here without understanding
# what they do.  They're here only as hints or reminders.  If you are unsure
# consult the online docs. You have been warned.  
#

LoadModule ssl_module modules/mod_ssl.so

#
# When we also provide SSL we have to listen to the 
# the HTTPS port in addition.
#
NameVirtualHost *:443
Listen 443

 

Update 2016.05.21

If you try to add certificate on a webpage protected with username and password, with .htaccess – you’ll get an error like this. Let’s encrypt cannot read the file under .well-known, so you need to temporary disable the .htaccess security by moving or renaming the file, while doing the let’s encrypt process.

Failed authorization procedure. sub.mydomain.no (http-01): urn:acme:error:unauthorized :: 
The client lacks sufficient authorization :: 
Invalid response from http://sub.mydomain.no/.well-known/acme-challenge/...: 
"<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>401 Authorization Required</title>
</head><body>
<h1>Auth"

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: db.infoplakat.no
   Type:   unauthorized
   Detail: Invalid response from http://sub.mydomain.no/.well-known
   /acme-challenge/...:
   "<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
   <html><head>
   <title>401 Authorization Required</title>
   </head><body>
   <h1>Auth"

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A record(s) for that domain
   contain(s) the right IP address.

 

Update 2016.08.21

Auto certificate renewal didn’t work as planned. Haven’t had the time to debug it yet, but got them renewed with:

scl enable python27 «/opt/letsencrypt/letsencrypt-auto renew»

I tried to specify domain, but got an error that domain cannot be specified by renewal.

Command with full feedback:

[user@webserver ~]# scl enable python27 "/opt/letsencrypt/letsencrypt-auto renew"

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/mydomain.no.conf
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/beta.mydomain.no.conf
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/beta.mydomain.no/fullchain.pem
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/dev.mydomain.no.conf
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/db.mydomain.no.conf
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/db.mydomain.no/fullchain.pem
-------------------------------------------------------------------------------

The following certs are not due for renewal yet:
/etc/letsencrypt/live/mydomain.no/fullchain.pem (skipped)
/etc/letsencrypt/live/dev.mydomain.no/fullchain.pem (skipped)
Congratulations, all renewals succeeded. The following certs have been renewed:
/etc/letsencrypt/live/beta.mydomain.no/fullchain.pem (success)
/etc/letsencrypt/live/db.mydomain.no/fullchain.pem (success)

When auto-renew doesn’t work?

The renew command worked for all of my sub-domains, but not mydomain.no. When i checked the changed time in /etc/letsencrypt/live/mydomain.no, the date was 3 months old (only on that domain). Still browser gives an expired message and the command tells me that the domain is not up for renewal yet.

The I used this command:

scl enable python27 "/opt/letsencrypt/letsencrypt-auto run -d mydomain.no"

This gave me this window, and is still telling me that I have a certificate that isn’t close to expiry:

letsencrypt_run

I selected number 2 «Renew & replace the cert…».

This gave me first an error:

No vhost exists with servername or alias of: mydomain.no. No vhost was selected. Please specify servernames in the Apache config

Then:

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/mydomain.no/fullchain.pem. Your cert will
expire on 2016-11-19. To obtain a new or tweaked version of this
certificate in the future, simply run letsencrypt-auto again with
the "certonly" option. To non-interactively renew *all* of your
certificates, run "letsencrypt-auto renew"

And it looks like it worked! Yey!

 

 

Sources: