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

Используемые термины: mTLS, NGINX, Linux.
В данной инструкции мы рассмотрим:
- Создание сертификатов сервера и клиента.
- Настройку NGINX для аутентификации клиента.
- Создание и настройку инфраструктуры отзыва сертификатов.
Изучим работу с mTLS в NGINX по шагам.
Настройка аутентификации клиента (mTLS)
Настройка https в NGINX
Конфигурирование mTLS
Настройка клиента
Создание клиентского сертификата
Пример настройки клиента Windows
Отзыв сертификатов
Настройка инфраструктуры отзыва
Отзыв сертификата и получение crl-файла
Дополнительная информация
Настройка 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:
Идем на наш сервер в каталог, где лежат созданные клиентские сертификаты.
Сконвертируем 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 — установка и настройка.