NSA Proof Your Apache Configuration
Between Heartbleed (CVE-2014-0160) and Edward Snowden the last eleven months have created quite a stir in realm of Information Security; especially when it comes to SSL. In the wake of Heartbleed I thought I would share my Apache configuration and provide some tips on preventing Heartbleed as well as implementing anti-NSA best practices.
First things first, fix the Heartbleed bug. This should be pretty simple, just make sure your running a patched version of OpenSSL. I run jasonsnider.com on Ubuntu 13.10 so this was simple as running the latest updates.
apt-get update
apt-get upgrade
QualSys SSL Labs offers an in-depth analysis of your SSL certificate. Currently my position is that if your pulling an A or an A+ on this site then you have diligently implemented anti-NSA best practices. So head over there and enter your domain name. If you are vulnerable to Heartbleed you will fail the test with a Heartbleed warning and you will want to install the latest version of OpenSSL.
Once the Heartbleed vulnerability has been patched, you’ll want harden your SSL configuration. Using a RapidSSL certificate on a server running Ubuntu 13.10 and Apache 2.4.6 I was already pulling an A-. All I really needed to do was implement Perfect Forward Secrecy (PFS) to boost my grade to an A. However, a review of the analysis showed a few other things I could improve. These improvements include mitigating BEAST, hardening HTTP Strict Transport Security (HSTS) and implementing Perfect Forward Secrecy (PFS). These are all fairly easy improvements to make; nothing more than a line or two in your server’s configuration.
Mitigate BEAST
While BEAST has arguably been mitigated by major browser vendors, the server side patch is trivial, so why not implement it. BEAST is easily mitigated by simply shutting down support for SSL v2.
SSLProtocol all -SSLv2
Implement HSTS
HTTP Strict Transport Security HSTS is simply denying your server the ability to make HTTP requests. There are a few ways to do this. The first is to simply not have a virtual host running over port 80. Which would typically be any Apache configuration beginning with the likes of <VirtualHost *:80>
. The second is the more SEO/user friendly approach of using mod_rewrite to redirect all insecure requests to secure requests and the third is to apply theStrict-Transport-Security
header to all requests coming in over http. My approach is to start of with a mod_rewrite and then use the Strict-Transport-Security header as a fall back. Here is my HSTS Strategy for jasonsnider.com.
<VirtualHost 162.243.75.115:80>
ServerAdmin xxx@xxx.xxx
ServerName jasonsnider.com
# HTTP Strict Transport Security (HSTS) Strategy
# Force SSL using mode-rewrite
# Enable mod-rewrite
# Force http to https
RewriteEngine On
RewriteRule ^(.\*)$ https://jasonsnider.com$1 \[R=301,L\]
# If the rewirte condition fails this will kill the insecure connection
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</VirtualHost>
Implement PFS
Using Ubuntu >=13.10 and Apache >= 2.4 implementing perfect forward secrecy (PFS) in another trivial task. All you need to do dissallow non-compliant ciphers and force the browser to honor your cipher order.
SSLCipherSuite EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS
SSLHonorCipherOrder on
Putting it all Together
This is the actual configuration file for jasonsnider.com.
The configuration below is derived from multiple sources including
- Default Apache2 Config files
- HTML5 Boilerplate
- Trial and Error
<VirtualHost 162.243.75.115:80>
ServerAdmin xxx@xxx.xxx
ServerName jasonsnider.com
# HTTP Strict Transport Security (HSTS) Strategy
# Force SSL using mode-rewrite
# Enable mod-rewrite
# Force http to https
RewriteEngine On
RewriteRule ^(.\*)$ https://jasonsnider.com$1 \[R=301,L\]
# If the rewirte condition fails this will kill the insecure connection
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</VirtualHost>
<VirtualHost 162.243.75.115:443>
# Enable mod-rewrite
RewriteEngine On
# Imporve SEO by rewriting www.jasonsnider.com to jasonsnider.com
RewriteCond %{HTTP\_HOST} ^www\\.(.+)$ \[NC\]
RewriteRule ^(.\*)$ https://jasonsnider.com$1 \[R=301,L\]
ServerAdmin xxx@xxx.xxx
ServerName jasonsnider.com
DocumentRoot /var/www/jasonsnider.com/app/webroot
<Directory /var/www/jasonsnider.com/app/webroot>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
</Directory>
ErrorLog ${APACHE\_LOG\_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE\_LOG\_DIR}/ssl\_access.log combined
Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
# Mitigate BEAST
SSLProtocol all -SSLv2
# Enable PFS
SSLCipherSuite EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS
SSLHonorCipherOrder on
# Point to SSL Certificates
SSLCertificateFile /etc/apache2/ssl/CSSL635327486032376577/ServerCertificate.cer
SSLCertificateKeyFile /etc/apache2/ssl/jasonsnider.com.key
SSLCACertificateFile /etc/apache2/ssl/CSSL635327486032376577/CACertificate-1.cer
# SSL Engine Options: \[...\]
<FilesMatch "\\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
# SSL Protocol Adjustments: \[...\]
BrowserMatch "MSIE \[2-6\]" \\
nokeepalive ssl-unclean-shutdown \\
downgrade-1.0 force-response-1.0
# MSIE 7 and newer should be able to use keepalive
BrowserMatch "MSIE \[17-9\]" ssl-unclean-shutdown
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
More Reading
- https://community.qualys.com/blogs/securitylabs/2013/09/10/is-beast-still-a-threat
- https://community.qualys.com/blogs/securitylabs/2013/09/10/is-beast-still-a-threat
- http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
- https://community.qualys.com/blogs/securitylabs/2013/08/05/configuring-apache-nginx-and-openssl-for-forward-secrecy
- http://vincent.bernat.im/en/blog/2011-ssl-perfect-forward-secrecy.html
- https://willnorris.com/2013/11/improving-my-https-support
- http://ivoras.net/blog/tree/2013-10-21.apache-2.2-and-perfect-forward-secrecy-pfs.html