Мы создали мастер Open Directory на OSX 10.10 Yosemite + Server.app v4:
$ sudo slapconfig -createldapmasterandadmin admin Administrator 1000
Которая генерирует корневой ЦС, промежуточный ЦС и SSL-сертификат хоста (все правильно размещены как в системной цепочке ключей, так и в /etc/certificates
каталог). Однако при подключении через SSL slapd
обеспечивает только сертификат хоста, а не всю цепочку сертификатов:
$ openssl s_client -connect a.b.c:636
CONNECTED(00000003)
depth=0 CN = a.b.c, C = GB, emailAddress = a@b.c.
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = a.b.c, C = GB, emailAddress = a@b.c
verify error:num=27:certificate not trusted
verify return:1
depth=0 CN = a.b.c, C = GB, emailAddress = a@b.c
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/CN=a.b.c/C=GB/emailAddress=a@b.c
i:/CN=IntermediateCA_A.B.C_1/O=b/OU=MACOSX OpenDirectory Intermediate CA/emailAddress=a@b.c
---
Конечно, это проблема, потому что клиенты (которые доверяют только корневому ЦС) не могут проверить сертификат хоста и прервать соединение.
В соответствии с Руководство администратора OpenLDAP 2.4, глава 16 «Использование TLS»:
16.2.1.1. TLSCACertificateFile <имя файла>
Эта директива определяет файл в формате PEM, содержащий сертификаты для центров сертификации, которым slapd будет доверять. Сертификат ЦС, подписавший сертификат сервера, должен быть включен в эти сертификаты. Если подписывающий ЦС не был ЦС верхнего уровня (корневым), должны присутствовать сертификаты для всей последовательности ЦС от подписывающего ЦС до ЦС верхнего уровня. К файлу просто добавляются несколько сертификатов; порядок не имеет значения.
(Во избежание сомнений, тот факт, что slapd
затем предоставит цепочку сертификатов для подключенных клиентов, недавно подтверждено в списке рассылки openldap-Technical- хотя это было ранее отмечалось что это вызывает проблемный конфликт, когда для сертификатов клиентов TLS используются разные якоря доверия).
Поскольку сборка Apple использует slapd.d
, обычно можно было бы ожидать, что этот параметр будет настроен через olcTLSCACertificateFile
- однако, согласно slapd-config(5)
(курсив мой):
olcTLSCACertificateFile: <имя файла>
Задает файл, содержащий сертификаты для всех центров сертификации, которые распознает slapd.
При использовании SecureTransport эта опция не действует. Вместо этого используйте параметр olcTLSTrustedCerts.
[ удаление ]olcTLSTrustedCerts
Перечисляет доверенные сертификаты в системной цепочке ключей, разделенные знаком «|». Например: olcTLSTrustedCerts Frobozz, Inc. | Widgets R Us | www.example.com
Используется SecureTransport вместо olcTLSCACertificateFile и olcTLSCACertificatePath. Игнорируется OpenSSL, GnuTLS и Mozilla NSS.
(SecureTransport - это библиотека SSL от Apple).
Удивительно, olcTLSTrustedCerts
не был создан в нашем каталоге slapconfig
, хотя сертификат хоста был названный в (родственном) olcTLSIdentity
. Тем не менее, slapd
в любом случае игнорировал olcTLSIdentity
в пользу OPENDIRECTORY_SSL_IDENTITY
предпочтение в системной связке ключей:
TLS: предпочтение идентификации OPENDIRECTORY_SSL_IDENTITY переопределяет настроенный olcTLSIdentity "a.b.c"
Итак, мы попробовали следующее (как самостоятельно, так и вместе):
Добавление olcTLSTrustedCerts
. slapd
четко анализирует CN, перечисленные в этой опции, и находит сертификаты CA в системной цепочке ключей, поскольку регистрирует случаи, когда предоставляется заведомо неправильное значение:
TLS: Ошибка SecItemCopyMatching (foo.bar) (проверьте настройку olcTLSTrustedCerts): указанный элемент не может быть найден в цепочке для ключей. (-25300)
Удаление OPENDIRECTORY_SSL_IDENTITY
предпочтение от системного брелка. slapd
больше не жалуется, что olcTLSIdentity
был переопределен (и он продолжает поддерживать SSL только до тех пор, пока значение этой опции конфигурации совпадает с CN сертификата в системной цепочке ключей, иначе он жалуется так же, как указанная выше ошибка, предполагая, что он использует этот параметр конфигурации, как ожидалось ).
Тем не менее, полная цепочка сертификатов все еще не предоставляется подключающимся клиентам. Как это исправить?
Проблема двоякая:
Secure Transport использует цепочку сертификатов именно как предоставлено ему клиентом API. Как документация по API, так и комментарии к исходному коду подразумевают (без явного указания), что это ошибка: в таких обстоятельствах кажется, что Secure Transport должен попытаться построить цепочку сертификатов из системной цепочки ключей.
Пощечина Apple всегда предоставляет Secure Transport с сертификатом идентификации хоста только и никогда цепочка сертификатов. См. Следующие фрагменты, извлеченные из libraries/libldap/tls_st.c
:
ctx-> identity_certs = /*
*/ CFArrayCreate (NULL, (const void **) & identityRef, 1, & kCFTypeArrayCallBacks);
SSLSetCertificate (ssl, ctx-> identity_certs);
Итак, как дела, Apple не может отправить полную цепочку сертификатов.