| |
В наши дни использование TLS является практически обязательным. TLS реализует защитные функции конфиденциальности и целостности данных, а так же служит для поддержки аутентификации LDAP с использованием механизма SASL EXTERNAL. TLS определён в RFC4346.
Для настройки TLS на сервере нам понадобятся SSL сертификат и ключ. Сертификат должен быть подписан доверенным удостоверяющим центром (УЦ, Certificate Authority, CA) или собственным удостоверяющим центром (на основе самоподписанного, self-signed, сертификата), если используется в тестовых целях.
С помощью OpenSSL мы создадим импровизированный удостоверяющий центр и затем настроим TLS.
Прямая цитата из Википедии:
Сертификаты, как правило, используются для обмена зашифрованными данными в больших сетях. Криптосистема с открытым ключом решает проблему обмена секретными ключами между участниками безопасного обмена, однако не решает проблему доверия к открытым ключам. Предположим, что Алиса, желая получать зашифрованные сообщения, генерирует пару ключей, один из которых (открытый) она публикует каким-либо образом. Любой, кто желает отправить ей конфиденциальное сообщение, имеет возможность зашифровать его этим ключом, и быть уверенным, что только она (так как только она обладает соответствующим секретным ключом) сможет это сообщение прочесть. Однако описанная схема ничем не может помешать злоумышленнику Давиду создать пару ключей, и опубликовать свой открытый ключ, выдав его за ключ Алисы. В таком случае Давид сможет расшифровывать и читать, по крайней мере, ту часть сообщений, предназначенных Алисе, которые были по ошибке зашифрованы его открытым ключом.
Идея сертификата — это наличие третьей стороны, которой доверяют две другие стороны информационного обмена. Предполагается, что таких третьих сторон немного, и их открытые ключи всем известны каким-либо способом, например, хранятся в операционной системе или публикуются в журналах. Таким образом, подлог открытого ключа третьей стороны легко выявляется.
Если Алиса сформирует сертификат со своим публичным ключом, и этот сертификат будет подписан третьей стороной (например, Трентом), любой, доверяющий Тренту, сможет удостовериться в подлинности открытого ключа Алисы. В централизованной инфраструктуре в роли Трента выступает удостоверяющий центр. В сетях доверия Трент может быть любым пользователем, и следует ли доверять этому пользователю, удостоверившему ключ Алисы, решает сам отправитель сообщения.
Где работаем: ldap-srv
Итак, мы создаём централизованную инфраструктуру открытых ключей (PKI) в миниатюре. Для этого сформируем пару закрытый ключ/корневой сертификат удостоверяющего центра. Причём сертификат будет подписан этим же закрытым ключом (т. е. станет самоподписанным).
Затем сгенерируем новый закрытый ключ для нашей службы каталогов и создадим для неё сертификат, подписанный закрытым ключом нашего удостоверяющего центра. При этом клиенские рабочие станции должны знать только корневой сертификат. Используя его они могут установить безопасное соединение с любым сервером, который имеет закрытый ключ и соответствующий ему сертификат, подписанный нашим УЦ.
Такие пары (ключ/сертификат) можно создавать для множества задач. Например, в разделе, посвященном репликации, мы создадим второй сервер каталогов, которому тоже понадобится такая пара.
Удостоверяющий центр желательно разворачивать на отдельной машине, не имеющей подключения к сети, но для простоты примера мы проделаем всю работу на ldap-srv.example.com.
Создадим каталог для нашего удостоверяющего центра (CA) и установим безопасные права доступа. Затем зададим значение umask
таким, чтобы вновь создаваемые файлы имели права доступа чтения и записи только для создавшего их пользователя:
# mkdir /root/CA # chmod u=rwx,g=,o= /root/CA # cd /root/CA # umask 066
В конфигурационном файле /etc/ssl/openssl.cnf в секции [ CA_default ]
для удобства поменяем значение директивы dir = ./demoCA
на dir = ./
. В этом же разделе директивой default_days
задаётся срок действия выпускаемых сертификатов. Можете поменять её значение по своему усмотрению.
Файлы index.txt и serial будут играть роль своеобразной базы данных, чтобы отслеживать статус выпущенных закрытых ключей и сертификатов.
Создадим структуру каталогов и файлов для своего удостоверяющего центра:
# mkdir certs crl newcerts private # chmod 700 private # touch index.txt # echo 1000 > serial
Сгенерируем закрытый ключ удостоверяющего центра (длиной 4096 бит). Он должен хранится особенно бережно. Поэтому мы защитим его при помощи шифра AES. Вам будет предложено ввести пароль для доступа к новому закрытому ключу. Запомните его и не потеряйте. Это последний рубеж защиты от злоумышленника. Без пароля выпустить новые сертификаты не получится.
# openssl genrsa -aes256 -out private/rootca.key 4096
Изменим права доступа к новому ключу, чтобы ненароком его не стереть:
# chmod 400 private/rootca.key
Откройте конфигурационный файл OpenSSL (openssl.cnf) и найдите секции [ usr_cert ]
и [ v3_ca ]
. Убедитесь, что в них присутствуют следующие директивы:
[ usr_cert ]
# Эти расширения будут добавлены при подписывании запроса нашим УЦ.
basicConstraints=CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ v3_ca ]
# Расширения для типового УЦ
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = CA:true
keyUsage = cRLSign, keyCertSign
Сейчас мы можем выпустить корневой сертификат удостоверяющего центра, подписав его закрытым ключом rootca.key. Так как это сертификат УЦ, используем расширение v3_ca
:
# openssl req -sha256 -new -x509 -days 3650 -extensions v3_ca \
-key private/rootca.key -out certs/rootca.crt \
-subj /C=RU/ST=Moscow/L=Moscow/O=ExampleInc/OU=ITdept/CN=ca-server/emailAddress=support@example.com
# chmod 444 certs/rootca.crt
В качестве алгоритма хэширования мы используем SHA-2 (подвид SHA-256). Стоимость атаки на SHA-1 стремительно падает, а о практическом применении новоявленного SHA-3 говорить пока рано. Почему мы выбрали именно SHA-256, а не SHA-512? С сертификатом, использующим SHA-512, Вы сможете запустить демон slapd, но не сможете к нему подключиться. Увидите лишь такую многозначную ошибку:
can't connect: A TLS packet with unexpected length was received...
Мы так же указываем количество дней, в течении которых сертификат будет действителен. Десять лет — достаточно большой срок.
С помощью модификатора subj
заносим в сертификат информацию:
Можем посмотреть содержимое сертификата следующей командой:
# openssl x509 -in certs/rootca.crt -noout -text
Удостоверяющий центр готов к выпуску сертификатов.
Где работаем: ldap-srv
Как правило, закрытые ключи клиентов УЦ не должны хранится в самом УЦ. Клиент может сам сформировать ключевую пару и прислать в УЦ лишь запрос на подпись (Certificate Signing Request, CSR). Запрос содержит открытый ключ. Однако мы будем создавать все ключи и хранить их в одном месте. В организации, которая серьёзно подходит к проблемам безопасности такой процесс работы может быть неприемлемым.
Продолжаем в том же каталоге /root/CA. Создадим закрытый ключ для сервера службы каталогов:
# openssl genrsa -out private/ldap-srv.example.com.key 4096 # chmod 400 private/ldap-srv.example.com.key
Сгенерируем запрос на подпись сертификата. Наименование организации (ExampleInc) должно совпадать с наименованием в корневом сертификате УЦ. В качестве Common Name
укажем FQDN нашего сервера:
# openssl req -sha256 -new \ -key private/ldap-srv.example.com.key -out certs/ldap-srv.example.com.csr \ -subj /C=RU/ST=Moscow/L=Moscow/O=ExampleInc/OU=ITdept/CN=ldap-srv.example.com/emailAddress=support@example.com
Следующим шагом должно быть подписание запроса CSR существующим доверенным удостоверяющим центром (например, VeriSign) в обмен на деньги. Но нам не хочется платить за эту услугу, или у нас нет своего (корпоративного) CA, или это просто тестовая конфигурация, а может нам просто всё равно. Поэтому мы подпишем его с помощью своего собственного CA:
# openssl ca -extensions usr_cert -notext -md sha256 \ -keyfile private/rootca.key -cert certs/rootca.crt \ -in certs/ldap-srv.example.com.csr -out certs/ldap-srv.example.com.crt # chmod 444 certs/ldap-srv.example.com.crt
Создадим каталог для ключевой информации нашего сервера и поместим туда получившиеся у нас файлы:
# mkdir /etc/ldap/ssl # chown openldap:openldap /etc/ldap/ssl # chmod 0500 /etc/ldap/ssl # cp certs/ldap-srv.example.com.crt private/ldap-srv.example.com.key /etc/ldap/ssl
Установим права доступа для ключевой информации:
# chown openldap:openldap /etc/ldap/ssl/{ldap-srv.example.com.crt,ldap-srv.example.com.key} # chmod 0400 /etc/ldap/ssl/{ldap-srv.example.com.crt,ldap-srv.example.com.key}
Поместим корневой сертификат в каталог с сертификатами операционной системы и зададим для него права доступа:
# cp certs/rootca.crt /etc/ssl/certs/ # chmod 0644 /etc/ssl/certs/rootca.crt
В заключение можем удалить запрос CSR, он нам больше не нужен:
# rm -rf certs/ldap-srv.example.com.csr
Каталог /root/CA теперь выполняет роль удостоверяющего центра. Аналогичным образом его можно создать на другой машине, тогда надо будет копировать секретные ключи и подписанные сертификаты по сети с помощью scp или через съёмный носитель. Неплохой идеей будет хранить этот каталог на отдельном носителе и монтировать его только для выпуска новых сертификатов. Сам носитель можно, например, положить в сейф. Процесс создания новых пар ключ-сертификат в будущем будет состоять из трёх этапов:
Где работаем: ldap-srv
Вернёмся во временный каталог:
$ cd ~/ldap
Создадим LDIF-файл 3.2-tls-config.ldif для внесения в каталог конфигурации TLS и запишем в него:
dn: cn=config
add: olcTLSVerifyClient
olcTLSVerifyClient: never
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/ssl/ldap-srv.example.com.crt
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap-srv.example.com.key
-
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/rootca.crt
Этими записи говорят демону slapd, где лежит его сертификат и ключ, где лежит корневой сертификат УЦ и что от клиентов требовать наличие сертификата не нужно. Чтобы окончательно всё запутать, мы могли бы создать сертификаты для всех клиентов. В реальной жизни такая аутентификация клиента принесёт небольшое усиление защиты за счёт большого увеличения работы по сопровождению всех этих сертификатов. Тем более далее в этом руководстве мы опишем механизмы аутентификации Kerberos.
Загрузим конфигурацию TLS в наш каталог:
# ldapmodify -QY EXTERNAL -H ldapi:/// -f 3.2-tls-config.ldif modifying entry "cn=config"
Теперь наш сервер OpenLDAP должен поддерживать расширения TLS. Перепроверим, что всё в порядке:
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b cn=config -s base | grep -i tls olcTLSCertificateFile: /etc/ldap/ssl/ldap-srv.example.com.crt olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap-srv.example.com.key olcTLSCACertificateFile: /etc/ssl/certs/rootca.crt olcTLSVerifyClient: never
Вновь отредактируем конфигурационный файл /etc/ldap/ldap.conf и включим поддержку TLS:
BASE dc=example,dc=com
URI ldap://ldap-srv.example.com
TLS_CACERT /etc/ssl/certs/rootca.crt
TLS_REQCERT demand
TIMELIMIT 15
TIMEOUT 20
Обычно для конфигурации cn=config
перезагрузка службы не требуется, но чтобы созданная нами ключевая информация подхватилась, придётся это сделать:
# service slapd restart * Stopping OpenLDAP slapd [ OK ] * Starting OpenLDAP slapd [ OK ]
Проверьте соединение с сервером с использованием TLS (модификатор -ZZ
). На этот раз мы выполним запрос с использованием DN нашего администратора:
$ ldapsearch -xZZLLLWD cn=admin,dc=example,dc=com -b cn=config -s base Enter LDAP Password: dn: cn=config objectClass: olcGlobal cn: config olcArgsFile: /var/run/slapd/slapd.args olcPidFile: /var/run/slapd/slapd.pid olcTLSCACertificateFile: /etc/ssl/certs/rootca.crt olcTLSCertificateFile: /etc/ldap/ssl/ldap-srv.example.com.crt olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap-srv.example.com.key olcTLSVerifyClient: never
Обратите внимание, что в запросе ldapsearch нам не пришлось указывать имя хоста (-H ldap://ldap-srv.example.com
). Всё потому что оно указано в файле /etc/ldap/ldap.conf. Что касается TLS, то во время инициирования соединения клиент (на данном этапе клиентский запрос выполняет сам сервер) получает от сервера его подписанный сертификат (ldap-srv.example.com.crt). Клиент может ничего не знать о сервере, но у него есть сертификат CA (rootca.crt), с помощью которого и проверяется сервер.
Где работаем: ldap-srv
Сертификаты не вечны. Во-первых при создании задаётся его срок действия. При этом частота обновления сертификатов — баланс между безопасностью и удобством. Во-вторых он может быть скомпрометирован, если скомпрометирован его закрытый ключ. Как во втором случае оповестить субъектов доступа, что сертификат более не действителен? Для этого и служит Certificate Revocation List (CRL). Он представляет собой список серийных номеров отозванных сертификатов, подписанный УЦ, который их выпустил.
Вернёмся в каталог удостоверяющего центра:
# cd /root/CA
Прежде чем мы сможем сгенерировать CRL, надо создать файл crlnumber. Он нужен openssl, чтобы отслеживать номер следующего CRL:
# echo 1000 > crlnumber
В стандартной конфигурации openssl использует CRL V1. Раскомментируйте строку
crl_extensions = crl_extв /etc/ssl/openssl.cnf, чтобы переключиться на CRL V2. Это хорошая идея, за исключением тех случаев, когда надо использовать именно CRL V1 (например, при использовании сильно устаревшего браузера). Создаём CRL:
# openssl ca -keyfile private/rootca.key -cert certs/rootca.crt -gencrl -out crl/rootca.crl
Посмотреть результат можно так:
# openssl crl -in crl/rootca.crl -text
Предположим, что закрытый ключ сервера ldap-srv был скомпрометирован. Чтобы оповестить об этом клиентские машины, надо отозвать сертификат этого сервера, создать CRL, а затем — распространить CRL среди клиентов.
Отзываем сертификат:
# openssl ca -keyfile private/rootca.key -cert certs/rootca.crt -revoke certs/ldap-srv.example.com.crt
Заглянем в index.txt. Начало записи с нашим сертификатом теперь изменилось с V
на R
:
# cat index.txt R 160116072355Z 150119081313Z 1000 unknown /C=RU/ST=Moscow/O=ExampleInc/OU=ITdept/CN=ldap-srv.example.com/emailAddress=support@example.com
Обратите внимание, что копии новых сертификатов так же содержатся в каталоге newcerts. При этом имя файла содержит серийный номер сертификата. Когда отзываете сертификаты, вместо файлов в каталоге certs Вы можете пользоваться каталогом newcerts. Результат будет идентичен. Например:
# openssl ca -keyfile private/rootca.key -cert certs/rootca.crt -revoke newcerts/1000.pem
Обновим CRL:
# openssl ca -keyfile private/rootca.key -cert certs/rootca.crt -gencrl -out crl/rootca.crl
Взглянём на содержимое CRL:
# openssl crl -in crl/rootca.crl -text
Вы должны увидеть нечто подобное:
... Revoked Certificates: Serial Number: 1000 Revocation Date: ...
Поместим CRL в каталог, где его увидит клиентское ПО:
# cp crl/rootca.crl /etc/ssl
Осталось только распространить этот CRL среди клиентов. Мы делаем это простым путём — копированием файлов по сети вручную.
Где работаем: ldap-client
На каждой клиентской машине надо будет запустиь:
# scp user@ldap-srv.example.com:/etc/ssl/certs/rootca.crt /etc/ssl/certs # scp user@ldap-srv.example.com:/etc/ssl/rootca.crl /etc/ssl/
Настроим клиентскую конфигурацию в /etc/ldap/ldap.conf и укажем, где хранится CRL:
BASE dc=example,dc=com
URI ldap://ldap-srv.example.com
TLS_CACERT /etc/ssl/certs/rootca.crt
TLS_REQCERT demand
TLS_CRLFILE /etc/ssl/rootca.crl
TIMELIMIT 15
TIMEOUT 20
И попробуем получить доступ к серверу каталогов:
$ ldapsearch -xZZLLLWD cn=admin,dc=example,dc=com -b cn=config -s base dn ldap_start_tls: Connect error (-11) additional info: (unknown error code)
Наш CRL работает. Но к slapd теперь не подключиться. Надо выпустить новый сертификат для сервера.
Где работаем: ldap-srv
Сделаем это простой последовательностью команд. Мы повторяем пройденное, комментарии излишни:
# cd /root/CA # openssl genrsa -out private/ldap-srv.example.com.key 4096 # chmod 400 private/ldap-srv.example.com.key # openssl req -sha256 -new \ -key private/ldap-srv.example.com.key -out certs/ldap-srv.example.com.csr \ -subj /C=RU/ST=Moscow/L=Moscow/O=ExampleInc/OU=ITdept/CN=ldap-srv.example.com/emailAddress=support@example.com # openssl ca -extensions usr_cert -notext -md sha256 \ -keyfile private/rootca.key -cert certs/rootca.crt \ -in certs/ldap-srv.example.com.csr -out certs/ldap-srv.example.com.crt # chmod 444 certs/ldap-srv.example.com.crt # cp certs/ldap-srv.example.com.crt private/ldap-srv.example.com.key /etc/ldap/ssl # chown openldap:openldap /etc/ldap/ssl/{ldap-srv.example.com.crt,ldap-srv.example.com.key} # chmod 0400 /etc/ldap/ssl/{ldap-srv.example.com.crt,ldap-srv.example.com.key}
Перезупустим демон slapd и убедимся, что к серверу можно подключиться:
# service slapd restart $ ldapsearch -xZZLLLWD cn=admin,dc=example,dc=com -b cn=config -s base dn Enter LDAP Password: dn: cn=config
В целом по отзыву сертификатов... Иногда в реальных условиях лучше применить другой подход. Намного удобней, когда клиентские машины самостоятельно выясняют у сервера, действителен конкретный сертификат или нет. В выпускаемые сертификаты можно вносить запись CRL Distribution Points
. Она заставит клиентов самих периодически скачивать новый CRL. Или можно использовать OCSP. Но эта тема выходит за рамки данного руководства.
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |