NGINX и SSL: Получаем четыре сотни и А+ на SSLLabs.com

Собственно сразу перейдем к делу

Цель -- А+ на SSLLabs, а в идеале вообще все четыре результата по сто баллов. Оценка выводится на основе четырех шкал:

  1. Certificate
  2. Protocol Support
  3. Key Exchange
  4. Cipher Strength

Первый пункт, насколько мне известно, просто предполалагает наличие подлинного сертификата от известного CA.

Для второго пункта достаточно отключить все протоколы, кроме TLSv1.2. Другими словами пишем это:

ssl_protocols TLSv1.2;

Для выполнения третьего пункта достаточно получить 4096-битный сертификат. Я использую сертификаты от Let's Encrypt, поэтому в моём случае это выглядит так:

sudo letsencrypt certonly --standalone --email savely@krasovsky.me -d domain.xyz --rsa-key-size 4096

С четвертым пунктом интереснее. Я очень долго пытался найти шифры, с котороми бы удалось набрать 100 баллов. И нашел:

ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!AES128';

SSLLabs предполагает, что мы должный отказаться от AES128, чтобы получить максимальный балл. Помимо этого, нужно также создать на сервере 4096-битный DH-ключ. Для ускорения процесса получения, можно использовать такую команду:

sudo openssl dhparam -dsaparam -out /etc/letsencrypt/live/domain.xyz/dhparam.pem 4096

Исключая шифры AES128, протоколы TLSv1.0 и TLSv1.1 вы стреляете себе в ногу!

Так как отрезаете добрую половину юзеров. Не будут работать очень многие браузеры, а со смартфонами совсем беда. Таким образом гораздо лучше использовать это:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

Безопасность при этом практически не падает, мы всё также будем получать A+.

В итоге, вместо 100-100-100-100, я получил 100-95-100-90. Но при этом 99% устройств будут работать с вашим сайтом. Исключением будут лишь древний Internet Explorer на Windows XP, а также Android 2.3.7. Результат считаю отличным.

Саму конфигурацию я разбил на две части. Большую часть настроек я прописал в основном конфиге, тогда как сами сертификаты, а также HSTS, я прописываю в конфиге виртуального хоста.

В /etc/nginx/nginx.conf:

##
# SSL Settings
##
  
# Оптимальный список поддерживаемых протоколов и шифров
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
  
# Если хотите поэксперементировать и получить 100-100-100-100
#ssl_protocols TLSv1.2;
#ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!AES128';
  
# В приоритете шифры сервера, а не браузера
ssl_prefer_server_ciphers on;
  
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
  
ssl_ecdh_curve secp384r1;
  
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;

Теперь в /etc/nginx/sites-available/domain.xyz.conf:

ssl on;
  
# Эти три мы можем прописать сразу после получения сертификата у Let's Encrypt
ssl_certificate /etc/letsencrypt/live/domain.xyz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.xyz/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/domain.xyz/fullchain.pem;
  
# Этот нужно предварительно сгенерировать
ssl_dhparam /etc/letsencrypt/live/domain.xyz/dhparam.pem;
  
# Header for HSTS support
add_header Strict-Transport-Security 'max-age=631138519; includeSubDomains; preload' always;