воскресенье, 19 июля 2020 г.

Сертификат удостоверяющего центра Active Directory для веб-серверов

На работе в локальной сети имеется ряд веб-серверов, для которых понадобилось сделать поддержку протокола HTTPS. Поскольку веб-серверы находятся в локальной сети, то публичные удостоверяющие центры сертификаты для них выдать не могут. Можно было сгенерировать самоподписанные сертификаты, но тогда понадобилось бы вносить каждый сертификат в список доверенных в каждом браузере. Но есть выход получше. Т.к. компьютеры под управлением Windows в локальной сети объединены в домен Active Directory, они все должны доверять удостоверяющему центру Active Directory. Можно сгенерировать сертификаты для веб-серверов, подписать их в удостоверяющем центре Active Directory и тогда все браузеры, использующие системное хранилище сертификатов, на таких компьютерах будут автоматически доверять этим сертификатам.

Насколько я знаю, из самой популярной тройки браузеров только Firefox в конфигурации не использует системное хранилище сертификатов. Если учитывать, что большинство компьютеров в локальных сетях предприятий обычно работают под управлением Windows и включены в домен Active Directory, а большая часть пользователей используют браузеры Chrome и Internet Explorer, то таким образом можно внедрить HTTPS на веб-серверах в локальной сети максимально гладко. В случае с Firefox можно либо включить использование системного хранилища сертификатов Windows в настройках браузера, либо вручную импортировать в браузер корневой сертификат удостоверяющего центра Active Directory. Он всего один и срок его действия больше, чем у сертификатов веб-серверов.

По возможности лучше генерировать для каждого веб-сервера индивидуальный сертификат и тогда при взломе одного веб-сервера трафик остальных останется защищённым, т.к. злоумышленник не сможет использовать приватный ключ со взломанного сервера для расшифровки перехваченного трафика других веб-серверов или организации атаки посредника. Я же для экономии времени предпочёл сегенерировать один сертификат сразу для всех веб-серверов, находящихся в моей зоне ответственности. Чтобы при необходимости продлить сертификат мне не пришлось бы вспоминать значения полей из запроса на сертификат и не пропустить по невнимательности ни одного из веб-серверов, я подготовил файл конфигурации cert-web.ini такого вида:
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req

[req_distinguished_name]
countryName = RU
countryName_default = RU
stateOrProvinceName = Bashkortostan Republic
stateOrProvinceName_default = Bashkortostan Republic
localityName = Ufa
localityName_default = Ufa
organizationalUnitName = My Department
organizationalUnitName_default = My Department
commonName = My Company
commonName_default = My Company
commonName_max  = 64

[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = server1.domain1.tld
DNS.2 = server2.domain1.tld
DNS.3 = server3.domain1.tld
DNS.4 = server4.domain2.tld
DNS.5 = server5.domain2.tld
DNS.6 = server6.domain3.tld
В конфигурации упоминаются:
  • RU - код страны,
  • Bashkortostan Republic - административная единица внутри страны,
  • Ufa - название населённого пункта,
  • My Company - название компании,
  • My Department - название подразделения компании,
  • serverX.domainY.tld - доменные имена веб-серверов в локальной сети.
Генерируем приватный ключ:
$ openssl genrsa -out cert-web.key 2048
Генерируем запрос на сертификат в соответствии с файлом конфигурации:
$ openssl req -config cert-web.ini -new -key cert-web.key -out cert-web.csr
Запрос на сертификат из файла cert-web.csr я передал администратору домена Active Directory, который подписал его в удостоверяющем центре и вернул мне подписанный сертификат cert-web.cer в формате DER.

Полученный сертификат надо преборазовать из формата DER в формат PEM:
$ openssl x509 -inform der -in cert-web.cer -out cert-web.crt
Осталось соединить приватный ключ и сертификат в формате PEM для использования получившегося файла веб-сервером:
$ cat cert-web.key cert-web.crt > cert-web.pem
Остаётся положить получившийся один файл на веб-серверы и задействовать их использование в конфигурациях веб-серверов. Если использовать систему автоматизированного управления конфигурациями, то эта задача не займёт много времени. После освоения Ansible я стал раскладывать сертификаты на веб-серверы именно с её помощью.

Для того, чтобы получить корневой сертификат удостоверяющего центра Active Directory, нужно зайти веб-браузером на сервер с удостоверяющим центром, где можно будет найти и скачать корневой сертификат. В моём случае корневой сертификат удостоверяющего центра был доступен по ссылке вида: https://domain1.tld/certsrv/certnew.cer?ReqID=CACert&Renewal=2&Mode=inst&Enc=b64

Т.к. на веб-серверах был доступен API, который использовался на других серверах, то корневой сертификат понадобилось добавить так же и на эти серверы. В случае с Debian это можно сделать способом, описанным ниже.

Сначала устанавливаем стандартные сертификаты удостоверяющих центров, если они ещё не были установлены:
# apt-get install ca-certificates
Кладём корневой сертификат нашего удостоверяющего центра в каталог /usr/local/share/ca-certificates/, предназначенный специально для дополнительных сертификатов удостоверяющих центров.

Обновляем список корневых сертификатов, которым должна доверять библиотека openssl:
# update-ca-certificates
После этого все установленные в системе программы должны начать доверять сгенерированным нами сертификатам веб-серверов. Если этого не случилось и какая-то программа или модуль не начали доверять новым сертификатам, изучите документацию. Например, для того, чтобы модуль urllib2 для Python начал доверять сертификатам, мне понадобилось передавать библиотеке urllib2 дополнительные настройки, описанные в заметке: Проверка действительности SSL-сертификата в urllib2

Комментариев нет: