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

FREAK застал нас врасплох: отключаем EXPORT-шифры на nginx и Apache

CVE-2015-0204: атака деградации TLS до экспортных шифров 1990-х. Несколько серверов клиентов поддерживали EXPORT-наборы. Чистим конфиги nginx и Apache, проверяем балансировщики.

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

Уязвимость FREAK (CVE-2015-0204) - атака деградации TLS до экспортных шифров 1990-х на популярных серверах

Про FREAK написали все, кто пишет про безопасность. Мы же столкнулись с ним не как читатели новостей, а как люди, которые в тот же день пошли смотреть конфиги своих клиентов - и нашли неприятное.

Что за зверь

FREAK (CVE-2015-0204) - это атака на TLS, которая заставляет сервер и клиент согласовать так называемые EXPORT-шифры: слабые ключи RSA длиной 512 бит, которые существовали потому, что в 1990-х американское законодательство запрещало экспорт стойкой криптографии. Ключ 512 бит факторизуется за несколько часов на нормальном железе. То есть атакующий с позиции man-in-the-middle может договориться с сервером об EXPORT-режиме, разложить ключ, и дальше читает трафик.

Казалось бы - кто вообще включает EXPORT-шифры на нормальном продакшн-сервере? Никто специально не включает. Проблема в том, что в ряде дистрибутивов и версий OpenSSL они были активны по умолчанию, если явно не выключить. И люди не выключали - потому что не знали, что они вообще есть.

Что мы нашли

Мы провели аудит нескольких серверов клиентов - проверили список согласуемых шифров через openssl s_client и nmap --script ssl-enum-ciphers. Результат оказался хуже, чем ожидали.

Несколько web-серверов поддерживали EXPORT-наборы. Не какие-то древние машины, поднятые в начале нулевых, - вполне живые nginx и Apache на CentOS 6 и Ubuntu 12.04 с относительно свежими пакетами. Конфиги TLS там либо были дефолтными, либо настраивались давно и по принципу «работает - не трогай».

Отдельная история - балансировщики. У двух клиентов HAProxy сидел перед несколькими backend-серверами, и TLS терминировался на нём. В конфигах HAProxy явного запрета EXPORT не было. Один клиент использовал stunnel как обёртку - там тоже пришлось смотреть.

Как чинили

Принцип один: явно задавать список допустимых шифров, не полагаясь на умолчания.

nginx. В блоке server или http добавляем ssl_ciphers с явным списком. Мы пользуемся рекомендациями Mozilla SSL Configuration Generator - на тот момент «intermediate» профиль выглядел примерно так:

ssl_protocols TLSv1 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_ciphers - это !EXPORT, !DES, !RC4, !3DES. Восклицательный знак означает явное исключение. Без них слабые шифры могут просочиться через групповые псевдонимы вроде ALL или HIGH.

Apache. Аналогично, в httpd.conf или в виртуальном хосте:

SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:...!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK
SSLHonorCipherOrder on

HAProxy. Версия 1.5+ умеет TLS через встроенный OpenSSL. Директива ssl-default-bind-ciphers задаётся глобально и применяется ко всем bind с ssl:

global
    ssl-default-bind-ciphers ECDHE+AESGCM:DHE+AESGCM:ECDHE+AES:DHE+AES:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES
    ssl-default-bind-options no-sslv3

stunnel. В stunnel.conf добавляем:

ciphers = HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5

После каждого изменения - перезагрузка сервиса и проверка через openssl s_client -connect host:443 -cipher EXPORT или nmap. Если сервер возвращает ошибку handshake на EXPORT-запрос - хорошо, шифры закрыты.

Где проверять

Есть онлайн-инструмент Qualys SSL Labs (ssllabs.com/ssltest) - он показывает все согласуемые шифры, протоколы и отдельно предупреждает про EXPORT. Не самый быстрый, зато полный. Для регулярных проверок удобнее держать testssl.sh локально - bash-скрипт, без внешних зависимостей, гоняет проверки с нескольких IP.

Что это говорит про процесс

Неприятная часть истории не в самой FREAK - там фикс несложный. Неприятно другое: EXPORT-шифры существовали в этих конфигах, вероятно, годами. Никто их не добавлял специально - они просто были, и никто не смотрел.

Это системная история: конфиг TLS настраивается один раз при запуске сервиса и потом не пересматривается, если всё «работает». Между тем криптографические рекомендации меняются, выходят новые CVE, появляются новые атаки. То, что было разумным выбором два года назад, сегодня может оказаться дырой.

Вывод, который мы для себя сделали: TLS-конфиги нужно включать в периодическую проверку инфраструктуры - хотя бы раз в полгода прогонять testssl.sh по всем публичным endpoint-ам и сверять с текущими рекомендациями. Не как реакция на очередную CVE с красивым именем, а как рутина.

Контакт

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

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