Назад | Перейти на главную страницу

Как можно заставить сервер Open Directory предоставлять свою полную цепочку сертификатов для подключения клиентов?

Эта проблема

Мы создали мастер 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

Поскольку сборка 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"

Итак, мы попробовали следующее (как самостоятельно, так и вместе):

  1. Добавление olcTLSTrustedCerts. slapd четко анализирует CN, перечисленные в этой опции, и находит сертификаты CA в системной цепочке ключей, поскольку регистрирует случаи, когда предоставляется заведомо неправильное значение:

    TLS: Ошибка SecItemCopyMatching (foo.bar) (проверьте настройку olcTLSTrustedCerts): указанный элемент не может быть найден в цепочке для ключей. (-25300)

  2. Удаление OPENDIRECTORY_SSL_IDENTITY предпочтение от системного брелка. slapd больше не жалуется, что olcTLSIdentity был переопределен (и он продолжает поддерживать SSL только до тех пор, пока значение этой опции конфигурации совпадает с CN сертификата в системной цепочке ключей, иначе он жалуется так же, как указанная выше ошибка, предполагая, что он использует этот параметр конфигурации, как ожидалось ).

Тем не менее, полная цепочка сертификатов все еще не предоставляется подключающимся клиентам. Как это исправить?

Проблема двоякая:

  1. Secure Transport использует цепочку сертификатов именно как предоставлено ему клиентом API. Как документация по API, так и комментарии к исходному коду подразумевают (без явного указания), что это ошибка: в таких обстоятельствах кажется, что Secure Transport должен попытаться построить цепочку сертификатов из системной цепочки ключей.

  2. Пощечина Apple всегда предоставляет Secure Transport с сертификатом идентификации хоста только и никогда цепочка сертификатов. См. Следующие фрагменты, извлеченные из libraries/libldap/tls_st.c:

    ctx-> identity_certs = /*
    */ CFArrayCreate (NULL, (const void **) & identityRef, 1, & kCFTypeArrayCallBacks);
    
    SSLSetCertificate (ssl, ctx-> identity_certs);
    

Итак, как дела, Apple не может отправить полную цепочку сертификатов.