Настройка mTLS в NGINX на Linux

Обновлено и опубликовано Опубликовано:

Используемые термины: mTLSNGINX, Linux.

В данной инструкции мы рассмотрим:

  • Создание сертификатов сервера и клиента.
  •  Настройку NGINX для аутентификации клиента.
  • Создание и настройку инфраструктуры отзыва сертификатов.

Изучим работу с mTLS в NGINX по шагам.

Настройка mTLS на NGINX

В рамках данной инструкции мы не будем рассматривать установку и базовую настройку NGINX, а сосредоточим внимание на mTLS. Процесс разобьем на этапы.

Настройка HTTPS

Наш веб-сервер должен принимать запросы по https. Для этого необходимо получить сертификат. Для тестовых целей мы будем использовать самоподписанный — создадим каталог для его хранения:

mkdir /etc/ssl/server

И сами ключи:

openssl req -new -x509 -days 1461 -nodes -out /etc/ssl/server/cert.crt -keyout /etc/ssl/server/cert.key -subj "/CN=mtls.dmosk.local"

* это простой способ создать сертификат с открытым и закрытым ключами в каталоге /etc/ssl/server.

Редактируем файл виртуального домена NGINX. Данных файлов может быть несколько, как правило, они расположены в каталогах:

  • /etc/nginx/sites-enabled (sites-available).
  • /etc/nginx/conf.d.

Или можно открыть конфигурационный файл с доменом по умолчанию. Он также может иметь различное расположение, например:

vi /etc/nginx/conf.d/default.conf

Для настройки https должны быть настроены директивы:

  • listen — указать порт, на котором слушать запросы (для https, как правило, 443), а также опцию ssl.
  • ssl_certificate — путь до файла с открытым ключом.
  • ssl_certificate_key — путь до файла с закрытым ключом.

В моем случае конфигурация имела такие значения вышеописанных опций:

server {
    ...
    listen       443 ssl;
    ...
    ssl_certificate     /etc/ssl/server/cert.pem;
    ssl_certificate_key /etc/ssl/server/cert.key;
    ...
}

Для проверки можно выполнить curl-запрос:

curl -k https://127.0.0.1

Сервер должен вернуть html для страницы вашего сайта. HTTPS настроен — переходим к настройке mTLS.

Настройка аутентификации клиента

Завершаем настройку mTLS, указав, что веб-сервер NGINX должен проверять клиента. Нам нужно сформировать клиентский сертификат. Мы также будем использовать самозаверенные ключи.

Создадим каталог, где будут находиться сертификаты и перейдем в него:

mkdir /etc/ssl/client

cd /etc/ssl/client

Сформируем ключи для центра сертификации:

openssl req -newkey rsa:2048 -nodes -keyout ca.key -x509 -days 3650 -subj "/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=ca" -out ca.crt

Этого достаточно для настройки NGINX — открываем конфигурационный файл (в нашем примере мы работали с доменом по умолчанию):

vi /etc/nginx/conf.d/default.conf

Добавил такие директивы:

server {
    ...
    ssl_client_certificate /etc/ssl/client/ca.crt;
    ssl_verify_client on;
    ...
}

* где:

  • ssl_client_certificate — путь до открытого ключа центра сертификации, который будет использоваться для проверки клиентов.
  • ssl_verify_client — включает или отключает проверку сертификатов. В нашем случае, включает.

Проверяем корректность конфигурации веб-сервера и перезапускаем его:

nginx -t && nginx -s reload

Теперь пробуем сделать http-запрос:

curl -k https://127.0.0.1

Мы должны получить ошибку:

<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx/1.25.2</center>
</body>
</html>

mTLS работает.

Теперь, чтобы наши запросы к серверу проходили, нужно использовать сертификат, выданный центром сертификации, ключ которого прописан в nginx.

Подключение клиента к веб-серверу

Теперь рассмотрим, как создать клиентский сертификат и использовать его.

Создание клиентского сертификата

Предполагается, что мы по-прежнему, находимся в каталоге с клиентскими сертификатами:

cd /etc/ssl/client

Для удобства, создаем переменную, значением которой будет порядковый номер сертификата:

export CLIENT_NO=01

Создадим файл запроса сертификата:

openssl req -newkey rsa:2048 -keyout client${CLIENT_NO}.key -out client${CLIENT_NO}.csr -nodes -days 731 -subj "/CN=client${CLIENT_NO}"

* в результате мы получим файл закрытого ключа client01.key и файл запроса client01.csr.

Теперь выдадим клиентский сертификат, заверив его ключом центра сертификации:

openssl x509 -req -in client${CLIENT_NO}.csr -out client${CLIENT_NO}.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 731

* будет сформирован ключ client01.crt. Мы используем ключи центра сертификации ca.crt и ca.key, которые сформировали ранее, а открытый ключ указали в nginx для аутентификации клиентов.

Теперь попробуем воспользоваться данными сертификатами, чтобы сделать http-запрос:

curl -k --key client${CLIENT_NO}.key --cert client${CLIENT_NO}.crt https://127.0.0.1

На этот раз, мы должны увидеть html-код, сформированный сервером.

Настройка клиента Windows

В качестве примера, рассмотрим настройку системы Windows.

Если мы попробуем перейти на веб-страницу с настроенным mTLS, браузер должен вернуть ошибку 400:

Ошибка 400 при попытке перейти на страницу, требующую аутентификацю клиента

Идем на наш сервер в каталог, где лежат созданные клиентские сертификаты.

Сконвертируем pfx-файл:

openssl pkcs12 -inkey client${CLIENT_NO}.key -in client${CLIENT_NO}.crt -export -out client${CLIENT_NO}.pfx

Обязательно, вводим пароль.

Полученный файл (в нашем случае, client01.pfx) копируем на компьютер с Windows и выполняем импорт в браузер.

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

Отзыв сертификата

Рассмотрим как процесс настройки сервера, так и отзыва сертификата.

Подготовка сервера

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

Мы должны быть в каталоге с клиентскими сертификатами:

cd /etc/ssl/client

Создадим каталог demoCA и в нем 2 файла:

mkdir ./demoCA

touch ./demoCA/index.txt

echo 1000 > ./demoCA/crlnumber

* где:

  • index.txt — файл с перечнем отозванных сертификатов.
  • crlnumber — файл с регистром номера CRL.

** расположение, имя каталога и файлов определяется конфигурационным файлом openssl.cnf. В данной инструкции предполагаются стандартные настройки, но если у вас свои настройки, то ориентироваться нужно на них.

Настраиваем nginx:

vi /etc/nginx/conf.d/default.conf

server {
    ...
    ssl_crl /etc/ssl/client/crl.pem;
    ...
}

* мы указали веб-серверу учитывать ключ с перечнем отозванных сертификатов.

Так как ключа crl.pem пока нет, NGINX перезагружать нельзя.

Переходим к отзыву сертификата.

Отзыв сертификата

Предположим, что нам нужно отозвать сертификат client03. Вводим команду:

openssl ca -revoke client03.crt -keyfile ca.key -cert ca.crt

И формируем актуальный файл crl:

openssl ca -keyfile ca.key -cert ca.crt -gencrl -out crl.pem

Готово. Теперь можно перезапустить nginx:

nginx -t && nginx -s reload

Проверим отправку http-запроса с помощью отозванного сертификата:

curl -k --key client03.key --cert client03.crt https://127.0.0.1

Мы должны получить ошибку с кодом 400.

Читайте также

Дополнительная информация, которая может оказаться полезной.

1. NGINX на CentOS 7 — установка и настройка.

2. Правильная настройка SSL в NGINX.

3. Настройка NGINX для HTTP/2 по шагам.

# Linux # NGINX # Безопасность # Интернет # Серверы
Дмитрий Моск — частный мастер
Была ли полезна вам эта инструкция?

Да            Нет