ssl configuration for apache 2.4 on centos 7 with let’s encrypt

In follow-up to previous posts I’ve had about [[SSL]] (specifically with Let’s Encrypt), here is the set of {{SSL}} configurations I use with all my sites. These, if used correctly, should score you an “A+” with no warnings from ssllabs.com. Note: I have an improved entropy package installed (twuewand). This is adapted from the Mozilla config generator with specific options added for individual sites and/or to match Let’s Encrypt’s recommendations.

Please note: you will need to modify the config files to represent your own domains, if you choose to use these as models.

[/etc/httpd/conf.d/defaults.conf]

#SSL options for all sites
Listen 443
SSLPassPhraseDialog builtin
SSLSessionCache shmcb:/var/cache/mod_ssl/scache(512000)
SSLSessionCacheTimeout 300
Mutex sysvsem default
SSLRandomSeed startup builtin
SSLRandomSeed startup file:/dev/urandom 1024
# requires twuewand to be installed
SSLRandomSeed startup exec:/bin/twuewand 64
SSLRandomSeed connect builtin
SSLRandomSeed connect file:/dev/urandom 1024
SSLCryptoDevice builtin
# the SSLSessionTickets directive should work - but on Apache 2.4.6-45, it does not
#SSLSessionTickets off
SSLCompression off
SSLHonorCipherOrder on
# there may be an unusual use case for enabling TLS v1.1 or 1 - but I don't know what that would be
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
SSLOptions +StrictRequire
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)

#all unknown requests get domain.tld (over http)

DocumentRoot /var/html
ServerName domain.tld
ServerAlias domain.tld *.domain.tld
ErrorLog logs/rerss-error_log
CustomLog logs/rerss-access_log combined
ServerAdmin user@domain.tld

Options All +Indexes +FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all



[/etc/httpd/conf.d/z-[sub-]domain-tld.conf]
ServerName domain.tld
# could use * instead of www if you don't use subdomains for anything special/separate
ServerAlias domain.tld www.domain.tld
Redirect permanent / https://domain.tld/



SSLCertificateFile /etc/letsencrypt/live/domain.tld/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domain.tld/privkey.pem
# if you put "fullchain.pem" here, you will get an error from ssllabs
SSLCertificateChainFile /etc/letsencrypt/live/domain.tld/chain.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

# could put this in defaults.conf - I prefer it in each site config
SSLEngine on


SSLOptions +StdEnvVars


SSLOptions +StdEnvVars


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


Options All +Indexes +FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all

I use the z....conf formatting to ensure all site-specific configs are loaded after everything else. That conveniently breaks every site into its own config file, too.

The config file for a non-https site is much simpler:

DocumentRoot /var/www/domain
ServerName domain.tld
ServerAlias domain.tld *.domain.tld
ErrorLog logs/domain-error_log
CustomLog logs/domain-access_log combined
ServerAdmin user@domain.tld

Options All +Indexes +FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all

# enabling mod_gzip for non-ssl sites helps with seo and mobile optimization (https://varvy.com/pagespeed)

mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*

If you’re running something like Nextcloud, you may want to turn on Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains" in the <VirtualHost> directive for the site. I haven't decided yet if I should put this in every SSL-enabled site's configs or not.


Originally published at antipaucity.