Перейти к содержанию

Взаимная TLS-аутентификация (mTLS) с Nginx

При обычном HTTPS сервер подтверждает свою подлинность клиенту. В режиме mTLS Nginx также требует у клиента сертификат и проверяет цепочку до доверенного УЦ. Этот механизм можно использовать для защищённых внутренних API и административных порталов НАЙС.ОС.

Требования

  • Серверный сертификат с назначением serverAuth.
  • Клиентский сертификат с назначением clientAuth.
  • Доверенный УЦ, который выпускает клиентские сертификаты.
  • Проверенный способ обновления списка отозванных сертификатов.
  • Согласованный TLS-профиль клиента и сервера.

Создание сертификатов: X.509, CSR и PKI.

Конфигурация

Внутри отдельного тестового server { ... }:

ssl_certificate     /etc/nginx/gost/server-chain.pem;
ssl_certificate_key /etc/nginx/gost/server-key.pem;
ssl_client_certificate /etc/nginx/gost/trusted-client-ca.pem;
ssl_verify_client on;
ssl_verify_depth 2;

location /api/ {
    proxy_set_header X-Client-Verify $ssl_client_verify;
    proxy_pass http://127.0.0.1:8080;
}

Директива ssl_verify_client on требует сертификат клиента. ssl_verify_depth задаёт допустимую глубину цепочки. Никогда не считайте HTTP-заголовок от самого клиента доказательством mTLS: доверенное значение должен устанавливать только Nginx, а непосредственный доступ к backend необходимо закрыть.

Испытания

  1. Клиент без сертификата должен быть отклонён.
  2. Клиент с действительным сертификатом — проходить.
  3. Клиент с сертификатом другого УЦ — отклоняться.
  4. Клиент с отозванным сертификатом — отклоняться при настроенной проверке отзыва.
  5. Проверить, что backend недоступен напрямую через сеть.
sudo nginx -t
curl -vk https://127.0.0.1:8443/api/

Для клиентского запроса с сертификатом используйте параметры --cert и --key с тестовыми файлами, если клиентская реализация TLS поддерживает нужный алгоритм. Отрицательный тест без сертификата должен завершиться отказом.