https для nginx

TLS и его предшественник SSL, и наличие в адресной строке браузера префикса https становятся обыденностью. В защищённой версии необходимо размещать как минимум все административные панели, формы с паролями и всё, что содержит чувствительные данные. И это относится не только к открытым wi-fi сетям. Защищённый протокол также обезопасит не только от «прослушки», но и от подмены данных (что иногда практикуют в бесплатных вайфаях в публичных местах). На поддержку https уже давно обращают внимание даже поисковики.

Здесь описывается как включить поддержку https для nginx и настроить его наиболее безопасно и оптимально.

Включаем кеширование

В SSL/TLS очень ресурсозатрано установление соединения. Поэтому кеширование параметров сессии существенно экономит ресурсы:

ssl_session_cache shared:SSL:20m;
ssl_session_timeout 30m;

Первая опция указывает рамер кеша (в мегабайтах), вторая — время его действия (в минутах). В документации указывается, что каждый мегабайт вмещает примерно 4к сессий, следовательно в указанных выше настройках вместится 80к сессий, что обычно более чем достаточно. Памятью nginx распоряжается очень экономично, поэтому если и потребуется изменение, то обычно в бОльшую сторону в зависимости от посещаемости ресурса.

Выбираем TLS и отключаем SSL

Да, отключаем старые протоколы, в том числе SSLv3, более известного в сочетании с POODLE. Оставляем только современный TLS, причём и его желательно последних версий, но некоторые браузеры ещё работают на TLSv:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

Выбираем используемые Cipher suites

Если коротко, то Cipher suite — это совокупность алгоритмов, используемых в TLS–сессии. Он включает в себя алгоритмы генерации ключей шифрования, аутентификации, обмена ключами, контроля целостности, иными словами полный набор алгоритмов для реализации TLS в каждом конкретном соединении.

Первое, что сделаем — сообщим клиенту, что имеется список предпочтительных cipher suites

ssl_prefer_server_ciphers on;

а затем перечислим допустимые из них

ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5

Приведённое здесь решение не единичное (но, очевидно, короткое), возможны другие наборы хороших шифров. Необходимо учитывать, что приведённый набор работает на достаточно современном ПО, старые версии браузеров (например, WindowsXP/IE8) его поддерживать не будут. Набор можно расширить для поддержки старого софта, однако, действительно требуется это в редких случаях.

Генерируем параметры обмена ключами DH [Diffie-Hellman key exchange]

Что это такое, как работает и зачем нужно можно прочить в подробном руководстве, например, от Мозиллы. Генерируем числа:

openssl dhparam -out dhparam.pem 4096

Полученный файл с вычисленными параметрами для обмена ключей положим в /nginx/ssl, далее его нужно включить в конфигурации:

ssl_dhparam /etc/nginx/cert/dhparam.pem;

В данном случае генерируются 4к-битные простые числа, они могут не поддерживаться старым редкоиспользуемым клиентским софтом, поэтому если такой софт есть — имеет смысл уменьшить длину генерируемых чисел. Файл может формироваться достаточно долго, особенно на слабых машинах.

OCSP-stapling

Сертификаты имеют свойство не только выдаваться, но и отзываться. Браузер для проверки действительности сертфиката обращается к издателю для проверки, что он не отозван и эта проверка ещё добавляет времени и ресурсов (со стороны клиента) к инициализации соединения, а также вовлекает в этот процесс ещё и издателя.

Часть из этих побочных эффектов можно устранить с помощью механизма OCSP (Online Certificate Status Protocol) Stapling. С помощью этого механизма сервер сам запрашивает OCSP-сервер на действительность сертификата и кэширует полученный ответ. Ответ «сшивается» (staple) с TLS рукопожатием через Certificate Status Request. Это устраняет прямое обращение браузера к издателю сертификата (а значит и время ожидания) и позволяет браузеру не раскрывать подробностей обращения к сайту третьим лицам.

Включаем расширение

server {
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/trusted.crt;
}

В качестве trusted.crt указываем цепочку сертификатов: корневой, затем промежуточный.

Тестируем

Наиболее хороший онлайн-тест в обозримом интернете предлагают Qualys SSL Labs.
Описанная выше конфигурация по этому тесту даёт в результате A.
SSL Labs A test

В принципе, на этом этапе можно и остановиться, поскольку основные требования безопасности выполнены и этого достаточно для большинства сайтов. Но можно пойти ещё дальше.

Включение HSTS (Strict Transport Security)

Переключение сайта на протокол https обычно сопровождается полным переездом на него. Для этого меняют внутренние ссылки с явно прописанным протоколом, а при обращении на http-версию какого-либо URL меняют протокол http->https (301 редиректом). Кроме этого, существует механизм сообщить браузеру, что сайт полностью сидит на защищённом протоколе и любое обращение должно идти по https-протоколу — это механизм HSTS. Реализуется он заголовком со стороны сервера:

Strict-Transport-Security: max-age=15768000

После первого обращение к сайту современный браузер будет «знать», что сайт работает только по https и работать только по этому протоколу. Параметр max-age это время в секундах, в течении которого после получения заголовка браузер считает, что существует только https-версия. А значит, после включения HSTS обратного пути на обычный http нет.

Механизм также можно включить на все поддомены заголовком

add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;

Результат

Применяя всё вышеописанное в результате должен получиться A+
SSL Labs A+ test

Можно пойти и ещё дальше. Хорошая практичная документация по SSL/TLS предоставляется, например, Мозиллой.