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 [email protected]
        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

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


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


A find on the directory heirarchy yields:

root@www:/etc/letsencrypt# find `pwd` -print

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


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 /home/cjsh/fathers>
    Options ExecCGI FollowSymLinks Indexes MultiViews
    AllowOverride None
    Order allow,deny
    allow from all

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 ::1/128


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

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.

  • 5
    The filename 0000_csr-letsencrypt.pem suggests you included the certificate signing request, not the actual signed certificate. Every file you need should be in a subdirectory of /etc/letsencrypt/live with your domain name. and a serial number, you don't need anything from /etc/letsencrypt/csr or keys Do you have log file entries?
    – Sven
    Mar 21, 2016 at 18:11
  • does apache have rights to read /home/jonathan/stornge?
    – warren
    Mar 29, 2016 at 13:45

3 Answers 3


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 *: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 [email protected]

    SSLEngine on

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

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


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

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.

  • Thank you; may I suggest a revision to your HOWTO? Let's Encrypt doesn't do multiple VirtualHosts in one .conf file; you might add a step before Let's Encrypt looks through the .conf files that any domain or subdomain served by Let's Encrypt should have only its VirtualHost in the .conf file, and files with multiple VirtualHosts should be separated so that Let's Encrypt finds one VirtualHost, one .conf file for every domain where you address encryption. (This includes a file that has a real site at domain.tld and with it a VirtualHost redirecting www.domain.tld to the real location.) Apr 6, 2016 at 17:58
  • @JonathanHayward - I run Let's Encrypt in --standalone certonly mode (see my cronning how-to (~/letsencrypt/letsencrypt-auto --agree-tos --keep --rsa-key-size 2048 --standalone certonly -m [email protected] -d domain.tld [-d sub.domain.tld [-d ...]])), I don't use any of the plugins (like automatically scanning Apache configs), which I cover in both how-tos. I appreciate the suggestion, but am having good success in standalone mode and letting it update certs behind the scenes, so to speak.
    – warren
    Apr 6, 2016 at 18:46
  • Ok, but I was writing out of difficulties with standalone certonly. I didn't use automatic scanning. Apr 6, 2016 at 18:48
  • @JonathanHayward - what issues have you had with --standalone certonly?
    – warren
    Apr 6, 2016 at 18:49
  • 1
    Thank you; see the updated question. I've also posted a question at serverfault.com/questions/768643/… , which is related but separate and I did not want to tack it on to an already verbose question. Apr 6, 2016 at 20:45

I've found the client ACME works well, it's easy to set up and get going, it's updated regularly and is easy to update, and it works very well on Amazon Linux. I've written a tutorial on it which you can find here.

Get started by downloading ACME and setting it up

cp ./acmetool /usr/local/bin
/usr/local/bin/acmetool quickstart

Request a certificate

./acmetool want example.com www.example.com

This is how I set up the directory for the challenge - this is where Let's Encrypt connects to your server to validate

mkdir -p /var/www/acme-challenge/.well-known/acme-challenge
chmod -R user:www-data /var/www/acme-challenge/*
find /var/www/acme-challenge/ -type d -exec chmod 755 {} \;
vi /var/www/acme-challenge/.well-known/acme-challenge/text.html   (add "hello world!" or similar)

There's more detail and commentary on the linked website above, and the author and community are helpful.


I had good success using EFF's Certbot in web root mode (because the idea of an automated process stopping the web server, even if only briefly, during certificate renewal scares me).

First, install Certbot. If you are on Debian Jessie (which is current at the time of my writing this), first add the jessie-backports repository, then

$ sudo apt-get install python-certbot-apache -t jessie-backports

This will bring in a handful of packages plus certbot itself.

Then, to create a certificate in webroot mode, run something like

$ sudo certbot certonly --webroot -w /srv/www/www.example.net/htdocs -d www.example.net

You can optionally add --register-unsafely-without-email as well as --rsa-key-size X if you want a modulus size other than the default (which is currently 2048 bits). -d fqdn.example.com can be repeated an arbitrary number of times, as can -w; each -w starts a new set of domains served out of a directory, domains named by -d. Let's Encrypt does not issue wildcard certificates (this is mentioned in their FAQ) and apparently, also not certificates for Punycode domain names.

The user that certbot runs as needs, at the very least and by default, write access to several places under /etc/letsencrypt. It's probably easiest to just run it as root. It will create a file under .well-known/acme-challenge under the given web root directory (-w), have the remote system verify that it's accessible over the specified domain names over HTTP, and if everything checks out will create a bunch of PEM files in /etc/letsencrypt/archive/www.example.net plus a corresponding set of symbolic links in /etc/letsencrypt/live/www.example.net and print a friendly success message.

If everything checks out, what's left for you to do is to set up your web server to use the certificate found in the host name subdirectory of /etc/letsencrypt/live for HTTPS for the domain in question. The absolute bare minimum for this for Apache is something similar to:

<VirtualHost *:443>
        ServerName www.example.net
        SSLEngine on
        SSLCertificateKeyFile /etc/letsencrypt/live/www.example.net/privkey.pem
        SSLCertificateFile /etc/letsencrypt/live/www.example.net/cert.pem
        SSLCertificateChainFile /etc/letsencrypt/live/www.example.net/chain.pem

Add any other directives as desired, verify using apache2ctl -S and apache2ctl configtest that everything checks out, and activate the HTTPS virtual host with apache2ctl graceful.

Don't forget to renew the certificate regularly; currently, Let's Encrypt certificates expire after 90 days. The Debian package ships with a cron job in /etc/cron.d/certbot and a systemd service in /lib/systemd/system/certbot.service which take care of this, or you can run certbot renew manually. Remember to apache2ctl graceful to start using the newly issued certificate; you may want to adjust the cron job or systemd service to do this automatically. To automatically load renewed certificates into Apache on Debian Jessie, consider updating /lib/systemd/system/certbot.service to add to the [Service] section (note: the order is important):

ExecStartPost=/usr/sbin/apache2ctl configtest
ExecStartPost=/usr/sbin/apache2ctl graceful

Doing so will automatically load the renewed certificate if the Apache configuration files pass configtest, and list Certbot as a failed unit if the configtest or graceful fails.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .