antipaucity

fighting the lack of good ideas

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)
<VirtualHost *:80>
    DocumentRoot /var/html
    ServerName domain.tld
    ServerAlias domain.tld *.domain.tld
    ErrorLog logs/domain-error_log
    CustomLog logs/domain-access_log combined
    ServerAdmin user@domain.tld
    <Directory "/var/html">
         Options All +Indexes +FollowSymLinks
         AllowOverride All
         Order allow,deny
         Allow from all
    </Directory>
</VirtualHost>

SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript text/css text/php

[/etc/httpd/conf.d/z-[sub-]domain-tld.conf]

<Virtualhost *:80>
    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/
</VirtualHost>

<VirtualHost *:443>
    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

<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>

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:

<VirtualHost *:80>
    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
    <Directory "/var/www/domain">
         Options All +Indexes +FollowSymLinks
         AllowOverride All
         Order allow,deny
         Allow from all
    </Directory>
</VirtualHost>

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&gt directive for the site. I haven’t decided yet if I should put this in every SSL-enabled site’s configs or not.

putting owncloud 8 on a subdomain instead of a subdirectory on centos 7

After moving to a new server, I wanted to finally get ownCloud up and running (over SSL, of course) on it.

And I like subdomains for different services, so I wanted to put it at sub.domain.tld. This turns out to be not as straight-forward as one might otherwise hope, sadly – ownCloud expects to be installed to domain.tld/owncloud (and plops itself into /var/www/owncloud by default (or sometimes /var/www/html/owncloud).

My server is running CentOS 7, Apache 2.4, and MariaDB (a drop-in replacement for MySQL). This overview is going to presume you’re running the same configuration – feel free to spin one up quickly at Digital Ocean to try this yourself.

Start with the ownCloud installation instructions, which will point you to the openSUSE build service page, where you’ll follow the steps to add the ownCloud community repo to your yum repo list, and install ownCloud. (In my last how-to, 8.0 was current – 8.2 rolled-out since I installed 8.1 a couple days ago.)

Here is where you need to go “off the reservation” to get it ready to actually install.

Add a VirtualHost directive to redirect http://sub.domain.tld to https://sub.domain.tld (cipher suite list compiled thusly):


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

Configure an SSL VirtualHost directive to listen for sub.domain.tld:


<VirtualHost *:443>
SSLCertificateFile /etc/letsencrypt/live/sub.domain.tld/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/sub.domain.tld/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/sub.domain.tld/fullchain.pem
DocumentRoot /var/www/subdomain
ServerName sub.domain.tld
ErrorLog logs/subdomain-error_log
CustomLog logs/subdomain-access_log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
ServerAdmin user@domain.tld
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
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
SSLHonorCipherOrder on
SSLOptions +StdEnvVars
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
# allow .htaccess to change things
<Directory "/var/www/subdomain">
Options All +Indexes +FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

Comment-out every line in (or remove) /etc/httpd/conf.d/owncloud.conf.

Move /var/www/html/owncloud/* to /var/www/subdomain.

Make sure permissions are correct on /var/www/subdomain:

  • chown -R :apache /var/www/subdomain

Run the command-line installer: /var/www/subdomain/occ maintenance:install

Fix ownership of the config file, /var/www/subdomain/config/config.php to root:apache.

In config.php,

  • change trusted domains from ‘localhost‘ to ‘sub.domain.tld
  • make sure ‘datadirectory‘ is equal to /var/www/subdomain/data
  • change ‘overwrite.cli.url‘ from ‘localhost‘ to ‘https://sub.domain.tld

Navigate to http://sub.domain.tld, and follow the prompts – and you should be a happy camper.

reverse proxying from apache to tomcat

After much hemming and hawing, I was able to get Apache working as a reverse proxy to Tomcat today.

<VirtualHost *:80>
    ServerName domain.com
    ServerAlias www.domain.com
    ProxyPreserveHost on
    ProxyPass / http://localhost:8080/path/
    ProxyPassReverse / http://domain.com:8080/path/
</VirtualHost>

That’s all you need (though you can add much more). Note the trailing slashes on the proxy paths – without them, you have no dice.