Настройка mTLS в NGINX на Linux
Используемые термины: mTLS, NGINX, Linux.
В данной инструкции мы рассмотрим:
- Создание сертификатов сервера и клиента.
- Настройку NGINX для аутентификации клиента.
- Создание и настройку инфраструктуры отзыва сертификатов.
Изучим работу с mTLS в NGINX по шагам.
Настройка аутентификации клиента (mTLS)
Настройка https в NGINX
Конфигурирование mTLS
Настройка клиента
Создание клиентского сертификата
Пример настройки клиента Windows
Отзыв сертификатов
Настройка инфраструктуры отзыва
Отзыв сертификата и получение crl-файла
Пример работы с сертификатами FreeIPA
Дополнительная информация
Настройка 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.crt;
ssl_certificate_key /etc/ssl/server/cert.key;
...
}
Проверяем корректность конфигурации и перечитываем конфигурацию nginx:
nginx -t && nginx -s reload
Для проверки можно выполнить 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
Обязательно, придумываем и вводим пароль для экспорта закрытого ключа (например, 12345678).
Полученный файл (в нашем случае, client01.pfx) копируем на компьютер с Windows (например, с помощью WinSCP) и выполняем импорт в браузер (в настройках конкретного браузера).
Возможно, браузер придется перезагрузить или для проверки запустить в режиме инкогнито. После чего при переходе на сайт, должно появится окно с запросом сертификата — выбираем тот, что импортировали. Сайт должен открыться.
Отзыв сертификата
Рассмотрим как процесс настройки сервера, так и отзыва сертификата.
Подготовка сервера
Наш сервер должен быть настроен для возможности отозвать сертификат.
Мы должны быть в каталоге с клиентскими сертификатами:
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.
Пример работы с FreeIPA
Дополнительно, рассмотрим пример получения и использования сертификатов от FreeIPA.
Запрос пользовательского сертификата
Сначала нам нужно сформировать запрос на получение сертификата. Это можно сделать на любом компьютере. Мы рассмотрим пример на Linux с помощью утилиты openssl.
Предположим, что мы хотим получить клиентский сертификат для пользователя user1. Создаем переменную:
export CLIENT_NAME=user1
Создаем закрытый ключи и файл запроса:
openssl req -newkey rsa:2048 -keyout ${CLIENT_NAME}.key -out ${CLIENT_NAME}.csr -nodes -days 731 -subj "/CN=${CLIENT_NAME}"
Выводим на экран последовательность для запроса:
cat ${CLIENT_NAME}.csr
Полученные строки копируем. Они нам понадобятся чуть позже.
Открываем веб-интерфейс FreeIPA и переходим в настройки пользователя. Кликаем Действия - Новый сертификат:
В открывшемся окне заполняем данные формы. В качестве запроса вставляем ту последовательность, которую получили на сервере nginx:
Нажимаем Выдать. Сертификат должен сформироваться и стать доступным для просмотра. В соответствующем разделе кликаем Действия - Получить:
На экране появится сертификат. Копируем его и возвращаемся на компьютер, где у нас находится закрытый ключ.
Создадим файл сертификата:
vi ${CLIENT_NAME}.crt
Копируем в него последовательность пользовательского сертификата, которую получили в веб-интерфейсе FreeIPA.
Мы можем протестировать полученный сертификат:
curl -k --key ${CLIENT_NAME}.key --cert ${CLIENT_NAME}.crt https://127.0.0.1
Запрос должен нам вернуть страницу без ошибки с кодом 400.
Если нам нужно импортировать сертификат на компьютер с Windows, получаем PFX командой:
openssl pkcs12 -inkey ${CLIENT_NAME}.key -in ${CLIENT_NAME}.crt -export -out ${CLIENT_NAME}.pfx
Отзыв сертификата в FreeIPA
FreeIPA позволяет администратору легко отозвать сертификат в веб-интерфейсе.
Но наш сервер nginx не получит соответвующую информацию по отзыву. Чтобы решить эту проблему, можно написать небольшой скрипт:
#!/bin/bash
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
IPA_SERVER=ipa-server.dmosk.ru
curl -o /tmp/MasterCRL.crl -L "https://${IPA_SERVER}/ca/ee/ca/getCRL?op=getCRL&crlIssuingPoint=MasterCRL"
openssl crl -in /tmp/MasterCRL.crl -inform DER -out /etc/ssl/client/crl.pem
rm -f /tmp/MasterCRL.crl
nginx -t && nginx -s reload
Данный скрипт выполнит запрос к серверу FreeIPA и получит сертификат отзыва в формате DER. После мы конвертируем DER в PEM и размещаем файл по пути, где nginx ожидает найти сертификат отзыва (в нашем примере это /etc/ssl/client/crl.pem). Последнее, скрипт проверит конфигурацию nginx и перезапустит его.
Наш скрипт можно поместить в cron, чтобы обновлять информацию по отзывам в автоматическом режиме.
Читайте также
Дополнительная информация, которая может оказаться полезной.
1. NGINX на CentOS 7 — установка и настройка.
2. Правильная настройка SSL в NGINX.
3. Настройка NGINX для HTTP/2 по шагам.
4. Сертификат для Linux в центре сертификации Active Directory Certificate Services.
5. Установка и использование FreeIPA на Rocky Linux или CentOS.