Let’s Encrypt – How to Use Let’s Encrypt as a Free SSL Certificate Provider

apache-2.4debianlets-encryptssl

I have a few sites running with a StartSSL free certificate (CJSHayward.com, JobhuntTracker.com), and Firefox rejects StartSSL and displays an error page saying that my server is not properly configured (IIRC) because of the certificate chain. I asked for help and confirmed that my VirtualHost (available on request) was for the certificate chain and I had the intermediate certificate installed correctly. The sites are displayed without errors that I am aware of in Chrome, Safari, Edge, or Opera.

After some searching, Let's Encrypt! looked like an attractive offering, and before too long I had (AFAICT) a private key and a certificate for each domain under /etc/apache2/sites-enabled, minus of course any domains that are no longer mine. I thought I'd do a trial run and make an HTTPS connection to a site now available only under HTTP: JSH.name. I moved the "Let's Encrypt!" certificate and private key to my SSL directory and added:

<VirtualHost *:443>
        ServerAdmin cjshayward@pobox.com
        DocumentRoot /home/jonathan/stornge
        SSLEngine On
        SSLCertificateFile /etc/apache2/ssl/0000_csr-letsencrypt.pem
        SSLCertificateKeyFile /etc/apache2/ssl/0000_key-letsencrypt.pem
        ServerName jsh.name
        ServerAlias www.jsh.name
        LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
        CustomLog /home/jonathan/logs/stornge.com combined
        <Directory /home/jonathan/stornge/>
            Options ExecCGI Indexes FollowSymLinks MultiViews
            AllowOverride None
            Order allow,deny
            allow from all
        </Directory>
</VirtualHost>

Then I rebooted to see my work, and every HTTP or HTTPS request I made simply hung. This included two domains on HTTPS with my StartSSL certificate, and the domain that should have been newly available on HTTPS accessed via both HTTP and HTTPS. I commented out the VirtualHost and bounced Apache, and all of the old functionality was back again in working order.

Have I used Let's "Encrypt!" correctly? I'm slightly suspicious as existing SSL configuration has private keys with an extension of .key, a certificate extension of .crt, and a certificate chain file with extension .pem.

I tried again after checking the SSL directory and finding that 0000_csr.letsencrypt.pem was mode 644; I changed all files in that directory to mode 600. When I tried a moment ago, I got a repeat of the old behavior: the website hangs on all requests and, in addition, an apachectl restart gets a statement (I forget the exact wording) that httpd is not running and the computer is trying to start it.

How can I get working free certitificates for "Let's Encrypt" or some other tool that hasn't alienated Firefox?

An apachectl -v gives:

Server version: Apache/2.4.10 (Debian)
Server built:   Nov 28 2015 14:05:48

A uname -a gives:

Linux www 4.4.0-x86_64-linode63 #2 SMP Tue Jan 19 12:43:53 EST 2016 x86_64 GNU/Linux

–UPDATE–

Contents deleted, 0000_key-letsencrypt.pem is bounded by:

-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----

A find on the directory heirarchy yields:

root@www:/etc/letsencrypt# find `pwd` -print
/etc/letsencrypt
/etc/letsencrypt/keys
/etc/letsencrypt/keys/0000_key-letsencrypt.pem
/etc/letsencrypt/accounts
/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org
/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory
/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/1ef8dc9b994b9b68a4e9c7cedd003be3
/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/1ef8dc9b994b9b68a4e9c7cedd003be3/private_key.json
/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/1ef8dc9b994b9b68a4e9c7cedd003be3/meta.json
/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/1ef8dc9b994b9b68a4e9c7cedd003be3/regr.json
/etc/letsencrypt/renewal
/etc/letsencrypt/options-ssl-apache.conf
/etc/letsencrypt/csr
/etc/letsencrypt/csr/0000_csr-letsencrypt.pem

The directory /home/jonathan/stornge and its contents are world readable and world executable where that would make a difference.

–UPDATE–

Adding something substantive here:

The http://OrthodoxChurchFathers.com Apache conf file has two VirtualHosts, one to serve up http://OrthodoxChurchFathers.com and one to redirect http://www.OrthodoxChurchFathers.com requests to http://OrthodoxChurchFathers.com. The .conf file housing both VirtualHosts is:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName orthodoxchurchfathers.com
    #ServerAlias www.orthodoxchurchfathers.com fathers.jonathanscorner.com

DocumentRoot /home/cjsh/fathers/document_root
&lt;Directory />
    Options FollowSymLinks
    AllowOverride None
&lt;/Directory>
&lt;Directory /home/cjsh/fathers>
    Options ExecCGI FollowSymLinks Indexes MultiViews
    AllowOverride None
    Order allow,deny
    allow from all
&lt;/Directory>

DirectoryIndex index.cgi index.html

ErrorLog ${APACHE_LOG_DIR}/error.log

# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn

CustomLog ${APACHE_LOG_DIR}/access.log combined

Alias /doc/ "/usr/share/doc/"
&lt;Directory "/usr/share/doc/">
    Options Indexes MultiViews FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
    Allow from 127.0.0.0/255.0.0.0 ::1/128
&lt;/Directory>

</VirtualHost>

&lt;VirtualHost *:80>
ServerAdmin CJSHayward@POBox.com
ServerName www.orthodoxchurchfathers.com
ServerAlias fathers.jonathanscorner.com
DocumentRoot /home/cjsh/oldmirror
RewriteEngine On
RewriteRule ^(.*)$ http://orthodoxchurchfathers.com$1 [R=301,L]
&lt;/VirtualHost></pre></code>

When I try to run it and request orthodoxchurchfathers.com alone, I get:

┌──────────────────────────────────────────────────────────────────────┐
│ We were unable to find a vhost with a ServerName or Address of │
│ orthodoxchurchfathers.com. │
│ Which virtual host would you like to choose? │
│ (note: conf files with multiple vhosts are not yet supported) │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │1 008-stornge.conf | Multiple Names | │ │
│ │2 014-paraskeva.conf | paraskeva.jonathansco | │ │
│ │3 036-unixytalk.conf | unixtalk.jsh.name | │ │
│ │4 038-proxy.conf | Multiple Names | │ │
│ │5 027-anna.conf | Multiple Names | │ │
│ │6 044-jobhunt-tracker.creation.c | Multiple Names | │ │
│ │7 049-jsh.conf | Multiple Names | │ │
│ │8 001-steampunk.conf | | │ │
│ │9 006-blajeny.conf | Multiple Names | │ │
│ │10 032-videos.conf | Multiple Names | d│ │
│ └────↓(+)──────────────────────────────────────────────────30%─────┘ │
├──────────────────────────────────────────────────────────────────────┤
│ │
└──────────────────────────────────────────────────────────────────────┘

The command I used was with ./letsencrypt-auto --debug certonly.

Best Answer

I have written a pair of how-tos for running Let's Encrypt SSL certs on CentOS: initial setup & cronning it.

And my per-domain (I use the file naming convention of z-<[sub-]domain-tld>.conf) Apache config files look like this:

<VirtualHost *:80>
ServerName domain.tld
Redirect permanent / https://domain.tld/
</VirtualHost>

<VirtualHost *:443>
    SSLCertificateFile /etc/letsencrypt/live/domain.tld/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/domain.tld/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/domain.tld/fullchain.pem
    DocumentRoot /var/www/domain
    ServerName domain.tld
    ErrorLog logs/domain-error_log
    CustomLog logs/domain-access_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    ServerAdmin user@domain.tld

    SSLEngine on

<Files ~ "\.(cgi|shtml|phtml|php3?)$">
    SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>

SetEnvIf User-Agent ".*MSIE.*" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

    <Directory "/var/www/domain">
         Options All +Indexes +FollowSymLinks
         AllowOverride All
         Order allow,deny
         Allow from all
    </Directory>

</VirtualHost>

And my ssl.conf looks like this:

#SSL options for all sites
Listen 443
SSLPassPhraseDialog  builtin
SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)
SSLSessionCacheTimeout  300
Mutex sysvsem default
SSLRandomSeed startup file:/dev/urandom  1024
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
SSLCompression          off
SSLHonorCipherOrder     on
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256

Using Let's Encrypt to get SSL certs (and get your site up to an "A" rating from SSL Labs) is pretty straight-forward - once you get past some of the arcana of the Apache configs and LE command-line arguments.