How do I conditionally set the SSLCertificateFile when the file exists?
I am using Let's Encrypt (certonly
) to generate SSL certificates for several websites hosted on an Apache server. The file location of these certificates is determinate before they are created, so I am writing their paths into my virtual host configuration in advance. Once the site is running, I will use certbot
to get the certificate files and then reload the Apache configuration.
I also have a global SSL certificate defined with valid files, so every SSL virtual host will be certain to have a certificate.
The problem I'm having is that Apache won't run without all the certificate files, despite having a global fallback. I tried to conditionally configure the Let's Encrypt certificate only when the file exists using IF
, but Apache says SSLCertificateFile not allowed here
.
How might I override the global SSLCertificateFile
only when the new certificate files exist? I'm trying to do all of this without having to modify the configuration before and after the certificates have been generated.
Here is what I tried:
<If "-f '/etc/letsencrypt/live/domain/fullchain.pem'">
SSLCertificateFile /etc/letsencrypt/live/domain/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domain/privkey.pem
</If>
→ SSLCertificateFile not allowed here
In this case, I would create a directory of symlinks for each domain, and use the server's snakeoil cert (or your previously mentioned "global" certificate) for domains you don't have configured yet. For example:
$ ls -1 /etc/ssl/domains
example.com/fullchain.pem -> /etc/letsencrypt/live/example.com/fullchain.pem
example.com/privkey.pem -> /etc/letsencrypt/live/example.com/privkey.pem
second-example.com/fullchain.pem -> /etc/ssl/certs/ssl-cert-snakeoil.pem
second-example.com/privkey.pem -> /etc/ssl/private/ssl-cert-snakeoil.key
You can then set the Apache directives to use the symlink directory:
SSLCertificateFile /etc/ssl/domains/example.com/fullchain.pem
SSLCertificateKeyFile /etc/ssl/domains/example.com/privkey.pem
This has the advantage of only needing to replace the symlink when you generate a Let's Encrypt certificate for the domain, however users visiting the domain before a full certificate is installed will receive warnings as the snakeoil certificate is self-signed.
You can use IfFile
instead of If
:
<IfFile "/etc/letsencrypt/live/www.example.com/fullchain.pem">
SSLEngine on
...
</IfFile>
This works because the IfFile
condition is evaluated at startup:
Encloses directives that will be processed only if file exists at startup
Whereas If
is evaluated at runtime:
Contains directives that apply only if a condition is satisfied by a request at runtime
Configuring the SSLEngine must be done at startup and cannot be done at runtime.
Quotes are from the Apache 2.4 Core Features docs.