Spec-Zone.ru › nginx

Настройка HTTPS-серверов

  • Оптимизация HTTPS-сервера
  • Цепочки сертификатов SSL
  • Один HTTP/HTTPS-сервер
  • HTTPS-серверы с именами
  • Сертификат SSL с несколькими именами
  • Указание имени сервера (SNI)
  • Совместимость

Для настройки HTTPS-сервера необходимо включить параметр ssl на сокетнах прослушивания в блоке server, а также указать расположение файлов сертификата сервера и ключевого файла:

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ...
}

Сертификат сервера — это открытый ключ. Он отправляется каждому клиенту, подключающемуся к серверу. Закрытый ключ — это секретный ключ и должен храниться в файле с ограниченным доступом, но должен быть доступен для главного процесса nginx. Закрытый ключ может альтернативно храниться в том же файле, что и сертификат:

    ssl_certificate     www.example.com.cert;
    ssl_certificate_key www.example.com.cert;

в этом случае права доступа к файлу также должны быть ограничены. Хотя сертификат и ключ хранятся в одном файле, клиенту отправляется только сертификат.

Директивы ssl_protocols и ssl_ciphers можно использовать для ограничения подключений, включив только сильные версии и шифры SSL/TLS. По умолчанию nginx использует «ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3» и «ssl_ciphers HIGH:!aNULL:!MD5», поэтому явное их указание обычно не требуется. Обратите внимание, что значения по умолчанию для этих директив несколько раз менялись.

Оптимизация HTTPS-сервера

Операции SSL потребляют дополнительные ресурсы процессора. На многопроцессорных системах следует запускать не менее числа доступных ядер процессора рабочих процессов. Наиболее ресурсоемкой операцией является рукопожатие SSL. Существует два способа минимизации числа этих операций на одного клиента: первое — это включение keepalive подключений для отправки нескольких запросов через одно подключение, а второе — повторное использование параметров сеанса SSL для предотвращения рукопожатий SSL при параллельных и последующих подключениях. Сессии хранятся в кэше сессий SSL, используемом совместно рабочими процессами и настраиваемом с помощью директивы ssl_session_cache. Один мегабайт кэша содержит примерно 4000 сессий. По умолчанию время жизни кэша составляет 5 минут. Его можно увеличить с помощью директивы ssl_session_timeout. Вот пример конфигурации, оптимизированной для многоядерной системы с общим кэшем сессий размером 10 мегабайт:

worker_processes auto;

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

    server {
        listen              443 ssl;
        server_name         www.example.com;
        keepalive_timeout   70;

        ssl_certificate     www.example.com.crt;
        ssl_certificate_key www.example.com.key;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ...

Цепочки сертификатов SSL

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

$ cat www.example.com.crt bundle.crt > www.example.com.chained.crt

Результирующий файл следует использовать в директиве ssl_certificate:

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.chained.crt;
    ssl_certificate_key www.example.com.key;
    ...
}

Если сертификат сервера и набор сертификатов были объединены в неправильном порядке, nginx не запустится и отобразит сообщение об ошибке:

SSL_CTX_use_PrivateKey_file(" ... /www.example.com.key") failed
   (SSL: error:0B080074:x509 certificate routines:
    X509_check_private_key:key values mismatch)

поскольку nginx пытался использовать закрытый ключ с первым сертификатом набора вместо сертификата сервера.

Браузеры обычно хранят промежуточные сертификаты, которые они получают и которые подписаны доверенными центрами, поэтому активно используемые браузеры, возможно, уже имеют необходимые промежуточные сертификаты и могут не жаловаться на отправленный сертификат без набора цепочки. Чтобы убедиться, что сервер отправляет полную цепочку сертификатов, можно использовать утилиту openssl , например:

$ openssl s_client -connect www.godaddy.com:443
...
Certificate chain
 0 s:/C=US/ST=Arizona/L=Scottsdale/1.3.6.1.4.1.311.60.2.1.3=US
     /1.3.6.1.4.1.311.60.2.1.2=AZ/O=GoDaddy.com, Inc
     /OU=MIS Department/CN=www.GoDaddy.com
     /serialNumber=0796928-7/2.5.4.15=V1.0, Clause 5.(b)
   i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
 1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc.
     /OU=http://certificates.godaddy.com/repository
     /CN=Go Daddy Secure Certification Authority
     /serialNumber=07969287
   i:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
 2 s:/C=US/O=The Go Daddy Group, Inc.
     /OU=Go Daddy Class 2 Certification Authority
   i:/L=ValiCert Validation Network/O=ValiCert, Inc.
     /OU=ValiCert Class 2 Policy Validation Authority
     /CN=http://www.valicert.com//emailAddress=info@valicert.com
...
При тестировании конфигураций с SNI важно указать параметр -servername , поскольку openssl по умолчанию не использует SNI.

В этом примере субъект («s») сертификата сервера #0 подписан издателем («i»), который сам является субъектом сертификата #1, который подписан издателем, который сам является субъектом сертификата #2, который подписан известным издателем ValiCert, Inc., сертификат которого хранится в встроенной базе сертификатов браузеров (в доме, который построил Джек).

Если набор сертификатов не был добавлен, будет показан только сертификат сервера #0.

Один HTTP/HTTPS-сервер

Можно настроить один сервер, обрабатывающий как HTTP-, так и HTTPS-запросы:

server {
    listen              80;
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ...
}
До версии 0.7.14 SSL нельзя было включать выборочно для отдельных сокетов прослушивания, как показано выше. SSL можно было включить только для всего сервера с помощью директивы ssl, что делало невозможным настроить один HTTP/HTTPS-сервер. Параметр ssl директивы listen был добавлен для решения этой проблемы. Использование директивы ssl в современных версиях не рекомендуется.

HTTPS-серверы с именами

Частая проблема возникает при настройке двух или более HTTPS-серверов, прослушивающих один IP-адрес:

server {
    listen          443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
    ...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
    ...
}

При такой конфигурации браузер получает сертификат по умолчанию сервера, т.е. www.example.com независимо от имени запрошенного сервера. Это вызвано поведением протокола SSL. SSL-соединение устанавливается до того, как браузер отправляет HTTP-запрос, и nginx не знает имени запрошенного сервера. Поэтому он может предложить только сертификат сервера по умолчанию.

Самый старый и надежный способ решения этой проблемы — назначить отдельный IP-адрес для каждого HTTPS-сервера:

server {
    listen          192.168.1.1:443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
    ...
}

server {
    listen          192.168.1.2:443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
    ...
}

Сертификат SSL с несколькими именами

Существуют и другие способы, позволяющие использовать один IP-адрес для нескольких HTTPS-серверов. Однако все они имеют свои недостатки. Один способ — использовать сертификат с несколькими именами в поле SubjectAltName сертификата, например, www.example.com и www.example.org. Однако длина поля SubjectAltName ограничена.

Другой способ — использовать сертификат с подстановочным знаком в имени, например, *.example.org. Сертификат с подстановочным знаком обеспечивает безопасность всех поддоменов указанного домена, но только на одном уровне. Этот сертификат соответствует www.example.org, но не соответствует example.org и www.sub.example.org. Эти два метода также можно комбинировать. Сертификат может содержать точные и подстановочные знаки в поле SubjectAltName, например, example.org и *.example.org.

Лучше поместить файл сертификата с несколькими именами и файл его закрытого ключа на уровне конфигурации http, чтобы унаследовать их единственную копию в памяти во всех серверах:

ssl_certificate     common.crt;
ssl_certificate_key common.key;

server {
    listen          443 ssl;
    server_name     www.example.com;
    ...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
    ...
}

Указание имени сервера (SNI)

Более универсальным решением для запуска нескольких HTTPS-серверов на одном IP-адресе является расширение протокола TLS Server Name Indication (SNI, RFC 6066), которое позволяет браузеру передавать имя запрошенного сервера во время рукопожатия SSL, и, следовательно, сервер будет знать, какой сертификат использовать для подключения. SNI в настоящее время поддерживается большинством современных браузеров, хотя некоторые старые или специальные клиенты могут его не использовать.

В SNI могут передаваться только имена домена, однако некоторые браузеры могут ошибочно передавать IP-адрес сервера как его имя, если запрос включает в себя буквальный IP-адрес. На это не стоит полагаться.

Для использования SNI в nginx он должен поддерживаться как в библиотеке OpenSSL, с которой был скомпилирован двоичный файл nginx, так и в библиотеке, к которой он динамически подключается во время выполнения. OpenSSL поддерживает SNI с версии 0.9.8f, если он был скомпилирован с опцией конфигурации “--enable-tlsext”. С версии OpenSSL 0.9.8j эта опция включена по умолчанию. Если nginx был скомпилирован с поддержкой SNI, то nginx покажет это при запуске с ключом «-V»:

$ nginx -V
...
TLS SNI support enabled
...

Однако, если SNI-совместимый nginx динамически подключен к библиотеке OpenSSL без поддержки SNI, nginx отображает предупреждение:

nginx was built with SNI support, however, now it is linked
dynamically to an OpenSSL library which has no tlsext support,
therefore SNI is not available

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

  • Статус поддержки SNI отображается ключом «-V» с версии 0.8.21 и 0.7.62.
  • Параметр ssl директивы listen поддерживается с версии 0.7.14. До версии 0.8.21 он мог быть указан только вместе с параметром default .
  • SNI поддерживается с версии 0.5.23.
  • Кэш общих сессий SSL поддерживается с версии 0.5.6.
  • Версия 1.23.4 и выше: по умолчанию используются протоколы SSL TLSv1, TLSv1.1, TLSv1.2 и TLSv1.3 (если поддерживаются библиотекой OpenSSL).
  • Версия 1.9.1 и выше: по умолчанию используются протоколы SSL TLSv1, TLSv1.1 и TLSv1.2 (если поддерживаются библиотекой OpenSSL).
  • Версия 0.7.65, 0.8.19 и выше: по умолчанию используются протоколы SSL SSLv3, TLSv1, TLSv1.1 и TLSv1.2 (если поддерживаются библиотекой OpenSSL).
  • Версия 0.7.64, 0.8.18 и ниже: по умолчанию используются протоколы SSL SSLv2, SSLv3 и TLSv1.
  • Версия 1.0.5 и выше: по умолчанию используются шифры SSL «HIGH:!aNULL:!MD5».
  • Версия 0.7.65, 0.8.20 и выше: по умолчанию используются шифры SSL «HIGH:!ADH:!MD5».
  • Версия 0.8.19: по умолчанию используются шифры SSL «ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM».
  • Версия 0.7.64, 0.8.18 и ниже: по умолчанию используются шифры SSL
    «ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP».
Написано Игорем Сысоевым
Отредактировано Брайаном Мерсером

© 2002-2021 Igor Sysoev
© 2011-2024 Nginx, Inc.
Licensed under the BSD License.
https://nginx.org/en/docs/http/configuring_https_servers.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API