Encryption and security is a must-have these days. The more secure, the better. A good start is to have a solid ssl configuration on your webserver. With ssllabs you can test your webserver's ssl configuration and its certificates.
As of today, the following apache httpd config snippets may give you an A+ rating, if your SSL certificate is valid, trusted, has a key size of at least 2048 bits and it's hash algorithm is sha2/sha256.
SSLv2 and SSLv3 are considered insecure and should be disabled:
SSLProtocol all -SSLv2 -SSLv3
This cipher list suits all modern browsers and operating systems, only leaving IE6/XP behind (who needs that anyway?). ECDSA ciphers are only relevant for ECDSA certificates. As far as I know only very few certificate authorities provide ECDSA, while RSA is common. Since POODLE does not affect TLS (yet), it is assumed safe to allow CBC ciphers for TLSv1.
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:
ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:
ECDH-RSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:
ECDH-RSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA
Modern browsers support (at least) the elliptic curves secp256r1, secp384r1 and secp521r1. To force stronger curves, use the following directive:
SSLOpenSSLConfCmd Curves secp521r1:secp384r1
I recommend using the cipher list and curves for mail, vpn, ldap and other servers/services, too.
To prevent the CRIME attack, disable SSL compression. Which is the default behaviour.
SSLCompression off
To prevent downgrade attacks (i.e. switching from https to http), you should add HSTS headers with a long duration. If your hostname has subdomains (e.g. foo.www.unixadm.org) you should add includeSubDomains
. You might want to add your HSTS policy to a central database browsers like Firefox, Chrome and IE use. In that case, you must add preload
to the header.
<IfModule headers_module>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>
You can make man in the middle attacks more difficult by providing a list of your certificate's / private key's fingerprints using an HPKP header. Keep in mind the first access to your webserver is still "unprotected", as at this point the HPKP header is not known the client yet. You should always include a backup key in case your current private key gets compromised.
get the fingerprint from your certificate:
$ openssl x509 -pubkey -noout -in certfile.pem | sed '1d;$d' | base64 -d | openssl dgst -sha256 -binary | base64
get the fingerprint from your private key:
$ openssl pkey -pubout -in keyfile.key | sed '1d;$d' | base64 -d | openssl dgst -sha256 -binary | base64
and finally add the header:
<IfModule headers_module>
Header always set Public-Key-Pins "max-age=86400; pin-sha256=\"current_fingerprint=\";pin-sha256=\"backup_fingerprint\";"
</IfModule>
To show that your certificate was not revoked, you may want to use OCSP stapling to add a timstamped OCSP response to your certificate. The validity duration depends on the certificate authority, StartCom has switched from one day to five days a few months ago.
<IfModule socache_shmcb_module>
SSLUseStapling On
SSLStaplingCache shmcb:/var/cache/httpd/ssl/ssl_stapling(512000)
SSLStaplingStandardCacheTimeout 21600
SSLStaplingErrorCacheTimeout 600
SSLStaplingResponseMaxAge 432000 # 5 days
SSLStaplingResponderTimeout 10
SSLStaplingReturnResponderErrors Off
</IfModule>
To prevent clickjacking, set the SAMEORIGIN
policy.
<IfModule headers_module>
Header always append X-Frame-Options SAMEORIGIN
</IfModule>
Avoid falsely detected MIME types and thus execution of malicious code by disabling MIME-sniffing for the IE:
<IfModule headers_module>
Header always append X-Content-Type-Options nosniff
</IfModule>
To set the browser's built-in reflective XSS protection use the following line. mode=block
is recommended, not setting it will result in the browser sanitising the script instead of blocking it.
<IfModule headers_module>
Header always set X-Xss-Protection "1; mode=block"
</IfModule>
Content-Security is a bigger chapter. You'll need to find all scripts, css, images, fonts, etc. your website uses, either loaded from your domain, externally, or used inline, and specify which sources are valid for them. See this website's header for example. The most basic and most secure setting is the following. But it probably will fsck up your website. See this site for a very good reference about Content-Security-Policy.
<IfModule headers_module>
Header always set Content-Security-Policy "default-src 'none'"
</IfModule>
Prevent client side scripts accessing the protected cookie:
<IfModule headers_module>
Header always edit Set-Cookie "(?i)^((?:(?!;\s?HttpOnly).)+)$" "$1; HttpOnly"
</IfModule>
And secure the cookies by using SSL:
<IfModule ssl_module>
<IfModule headers_module>
Header always edit Set-Cookie "(?i)^((?:(?!;\s?secure).)+)$" "$1; Secure"
</IfModule>
</IfModule>