Допустим, у вас в локальной сети поднят контроллер домена под управлением MS Windows и пользовательские компьютеры входят в данный домен. И у вас есть Linux-сервер, который как-то должен обмениваться информацией с соседями по несчастью сети. И хорошо бы по защищенному каналу. А еще лучше, если сертификат у него будет валиден внутри сети. Вот о том, как этого добиться и пойдет речь.
Вообще, часто не заморачиваются, а создают самоподписанный сертификат и всех клиентов к ногтю заставляют ему доверять. Но это не наш метод :) Автор (т.е. я, собственной скромной персоной) использует схему описанную ниже.
Компьютеры, которые находятся в Windows-домене должны доверять контроллеру домена. У контроллера домена должны быть ключи и сертификаты и он должен быть CA. На контроллере должен работать центр сертификации. Соответственно, все сертификаты, которые подписаны нашим доморощенным CA, должны быть валидны внутри сети. Про настройку СА на контроллере домена я тут рассказывать не буду - это несколько другая история. Считаем, что все это у нас уже есть и поднята веб-морда центра сертификации. Допустим что эта вебморда спрятана по адресу: https://dc/certsrv/.
Первое, что нам нужно сделать - создать запрос на сертификат. Делаем это при помощи следующего скрипта на нашем Linux-сервере:
#!/bin/bash
hn=`hostname --short`
# set dm= to your domain name (no spaces around the equal sign!)
dm=`hostname --domain`
# go to OpenSSL directory
ssldir=`openssl version -a | grep OPENSSLDIR | sed -e 's/OPENSSLDIR://' -e 's/ //g' -e 's/\"//g'`
cd $ssldir
cd /etc/pki/tls
openssl req \
-new -newkey rsa:1024 -nodes \
-keyout private/$hn.key -out private/$hn.req.pem \
-subj "/CN=$hn.$dm/OU=IT"
Результатом работы скрипта будут два файла в папочке private (допустим имя сервера lin-srv): lin-srv.key и lin-srv.req.pem. Папочку искать либо в /etc/pki/tls, либо (если такой директории нет) в директории OPENSSLDIR, адрес которой можно узнать, выполнив:
openssl version -a | grep OPENSSLDIR
У меня в ubuntu файлы легли в /etc/ssl/private.
Теперь откроем в браузере вебморду контроллера домена https://dc/certsrv/, авторизуемся (у учетки должны быть права на создание сертификатов) и пройдем по ссылке: "Request a certificate" (https://dc/certsrv/certrqus.asp), далее - "advanced certificate request" (https://dc/certsrv/certrqxt.asp). Помните два файла на Linux-сервере? Нас сейчас интересует файл запроса lin-srv.req.pem. С помощью этого запроса мы и будем создавать сертификат :) Копируем содержимое файла и вставляем его в первое поле формы, шаблон сертификата можно выбрать "Web server" - скорее всего этот шаблон вам подойдет, если нет - доки в помощь :) Атрибуты? А они вам нужны? Мне и без них хорошо :) Жмем "Submit" и скачиваем сертификат в DER-формате, попутно можно скачать и сертификат самого CA.
Печаль в том, что нам сертификат нужен в PEM-формате. Но тут все просто, достаточно скопировать сертификат на linux-сервер и сделать:openssl x509 -in lin-srv.cer -inform DER -out lin-srv.pem -outform PEM
Проверим содержимое сертификата:openssl x509 -noout -text -in lin-srv.pem
Теперь у нас есть пара: ключ (lin-srv.key) и сертификат (lin-srv.pem), подписанный контроллером домена. Большая часть дела сделана :)
Вот только наш Linux-сервер пока не доверяет контроллеру домена :( Но это не проблема. Сертификат CA мы должны были добыть еще ранее. Копируем его (а заодно и свеже созданный сертификат нашего Linux-сервера) в директорию /etc/ssl/certs. Проблема в том, что одного копирования мало, нужно создать еще симлинки на эти файлы. Симлинки должны иметь имена соответствующие хэш-сумме сертификата. Для создания/обновления симлинков нужно выполнить:
c_rehash
Теперь можно проверить, установился ли CA сертификат домена:openssl s_client -connect dc:636 -CApath /etc/ssl/certs/
Если проверка прошла успешно, то можно настраивать обмен информацией!
P.S. Не надо забывать о том, что необходимо будет указать правильные пути к файлам сертификатов и ключей для программ, которые будут работать с доменом. Например, для работы с LDAP возможно придется поправить файл /etc/ldap.conf или /etc/openldap/ldap.conf.