Securing and optimizing SSL / SSL Tweaking
If you configure a web server’s TLS configuration, you have primarily to take care of the following things.
SSL Session Cache
Enable session cache:
ssl_session_cache shared:SSL:20m; ssl_session_timeout 10m;
Use only secure protocols
Use only secure protocols:
- disable SSL 2.0 (FUBAR) and SSL 3.01 (POODLE)
- disable TLS 1.0 compression (CRIME)
The SSL Cipher Suite
We need to choosing both secure and fast SSL Ciphers. The bible, specially on ciphers is this article - Hardening Your Web Server’s SSL Ciphers
- disable weak ciphers (DES, RC4)
- and prefer modern ciphers (AES), modes (GCM) and protocols (TLS 1.2).
On nginx, configuration will look like this:
ssl_prefer_server_ciphers on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
The cipher list is kind of long, but it will work on most older browsers, if you don’t need to think about IE 8 then you can use this short one:
# This was default on nginx ssl_ciphers HIGH:!aNULL:!MD5;
It means that you sent status info about your certificate along with the request, instead of making the browser check the certificate with the Certificate Authority. This removes a large portion of the SSL overhead.
In nginx, it’s should be easy. The following config uses Google’s DNS for resolving and assumes your certificate file contains the entire certificate chain.
# OCSP stapling # ssl_stapling on; ssl_stapling_verify on; # # Using Google DNS & OpenDNS resolver 188.8.131.52 184.108.40.206 220.127.116.11 18.104.22.168 valid=60s; resolver_timeout 2s;
If intermediate certificate is not already in
ssl_certificate, we must
ssl_trusted_certificate directive with file made up of your
intermediate certificate followed by root certificate.
Testing if it’s working:
echo QUIT | openssl s_client -connect hostingtipp.ch:443 -servername hostingtipp.ch -status 2> /dev/null | grep -A 17 'OCSP response:' | grep -B 17 'Next Update'
Note that we need to use OpenSSL’s
s_client directive for web servers
using Server Name Indication (SNI).
OCSP won’t be detected on first request. Simply put, nginx needs some time to fetch the OCSP response and cache it for all clients. After running the above OpenSSL command several times the test would show up successful. Additionally, the first request to a worker will never have an OCSP response stapled.
HTTP Strict Transport Security (HSTS)
HTTP Strict Transport Security (HSTS) will force the browser to load all subsequent requests from the same host over https, even when you’ve linked to http. So we just need to add and enable Strict Transport Security header.
In nginx, you add this like this:
# force every request after this to be over HTTPS add_header Strict-Transport-Security "max-age=31536000";
Sources & articles
SSL Performance Diary #1: The Certificate Chain SSL Performance Diary #2: HTTP Strict Transport Security SSL Performance Diary #3: Optimizing Data Encryption SSL Performance Diary #4: Optimizing the TLS Handshake
Still not fixed a
wich can be done by using
Fix POODLE exploit on every Plesk service including Parallels Plesk service, Apache, Postfix SMTP, Courier or Dovecot IMAP/POP3 server, ProFTPD server and of course nginx.
BEAST is purely a client-side vulnerability. BEAST has been mitigated by most browsers on the client side. The only major browser holding out has been Safari. Although I don’t believe that the problem is exploitable today
Sources & articles
If we already created our custom domain template:
nano /usr/local/psa/admin/conf/templates/custom/domain/nginxDomainVirtualHost.php nano /usr/local/psa/admin/conf/templates/custom/server/nginxVhosts.php # reconfigure domains plesk sbin httpdmng --reconfigure-domain hostingtipp.ch
Plesk custom domain templates
Create a new custom domain templates. Maybe you have them already, for some other purpose.
mkdir -p /usr/local/psa/admin/conf/templates/custom/ mkdir -p /usr/local/psa/admin/conf/templates/custom/server/ mkdir -p /usr/local/psa/admin/conf/templates/custom/domain/ cp /usr/local/psa/admin/conf/templates/default/domain/nginxDomainVirtualHost.php /usr/local/psa/admin/conf/templates/custom/domain/ cp /usr/local/psa/admin/conf/templates/default/server/nginxVhosts.php /usr/local/psa/admin/conf/templates/custom/server/
Plesk custom domain templates
sed -i 's/ssl_protocols SSLv2 SSLv3 TLSv1;/ssl_protocols TLSv1 TLSv1.1 TLSv1.2;/g' /usr/local/psa/admin/conf/templates/custom/nginxWebmailPartial.php sed -i 's/ssl_protocols SSLv2 SSLv3 TLSv1;/ssl_protocols TLSv1 TLSv1.1 TLSv1.2;/g' /usr/local/psa/admin/conf/templates/custom/domain/nginxDomainVirtualHost.php sed -i 's/ssl_protocols SSLv2 SSLv3 TLSv1;/ssl_protocols TLSv1 TLSv1.1 TLSv1.2;/g' /usr/local/psa/admin/conf/templates/custom/server/nginxVhosts.php
Using Plesk internal variables
There is a better way for disabling SSLv3, by using Plesk variable
How to set Plesk variable?
mysql -uadmin -p`cat /etc/psa/.psa.shadow` -Dpsa -e "insert into misc values('disablesslv3', 'true')" # reconfigure domains plesk sbin httpdmng --reconfigure-all # and check grep ssl_protocols /var/www/vhosts/system/*/conf/last_nginx.conf
When using this way, I try to minimize Sources:
At the end, this is the great setting:
# Speed up SSL handshake # # OCSP stapling, Using Google DNS & OpenDNS # ssl_stapling on; ssl_stapling_verify on; resolver 22.214.171.124 126.96.36.199 188.8.131.52 184.108.40.206 valid=60s; resolver_timeout 2s; # # SSL Session Cache ssl_session_cache shared:SSL:20m; ssl_session_timeout 10m; # # Use fastest ciphers: these shaved off 50ms # SSL Negotiation should be ~80ms, down from ~130ms ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK;