ADG Оставить заявку
Блог Информационная безопасность 4 мин чтения

SSL-аудит nginx после Heartbleed: от B до A минимальными правками

Прогнали клиентские nginx-серверы через ssllabs.com - большинство получили B из-за TLSv1.0 и слабых шифров. Разбираем минимальный набор директив для оценки A.

Контекст момента

После Heartbleed в апреле 2014 сообщество продолжает аудит SSL/TLS-конфигураций веб-серверов; в рамках аудита клиентских серверов большинство nginx-инстансов получили оценку B из-за включённого TLSv1.0 и слабых шифров

После Heartbleed в апреле всем стало чуть неловко за то, как давно они последний раз смотрели на SSL-конфигурацию своих серверов. Мы не исключение. Поводом для систематического прохода по клиентским серверам стала просьба одного из клиентов - он прочитал про уязвимость, обновил OpenSSL, и на этом остановился. Мы договорились сделать полный аудит безопасности - и заодно прогнали через него всех остальных.

Инструмент - ssllabs.com/ssltest. Бесплатный, публичный, даёт подробный разбор: протоколы, шифры, цепочка сертификатов, forward secrecy, уязвимости. На выходе оценка от A+ до F. Ожидали разброс - получили унылое однообразие: большинство серверов дали B.

Почему B, а не хуже

Оценка B - это не катастрофа, но сигнал. У Qualys чёткая логика: B значит, что конфигурация в целом нормальная, но есть что-то, что тянет вниз. В нашем случае везде было одно и то же:

  • TLSv1.0 включён - протокол 1999 года, к которому уже есть атаки (BEAST, в частности). Qualys снижает оценку за его поддержку.
  • Слабые шифры в наборе - RC4 и шифры без PFS (perfect forward secrecy). RC4 в 2014 году всё ещё часто встречается в дефолтных nginx-конфигах, но атаки на него накопились.
  • Цепочка сертификатов не передаётся полностью - браузеры справляются, но это замечание и потеря баллов.

Всё это наследие того, что конфигурации ставились давно по документации «лишь бы работал HTTPS», и никто их не трогал.

Минимальный набор директив

Минимальные изменения, которые поднимают оценку с B до A на большинстве серверов с nginx 1.4-1.6:

ssl_protocols TLSv1.1 TLSv1.2;

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

ssl_prefer_server_ciphers on;

ssl_session_cache    shared:SSL:10m;
ssl_session_timeout  10m;

Плюс для ECDHE нужен DH-параметр - без него Diffie-Hellman работает на дефолтных 1024-битных параметрах, что тоже тянет оценку вниз:

openssl dhparam -out /etc/nginx/dhparam.pem 2048

И в конфиг:

ssl_dhparam /etc/nginx/dhparam.pem;

Генерация 2048-битного dhparam занимает несколько минут - нормально, это разовая операция.

Что решили не включать

HSTS (add_header Strict-Transport-Security) - не добавляли по умолчанию. Причина простая: если сертификат истечёт или сломается переход на HTTPS - сайт станет недоступен для браузера без ручного вмешательства пользователя. Для клиентов, где HTTPS обязателен и процедура обновления сертификатов отлажена - добавили. Там, где HTTP и HTTPS работают параллельно или бывают тестовые домены - не стали рисковать.

OCSP Stapling (ssl_stapling on) - включили тем, у кого правильно передаётся цепочка сертификатов. Это ускоряет TLS-рукопожатие и убирает замечание от ssllabs, но требует, чтобы nginx мог достучаться до OCSP-сервера удостоверяющего центра. На серверах с файрволом, режущим исходящие соединения, проверяем отдельно.

Совместимость

Исключение TLSv1.0 ломает поддержку IE6 на Windows XP. В 2014 году это звучит как не очень страшно, но на практике у нескольких клиентов доля XP в аналитике была ненулевой. Проверяли заранее - для двух клиентов отложили отключение TLSv1.0 до согласования с ними.

RC4 используется некоторыми старыми Android-устройствами (2.x) как запасной шифр. При наличии ECDHE и AES-GCM в наборе устройства с Android 4+ подключаются нормально. Android 2.x при таком наборе может упасть. Опять же - смотрели на аналитику.

Итог прохода

После правок все серверы, где не было явных ограничений по совместимости, получили A. Несколько серверов остались на B - это осознанное решение по согласованию с клиентами, а не просчёт. Разница между «мы не проверяли» и «мы проверили и решили не менять» - принципиальная.

Конфигурация шифров выше основана на рекомендациях Mozilla Server Side TLS Guide - публичный документ, который регулярно обновляется и объясняет логику каждого шифра. Рекомендуем держать его в закладках и сверяться при обновлении nginx или смене сертификатного центра.

Один нюанс, который вылез в процессе: ssllabs кеширует результаты несколько часов. После изменения конфига - перезапуска nginx недостаточно, нужно подождать или добавить &startNew=on к URL теста. Потратили на это чуть больше времени, чем следовало.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.