Модуль ngx_stream_ssl_module

Пример конфигурации
Директивы
     ssl_alpn
     ssl_certificate
     ssl_certificate_key
     ssl_ciphers
     ssl_client_certificate
     ssl_conf_command
     ssl_crl
     ssl_dhparam
     ssl_ecdh_curve
     ssl_handshake_timeout
     ssl_password_file
     ssl_prefer_server_ciphers
     ssl_protocols
     ssl_reject_handshake
     ssl_session_cache
     ssl_session_ticket_key
     ssl_session_tickets
     ssl_session_timeout
     ssl_trusted_certificate
     ssl_verify_client
     ssl_verify_depth
Встроенные переменные

Модуль ngx_stream_ssl_module (1.9.0) обеспечивает необходимую поддержку для работы прокси-сервера по протоколу SSL/TLS. По умолчанию этот модуль не собирается, его сборку необходимо разрешить с помощью конфигурационного параметра --with-stream_ssl_module.

Пример конфигурации

Для уменьшения загрузки процессора рекомендуется

worker_processes auto;

stream {

    ...

    server {
        listen              12345 ssl;

        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers         AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
        ssl_certificate     /usr/local/nginx/conf/cert.pem;
        ssl_certificate_key /usr/local/nginx/conf/cert.key;
        ssl_session_cache   shared:SSL:10m;
        ssl_session_timeout 10m;

        ...
    }

Директивы

Синтаксис: ssl_alpn протокол ...;
Умолчание:
Контекст: stream, server

Эта директива появилась в версии 1.21.4.

Задаёт список поддерживаемых протоколов ALPN. Один из протоколов должен быть согласован, если клиент использует ALPN:

map $ssl_alpn_protocol $proxy {
    h2                 127.0.0.1:8001;
    http/1.1           127.0.0.1:8002;
}

server {
    listen      12346;
    proxy_pass  $proxy;
    ssl_alpn    h2 http/1.1;
}

Синтаксис: ssl_certificate файл;
Умолчание:
Контекст: stream, server

Указывает файл с сертификатом в формате PEM для данного сервера. Если вместе с основным сертификатом нужно указать промежуточные, то они должны находиться в этом же файле в следующем порядке — сначала основной сертификат, а затем промежуточные. В этом же файле может находиться секретный ключ в формате PEM.

Начиная с версии 1.11.0 эта директива может быть указана несколько раз для загрузки сертификатов разных типов, например RSA и ECDSA:

server {
    listen              12345 ssl;

    ssl_certificate     example.com.rsa.crt;
    ssl_certificate_key example.com.rsa.key;

    ssl_certificate     example.com.ecdsa.crt;
    ssl_certificate_key example.com.ecdsa.key;

    ...
}

Возможность задавать отдельные цепочки сертификатов для разных сертификатов есть только в OpenSSL 1.0.2 и выше. Для более старых версий следует указывать только одну цепочку сертификатов.

Начиная с версии 1.15.9 в имени файла можно использовать переменные при использовании OpenSSL 1.0.2 и выше:

ssl_certificate     $ssl_server_name.crt;
ssl_certificate_key $ssl_server_name.key;

Однако нужно учитывать, что при использовании переменных сертификат загружается при каждой операции SSL handshake, что может отрицательно влиять на производительность.

Вместо файла можно указать значение data:$переменная (1.15.10), при котором сертификат загружается из переменной без использования промежуточных файлов. При этом следует учитывать, что ненадлежащее использование подобного синтаксиса может быть небезопасно, например данные секретного ключа могут попасть в лог ошибок.

Синтаксис: ssl_certificate_key файл;
Умолчание:
Контекст: stream, server

Указывает файл с секретным ключом в формате PEM для данного сервера.

Вместо файла можно указать значение engine:имя:id, которое загружает ключ с указанным id из OpenSSL engine с заданным именем.

Вместо файла можно указать значение data:$переменная (1.15.10), при котором секретный ключ загружается из переменной без использования промежуточных файлов. При этом следует учитывать, что ненадлежащее использование подобного синтаксиса может быть небезопасно, например данные секретного ключа могут попасть в лог ошибок.

Начиная с версии 1.15.9 в имени файла можно использовать переменные при использовании OpenSSL 1.0.2 и выше.

Синтаксис: ssl_ciphers шифры;
Умолчание:
ssl_ciphers HIGH:!aNULL:!MD5;
Контекст: stream, server

Описывает разрешённые шифры. Шифры задаются в формате, поддерживаемом библиотекой OpenSSL, например:

ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;

Полный список можно посмотреть с помощью команды “openssl ciphers”.

Синтаксис: ssl_client_certificate файл;
Умолчание:
Контекст: stream, server

Эта директива появилась в версии 1.11.8.

Указывает файл с доверенными сертификатами CA в формате PEM, которые используются для проверки клиентских сертификатов.

Список сертификатов будет отправляться клиентам. Если это нежелательно, можно воспользоваться директивой ssl_trusted_certificate.

Синтаксис: ssl_conf_command имя значение;
Умолчание:
Контекст: stream, server

Эта директива появилась в версии 1.19.4.

Задаёт произвольные конфигурационные команды OpenSSL.

Директива поддерживается при использовании OpenSSL 1.0.2 и выше.

На одном уровне может быть указано несколько директив ssl_conf_command:

ssl_conf_command Options PrioritizeChaCha;
ssl_conf_command Ciphersuites TLS_CHACHA20_POLY1305_SHA256;

Директивы наследуются с предыдущего уровня конфигурации при условии, что на данном уровне не описаны свои директивы ssl_conf_command.

Следует учитывать, что изменение настроек OpenSSL напрямую может привести к неожиданному поведению.

Синтаксис: ssl_crl файл;
Умолчание:
Контекст: stream, server

Эта директива появилась в версии 1.11.8.

Указывает файл с отозванными сертификатами (CRL) в формате PEM, используемыми для проверки клиентских сертификатов.

Синтаксис: ssl_dhparam файл;
Умолчание:
Контекст: stream, server

Указывает файл с параметрами для DHE-шифров.

По умолчанию параметры не заданы, и соответственно DHE-шифры не будут использоваться.

До версии 1.11.0 по умолчанию использовались встроенные параметры.

Синтаксис: ssl_ecdh_curve кривая;
Умолчание:
ssl_ecdh_curve auto;
Контекст: stream, server

Задаёт кривую для ECDHE-шифров.

При использовании OpenSSL 1.0.2 и выше можно указывать несколько кривых (1.11.0), например:

ssl_ecdh_curve prime256v1:secp384r1;

Специальное значение auto (1.11.0) соответствует встроенному в библиотеку OpenSSL списку кривых для OpenSSL 1.0.2 и выше, или prime256v1 для более старых версий.

До версии 1.11.0 по умолчанию использовалась кривая prime256v1.

При использовании OpenSSL 1.0.2 и выше директива задаёт список кривых, поддерживаемых сервером. Поэтому для работы ECDSA-сертификатов важно, чтобы список включал кривые, используемые в сертификатах.

Синтаксис: ssl_handshake_timeout время;
Умолчание:
ssl_handshake_timeout 60s;
Контекст: stream, server

Задаёт таймаут для завершения операции SSL handshake.

Синтаксис: ssl_password_file файл;
Умолчание:
Контекст: stream, server

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

Пример:

stream {
    ssl_password_file /etc/keys/global.pass;
    ...

    server {
        listen 127.0.0.1:12345;
        ssl_certificate_key /etc/keys/first.key;
    }

    server {
        listen 127.0.0.1:12346;

        # вместо файла можно указать именованный канал
        ssl_password_file /etc/keys/fifo;
        ssl_certificate_key /etc/keys/second.key;
    }
}

Синтаксис: ssl_prefer_server_ciphers on | off;
Умолчание:
ssl_prefer_server_ciphers off;
Контекст: stream, server

Указывает, чтобы при использовании протоколов SSLv3 и TLS серверные шифры были более приоритетны, чем клиентские.

Синтаксис: ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3];
Умолчание:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
Контекст: stream, server

Разрешает указанные протоколы.

Если директива указана на уровне server, то может использоваться значение из сервера по умолчанию.

Параметры TLSv1.1 и TLSv1.2 работают только при использовании OpenSSL 1.0.1 и выше.

Параметр TLSv1.3 (1.13.0) работает только при использовании OpenSSL 1.1.1 и выше.

Параметр TLSv1.3 используется по умолчанию начиная с 1.23.4.

Синтаксис: ssl_reject_handshake on | off;
Умолчание:
ssl_reject_handshake off;
Контекст: stream, server

Эта директива появилась в версии 1.25.5.

Если разрешено, то операции SSL handshake в блоке server будут отклонены.

Например в этой конфигурации отклоняются все операции SSL handshake с именем сервера, отличным от example.com:

server {
    listen               443 ssl default_server;
    ssl_reject_handshake on;
}

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

Синтаксис: ssl_session_cache off | none | [builtin[:размер]] [shared:название:размер];
Умолчание:
ssl_session_cache none;
Контекст: stream, server

Задаёт тип и размеры кэшей для хранения параметров сессий. Тип кэша может быть следующим:

off
жёсткое запрещение использования кэша сессий: nginx явно сообщает клиенту, что сессии не могут использоваться повторно.
none
мягкое запрещение использования кэша сессий: nginx сообщает клиенту, что сессии могут использоваться повторно, но на самом деле не хранит параметры сессии в кэше.
builtin
встроенный в OpenSSL кэш, используется в рамках только одного рабочего процесса. Размер кэша задаётся в сессиях. Если размер не задан, то он равен 20480 сессиям. Использование встроенного кэша может вести к фрагментации памяти.
shared
кэш, разделяемый между всеми рабочими процессами. Размер кэша задаётся в байтах, в 1 мегабайт может поместиться около 4000 сессий. У каждого разделяемого кэша должно быть произвольное название. Кэш с одинаковым названием может использоваться в нескольких серверах. Также он используется для автоматического создания, хранения и периодического обновления ключей TLS session tickets (1.23.2), если они не указаны явно с помощью директивы ssl_session_ticket_key.

Можно использовать одновременно оба типа кэша, например:

ssl_session_cache builtin:1000 shared:SSL:10m;

однако использование только разделяемого кэша без встроенного должно быть более эффективным.

Синтаксис: ssl_session_ticket_key файл;
Умолчание:
Контекст: stream, server

Задаёт файл с секретным ключом, применяемым при шифровании и расшифровании TLS session tickets. Директива необходима, если один и тот же ключ нужно использовать на нескольких серверах. По умолчанию используется случайно сгенерированный ключ.

Если указано несколько ключей, то только первый ключ используется для шифрования TLS session tickets. Это позволяет настроить ротацию ключей, например:

ssl_session_ticket_key current.key;
ssl_session_ticket_key previous.key;

Файл должен содержать 80 или 48 байт случайных данных и может быть создан следующей командой:

openssl rand 80 > ticket.key

В зависимости от размера файла для шифрования будет использоваться либо AES256 (для 80-байтных ключей, 1.11.8), либо AES128 (для 48-байтных ключей).

Синтаксис: ssl_session_tickets on | off;
Умолчание:
ssl_session_tickets on;
Контекст: stream, server

Разрешает или запрещает возобновление сессий при помощи TLS session tickets.

Синтаксис: ssl_session_timeout время;
Умолчание:
ssl_session_timeout 5m;
Контекст: stream, server

Задаёт время, в течение которого клиент может повторно использовать параметры сессии.

Синтаксис: ssl_trusted_certificate файл;
Умолчание:
Контекст: stream, server

Эта директива появилась в версии 1.11.8.

Задаёт файл с доверенными сертификатами CA в формате PEM, которые используются для проверки клиентских сертификатов.

В отличие от ssl_client_certificate, список этих сертификатов не будет отправляться клиентам.

Синтаксис: ssl_verify_client on | off | optional | optional_no_ca;
Умолчание:
ssl_verify_client off;
Контекст: stream, server

Эта директива появилась в версии 1.11.8.

Разрешает проверку клиентских сертификатов. Результат проверки доступен через переменную $ssl_client_verify. Если при проверке клиентского сертификата произошла ошибка или клиент не предоставил требуемый сертификат, соединение закрывается.

Параметр optional запрашивает клиентский сертификат, и если сертификат был предоставлен, проверяет его.

Параметр optional_no_ca запрашивает сертификат клиента, но не требует, чтобы он был подписан доверенным сертификатом CA. Это предназначено для случаев, когда фактическая проверка сертификата осуществляется внешним по отношению к nginx’у сервисом. Содержимое сертификата доступно через переменную $ssl_client_cert.

Синтаксис: ssl_verify_depth число;
Умолчание:
ssl_verify_depth 1;
Контекст: stream, server

Эта директива появилась в версии 1.11.8.

Устанавливает глубину проверки в цепочке клиентских сертификатов.

Встроенные переменные

Модуль ngx_stream_ssl_module поддерживает переменные начиная с версии 1.11.2.

$ssl_alpn_protocol
возвращает протокол, выбранный при помощи ALPN во время операции SSL handshake, либо пустую строку (1.21.4);
$ssl_cipher
возвращает название используемого шифра для установленного SSL-соединения;
$ssl_ciphers
возвращает список шифров, поддерживаемых клиентом (1.11.7). Известные шифры указаны по имени, неизвестные указаны в шестнадцатеричном виде, например:
AES128-SHA:AES256-SHA:0x00ff
Переменная полностью поддерживается при использовании OpenSSL версии 1.0.2 и выше. При использовании более старых версий переменная доступна только для новых сессий и может содержать только известные шифры.
$ssl_client_cert
возвращает клиентский сертификат для установленного SSL-соединения в формате PEM перед каждой строкой которого, кроме первой, вставляется символ табуляции(1.11.8);
$ssl_client_fingerprint
возвращает SHA1-отпечаток клиентского сертификата для установленного SSL-соединения (1.11.8);
$ssl_client_i_dn
возвращает строку “issuer DN” клиентского сертификата для установленного SSL-соединения согласно RFC 2253 (1.11.8);
$ssl_client_raw_cert
возвращает клиентский сертификат для установленного SSL-соединения в формате PEM (1.11.8);
$ssl_client_s_dn
возвращает строку “subject DN” клиентского сертификата для установленного SSL-соединения согласно RFC 2253 (1.11.8);
$ssl_client_serial
возвращает серийный номер клиентского сертификата для установленного SSL-соединения (1.11.8);
$ssl_client_v_end
возвращает дату окончания срока действия клиентского сертификата (1.11.8);
$ssl_client_v_remain
возвращает число дней, оставшихся до истечения срока действия клиентского сертификата (1.11.8);
$ssl_client_v_start
возвращает дату начала срока действия клиентского сертификата (1.11.8);
$ssl_client_verify
возвращает результат проверки клиентского сертификата (1.11.8): “SUCCESS”, “FAILED:reason” и, если сертификат не был предоставлен, “NONE”;
$ssl_curve
возвращает согласованную кривую, использованную для обмена ключами во время операции SSL handshake (1.21.5). Известные кривые указаны по имени, неизвестные указаны в шестнадцатеричном виде, например:
prime256v1
Переменная поддерживается при использовании OpenSSL версии 3.0 и выше. При использовании более старых версий значением переменной будет пустая строка.
$ssl_curves
возвращает список кривых, поддерживаемых клиентом (1.11.7). Известные кривые указаны по имени, неизвестные указаны в шестнадцатеричном виде, например:
0x001d:prime256v1:secp521r1:secp384r1
Переменная поддерживается при использовании OpenSSL версии 1.0.2 и выше. При использовании более старых версий значением переменной будет пустая строка.
Переменная доступна только для новых сессий.
$ssl_protocol
возвращает протокол установленного SSL-соединения;
$ssl_server_name
возвращает имя сервера, запрошенное через SNI;
$ssl_session_id
возвращает идентификатор сессии установленного SSL-соединения;
$ssl_session_reused
возвращает “r”, если сессия была использована повторно, иначе “.”.