ssl_protocols (версии TLS в nginx)
ssl_protocols это директива nginx, которая задаёт, какие версии протоколов SSL и TLS сервер согласует с клиентами. По текущей документации nginx значение по умолчанию TLSv1.2 TLSv1.3, а RFC 8996 запрещает TLS 1.0 и 1.1. Её задают в контексте http или server, чтобы устаревшие версии оставались выключенными, а современные браузеры подключались без проблем.
Синтаксис, допустимые значения и значения по умолчанию
Директива входит в ngx_http_ssl_module и допустима в контекстах http и server:
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3];
По документации значение по умолчанию ssl_protocols TLSv1.2 TLSv1.3;. Там же сказано, что TLSv1.3 входит в значение по умолчанию начиная с nginx 1.23.4, поэтому сервер на старой сборке или со старым конфигом может вести себя иначе. Параметры зависят и от библиотеки OpenSSL: для TLSv1.1 и TLSv1.2 нужен OpenSSL 1.0.1 или новее, а для TLSv1.3 (nginx 1.13.0 и новее) нужен OpenSSL 1.1.1 или новее. Какую библиотеку использует ваша сборка, покажет nginx -V.
Синтаксис по-прежнему принимает SSLv2, SSLv3, TLSv1 и TLSv1.1, но включать их незачем. RFC 8996 прямо говорит: TLS 1.0 MUST NOT be used и TLS 1.1 MUST NOT be used, то есть их применять нельзя.
Минимальная конфигурация и проверка
Если перечислить версии явно, политика видна в конфиге и не зависит от значения по умолчанию, которое менялось между релизами:
server {
listen 443 ssl;
server_name example.com;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_certificate /etc/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/example.com/privkey.pem;
}
Проверьте синтаксис, примените настройки и посмотрите с другой машины, что согласуется:
sudo nginx -t && sudo systemctl reload nginx
openssl s_client -connect example.com:443 -servername example.com -tls1_3 -brief </dev/null
openssl s_client -connect example.com:443 -servername example.com -tls1_2 -brief </dev/null
nmap --script ssl-enum-ciphers -p 443 example.com
Две команды s_client подтверждают, что разрешённые версии работают. Чтобы доказать, что старые версии отклоняются, используйте скрипт nmap: современный клиент OpenSSL может сам отказаться говорить по TLS 1.1, и его ошибка ничего не скажет о вашем сервере. Запускайте nmap только против своих серверов. А чтобы заранее узнать, кого заденет отключение версии, пишите переменную $ssl_protocol в формат access-лога.
Подводные камни: сервер по умолчанию, шифры и старые клиенты
Место директивы важно. Рукопожатие происходит раньше, чем nginx прочитает заголовок Host, поэтому, как предупреждает документация, значение на уровне server может быть взято у сервера по умолчанию для того же адреса и порта. Задавайте ssl_protocols в блоке http или следите, чтобы все серверы на общем listen имели одинаковое значение. Чтобы вообще отклонять рукопожатия для неизвестных имён, в nginx 1.19.4 появилась ssl_reject_handshake on; для запасного сервера по умолчанию.
ssl_protocols и ssl_ciphers это разные настройки. У второй значение по умолчанию HIGH:!aNULL:!MD5, а по руководству OpenSSL по ciphers строка списка шифров относится к TLS 1.2 и ниже, тогда как наборы TLS 1.3 задаются отдельно (в nginx через ssl_conf_command, доступную с 1.19.4). Разрешив версию, вы ещё не выбрали для неё стойкие шифры.
- Отключение TLS 1.0 и 1.1 ломает только очень старые клиенты, которым по RFC 8996 и так не следует работать по этим версиям.
- После изменения директивы нужен reload, одного обновления сертификата мало.
Место в укреплении сервера
Ограничение версий протокола это одна строка в более широком TLS-минимуме: корректная цепочка сертификатов, разумные шифры, защитные HTTP-заголовки и продление, после которого nginx действительно перечитывает конфигурацию. Руководство по безопасности nginx показывает полный TLS-блок в контексте, а страница TLS / SSL объясняет, почему название «SSL» живёт, хотя сам протокол давно устарел.
С эксплуатационной точки зрения относитесь к директиве как к любой настройке безопасности. Храните её в системе контроля версий, перед каждым reload запускайте nginx -t и перепроверяйте снаружи после каждого обновления nginx или OpenSSL, потому что значения по умолчанию могут меняться между релизами. Короткие сроки жизни сертификатов делают автоматический reload ещё важнее, об этом рассказывает статья про 45-дневные сертификаты. Соседние меры перечислены в чек-листе безопасности VPS.
Сканирование версий TLS это снимок на момент проверки. Запускайте его по расписанию, чтобы регресс после правки конфигурации заметили за дни, а не за месяцы.
Связанные термины: TLS / SSL, nginx, Защитные заголовки, server_tokens, limit_req.
Часто задаваемые вопросы
Какое значение ssl_protocols в nginx по умолчанию?
В документации nginx по умолчанию указано ssl_protocols TLSv1.2 TLSv1.3; и отмечено, что TLSv1.3 входит в него с версии 1.23.4. Явная настройка убережёт от сюрпризов между версиями.
Нужно ли отключать TLS 1.0 и TLS 1.1 в nginx?
Да. RFC 8996 устанавливает, что TLS 1.0 и TLS 1.1 использовать нельзя, поэтому не включайте их в ssl_protocols.
Включает ли ssl_protocols TLS 1.3?
Только если nginx собран с OpenSSL 1.1.1 или новее и TLSv1.3 есть в списке или в значении по умолчанию. Библиотеку проверьте командой nginx -V.
Выбирает ли ssl_protocols наборы шифров?
Нет. Списком шифров TLS 1.2 и старше управляет ssl_ciphers, а наборы TLS 1.3 настраиваются отдельно, например через ssl_conf_command.
Почему изменение ssl_protocols не подействовало на один виртуальный хост?
Рукопожатие идёт до того, как nginx узнает запрошенное имя, поэтому может применяться значение сервера по умолчанию для этого адреса и порта. Задайте директиву в блоке http или держите одинаковой у всех серверов на одном listen.
Хотите увидеть, в каком состоянии ваш сервер?
Запустите бесплатную read-only проверку сервера или откройте Security Lab и посмотрите цикл обнаружение, сдерживание, восстановление, проверка в действии.
Получить бесплатную проверку сервераОткрыть Security Lab