SSL/TLS · 3 min read · Oct 12, 2025

Реализация идеальной секретности при пересылке SSL в веб-сервере NGINX

Этот HOW-TO описывает процесс реализации идеальной секретности при пересылке с веб-сервером NGINX на системах Debian и Ubuntu. Процесс можно легко адаптировать для других систем GNU/Linux.

Кратко, идеальная секретность при пересылке гарантирует: “… что компрометация одного сообщения не может привести к компрометации других, и также что нет единственного секретного значения, которое может привести к компрометации нескольких сообщений.” Для получения дополнительной информации смотрите http://en.wikipedia.org/wiki/Forward_secrecy#Perfect_forward_secrecy.

Когда уязвимость Heartbleed в OpenSSL была раскрыта в начале 2014 года, стало все более очевидно, что PFS является необходимостью для любой системы, использующей SSL/TLS в серьезных целях.

Если вы хотите сравнить свои результаты с моими, моя эталонная реализация может быть протестирована на https://www.ssllabs.com/ssltest/analyze.html?d=indietorrent.org, а цепочку SSL-сертификатов и заголовки NGINX, которые отправляются, можно просмотреть на https://indietorrent.org.

Без лишних слов, давайте настроим NGINX для реализации PFS.

Перейдем в каталог конфигурации NGINX:

cd /etc/nginx/

Нам нужно сгенерировать параметры Диффи-Хеллмана, которые достаточно сильны. Некоторые утверждают, что 4096 бит — это избыточно и создаст ненужную нагрузку на процессор системы, но с современными вычислительными мощностями это кажется разумным компромиссом. Для получения дополнительной информации смотрите раздел Ссылки ниже.

openssl dhparam -out dh4096.pem 4096

Удобно иметь этот файл конфигурации, который специфичен для данной задачи, в отдельном файле включения; это упрощает реализацию PFS на большом количестве систем.

vi /etc/nginx/perfect-forward-secrecy.conf

Вставьте следующее в указанный файл:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 \
EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 \
EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !MEDIUM";
ssl_dhparam dh4096.pem;

Измените конфигурацию NGINX, чтобы включить указанный файл, вставив следующую строку в основной конфигурационный файл NGINX (по умолчанию /etc/nginx/nginx.conf), внизу (и внутри) блока http {}:

# См.: https://community.qualys.com/blogs/securitylabs/2013/08/05/configuring-apache-nginx-and-openssl-for-forward-secrecy
# Это ДОЛЖНО идти ПОСЛЕ строк, которые включают .../sites-enabled/*, в противном случае поддержка SSLv3 может быть случайно повторно включена.
include perfect-forward-secrecy.conf;

Перезапустите NGINX, чтобы изменения вступили в силу:

service nginx restart

Если тест на https://www.ssllabs.com/ssltest/analyze.html отображает “Возобновление сеанса (кэширование) Нет (идентификаторы назначены, но не приняты)” красным цветом, и сервер реализует SNI, добавьте следующее в верхний уровень блока http {} (т.е. добавьте в nginx.conf, сразу под тем местом, где мы сделали предыдущие добавления):

# См.: http://forum.nginx.org/read.php?2,152294,152401#msg-152401
ssl_session_cache shared:SSL:10m;

Снова перезапустите NGINX, чтобы изменения вступили в силу:

service nginx restart

Вышеуказанный тест больше не должен сообщать об этой проблеме (даже если проблема не снижает общий балл теста).

Дальнейшие шаги: Реализация строгой транспортной безопасности HTTP (HSTS) с длительным сроком

Это просто, и стоит сделать, при условии, что:

  1. Вы хотите принудительно использовать SSL для всех ресурсов для любого хоста, для которого этот заголовок установлен (т.е. для каждой страницы на рассматриваемом веб-сайте).
  2. Вы можете смириться с тем, что не сможете принимать и игнорировать предупреждения SSL для любого ресурса, запрашиваемого с любого хоста, для которого этот заголовок установлен, такие как “Несоответствие доменного имени” и т.д. Само по себе HSTS подразумевает, что предупреждения и ошибки, связанные с SSL-сертификатом, не могут быть переопределены.

Я искал информацию в Интернете о том, может ли установка этого заголовка иметь непредвиденные последствия в браузерах, которые не поддерживают заголовок, и не нашел ничего. Но я смог развеять свои опасения, протестировав эту реализацию в Internet Explorer 6, например, и браузеры, в которых HSTS не реализован, просто игнорируют заголовок. Отлично!

Просто добавьте следующие строки в конец /etc/nginx/perfect-forward-secrecy.conf и сохраните изменения:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
# Это предотвратит определенные атаки click-jacking, но предотвратит
# другие сайты от фрейминга вашего сайта, поэтому удалите или измените по мере необходимости!
add_header X-Frame-Options SAMEORIGIN;

Перезагрузка (вместо перезапуска) будет достаточной для того, чтобы заставить NGINX учесть эти изменения:

service nginx reload

Можно подтвердить, что HSTS работает должным образом, протестировав вашу реализацию на https://www.ssllabs.com/ssltest/analyze.html. Если HSTS реализован правильно, вы должны увидеть зеленый блок сразу под вашим баллом, в котором говорится: “Этот сервер поддерживает строгую транспортную безопасность HTTP с длительным сроком. Оценка установлена на A+.”

Поздравляем!

Теперь у вас одна из самых безопасных реализаций SSL/TLS в Интернете.

Ссылки:

Copyright © 2014 Ben Johnson

Share: X/Twitter LinkedIn

Get new posts in your inbox

No spam. Unsubscribe anytime.