На работе в локальной сети имеется ряд веб-серверов, для которых понадобилось сделать поддержку протокола 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
В конфигурации упоминаются:
Генерируем приватный ключ:
$ 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