michael orlitzky

Certificate chains in Apache 2.4

posted 2015-01-09

The Problem

AH00016: Configuration Failed, most likely.

With version 2.4, the Apache web server has deprecated the SSLCertificateChainFile directive:

SSLCertificateChainFile is deprecated

SSLCertificateChainFile became obsolete with version 2.4.8, when SSLCertificateFile was extended to also load intermediate CA certificates from the server certificate file.

Instead you're supposed to use SSLCertificateFile; but before you do, jam all of your certificates together into one big file. Suppose www.example.com.crt is your site's certificate, and chain.crt is the intermediate certificate bundle. You try,

user $ cat chain.crt www.example.com.crt > combined.crt

And configure Apache to use combined.crt:

SSLCertificateFile /path/to/ssl/y'all/combined.crt

You even verify that OpenSSL likes your big certy mess:

user $ openssl verify combined.crt

combined.crt: OK

Now you restart Apache and… the phones start ringing. Fuck. Apache is dead. If you look in the main Apache error log, you'll find a line that says,

AH00016: Configuration Failed

Ok, so…? You would never guess, but that error means that Apache didn't like one of your certificates. Yes, one bad certificate can kill the entire server.

This whole dumb ass scenario is httpd bug #57360.

Doin' it Well

If you combine the certificates in the correct order, everything is fine. Let's summon SSL Candyman. You certificate must come first. Your certificate must come first. Your certificate must come first.

user $ cat www.example.com.crt chain.crt > combined.crt

Now restart Apache, and it will work unless you screwed up something else.

Warning: If your site's certificate file doesn't end in a newline, you're going to wind up with a combined.crt containing a line like this:


Guess what happens if that happens. That, but also AH00016: Configuration Failed!

A Very Special Fuck You

Remember how openssl verify happily verified combined.crt when it had been combined in the wrong order? Try it now that you've done it correctly:

user $ openssl verify combined.crt

combined.crt: O = www.example.com, OU = Domain Control Validated, CN = www.example.com

error 20 at 0 depth lookup:unable to get local issuer certificate;

Go right to hell.