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

Использование сертификатов Lets Encrypt с openLDAP

Я использую сервер openLDAP в течение нескольких месяцев, и мы используем его для аутентификации для ряда приложений. Предыдущий сотрудник устанавливал сервер, и это не похоже на стандартную установку, но это довольно просто.

Недавно истек срок действия одного из наших сертификатов CA, и было принято решение заменить его на Let's Encrypt. Мой менеджер заменил сертификат на сервере.

Он работает для веб-приложения (диспетчер LDAP, самостоятельная смена пароля), однако ни один клиент не может пройти аутентификацию с его помощью. Например, если я пытаюсь протестировать конфигурацию Redmine LDAP, я получаю сообщение «Невозможно подключиться (SSL_connect SYSCALL Return = 5 errno = 0 state = SSLv2 / v3 read server hello A)»

Тестирование аутентификации Nexus против него просто не подключается.

К сожалению, нет ничего в журналах ни на сервере LDAP, ни в журналах с приложениями, чтобы указать, почему это не работает. Мои исследования заставили меня поверить в то, что это то, что нужно делать, как настроен сертификат / ключ, но я перепробовал все, что мог придумать, и все, что я мог найти в Интернете, и ничего не работает.

Подробная информация об окружающей среде:

Debian 8 openLDAP openldap-2.4.40

Моя конфигурация выглядит так:

/etc/ldap/ldap.conf

# LDAP Defaults
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
#BASE   dc=example,dc=com
#URI    ldap://ldap.example.com ldap://ldap-master.example.com:666
#SIZELIMIT      12
#TIMELIMIT      15
#DEREF          never
# TLS certificates (needed for GnuTLS)
TLS_CACERT      /etc/letsencrypt/live/myserver.com/fullchain.pem

/etc/ldap/slapd.d/cn=config.ldif

dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/run/slapd/slapd.args
olcLogLevel: none
olcPidFile: /var/run/slapd/slapd.pid
olcToolThreads: 1
structuralObjectClass: olcGlobal
entryUUID: c6dd9e40-9dc2-1035-8c03-add74f928a5e
creatorsName: cn=config
createTimestamp: 20160423171552Z
entryCSN: 20160423171552.629347Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20160423171552Z

Если я проверю соединение:

admin@ldap:~$ sudo openssl s_client -connect localhost:636 -showcerts -state -CAfile /etc/letsencrypt/live/myserver.com/fullchain.pem
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
140394818631312:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:184:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 289 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE

Кто-нибудь знает, что мне не хватает?

РЕДАКТИРОВАТЬ

В соответствии с предложением @ 84104 я отредактировал файл tls.ldif следующим образом:

dn: cn=config
changetype: modify
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/letsencrypt/live/myserver/fullchain.pem
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/letsencrypt/live/myserver/cert.pem
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/letsencrypt/live/myserver/privkey.pem

Затем запустите команду:

ldapmodify -Y EXTERNAL -H ldapi:/// -f tls.ldif

Однако теперь я получаю следующий результат:

SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"
ldap_modify: Other (e.g., implementation specific) error (80)

Я обнаружил, что это может быть связано с разрешениями на файлы сертификата или ключей, но я изменил их, чтобы они точно соответствовали тем, которые были в ранее используемых файлах, и все еще получаю это сообщение.

Еще раз прошу прощения за отсутствие общих знаний по теме, но может ли кто-нибудь предложить что-нибудь еще?

РЕДАКТИРОВАТЬ

В соответствии с предложением я изменил tls.ldif и изменил все команды с replace на delete, а затем снова выполнил команду ldapmodify. Есть еще одна ошибка.

    admin@ldap:/etc/ansible_ldif_work$ sudo ldapmodify -Y EXTERNAL -H   ldapi:/// -f tls.remove.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"
ldap_modify: Inappropriate matching (18)
        additional info: modify/delete: olcTLSCACertificateFile: no equality matching rule

Файл fullchain.pem НЕ является объединением цепочки сертификатов над файлом cert.pem, это объединение файлов chain.pem и cert.pem.

Файл chain.pem и корневой авторитетный файл должны быть объединены в файл, который вы представите slapd как olcTLSCACertificateFile.

Файл privkey.pem должен быть представлен slapd как olcTLSCertificateKeyFile.

Простой файл cert.pem должен быть представлен slapd как olcTLSCertificateFile.

Я не уверен, имеет ли значение порядок конкатенации, но я использовал именно такой порядок: cat chain.pem root.pem> ca.merged.crt

Тест openssl, который вы использовали, показывает, что при такой настройке все в порядке.

Корневой авторитетный файл можно найти здесь: https://www.identrust.com/certificates/trustid/root-download-x3.html

Тест:

[root@█████ ssl]# openssl s_client -connect [REDACTED]:636 -showcerts -state -CAfile ca.merged.crt
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = [REDACTED]
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
---
Certificate chain
 0 s:/CN=[REDACTED]
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
-----BEGIN CERTIFICATE-----
[REDACTED]
-----END CERTIFICATE-----
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
-----BEGIN CERTIFICATE-----
[REDACTED]
-----END CERTIFICATE-----
 2 s:/O=Digital Signature Trust Co./CN=DST Root CA X3
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
-----BEGIN CERTIFICATE-----
[REDACTED]
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=[REDACTED]
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
---
No client certificate CA names sent
Server Temp Key: ECDH, secp384r1, 384 bits
---
SSL handshake has read 4417 bytes and written 405 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: [REDACTED]
    Session-ID-ctx:
    Master-Key: [REDACTED]
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1487882605
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

На эту тему есть красивая запись в блоге. Меня устраивает https://www.dahlem.uk/display/deb/Configure+and+enable+TLS+for+OpenLDAP

Обновить (резервная копия блога на archive.org):https://web.archive.org/web/20161023210915/http://www.dahlem.uk:80/display/deb/Configure+and+enable+TLS+for+OpenLDAP

Моя система такова:

# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 8.8 (jessie)
Release:        8.8
Codename:       jessie

# slapd -V
@(#) $OpenLDAP: slapd  (Jul 16 2017 19:57:41) $
        Debian OpenLDAP Maintainers <pkg-openldap-devel@lists.alioth.debian.org>

Вот быстрый пробег. Обрабатывать доступ к файловой системе для letsencrypt ...

useradd letsencrypt
chown openldap:letsencrypt /etc/letsencrypt/ -R
usermod -a -G letsencrypt openldap

Активировать услуги ...

# /etc/default/slapd
SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"

И расскажите openldap о ваших сертификатах ...

# /root/add_ssl.ldif
dn: cn=config
changetype: modify
add: olcTLSCipherSuite
olcTLSCipherSuite: NORMAL
-
add: olcTLSCRLCheck
olcTLSCRLCheck: none
-
add: olcTLSVerifyClient
olcTLSVerifyClient: never
-
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/letsencrypt/live/YOURDOMAIN/fullchain.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/letsencrypt/live/YOURDOMAIN/cert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/letsencrypt/live/YOURDOMAIN/privkey.pem
-
add: olcTLSProtocolMin
olcTLSProtocolMin: 3.3

Прочтите в файле ldif ...

ldapmodify -Y EXTERNAL -H ldapi:/// -f add_ssl.ldif

Наконец перезапустите и проверьте slapd.

systemctl restart slapd.service
systemctl status slapd.service

Включены ли у вас какие-либо дополнительные меры безопасности (например, apparmor), которые ограничивают доступ для чтения к вашим сертификатам? У меня такое же сообщение об ошибке ldap_modify: Other (e.g., implementation specific) error (80) потому что apparmor не разрешил openldap доступ к сертификатам Let's encrypt:

Следующие шаги решили проблему для меня:

  • Добавить строку в /etc/apparmor.d/local/usr.sbin.slapd: /etc/letsencrypt/** r,

  • service apparmor restart

На вашем сервере OpenLDAP не настроен TLS.

Ваш /etc/ldap/slapd.d/cn=config.ldif должно получиться что-то вроде следующего:

olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap.key
olcTLSCACertificateFile: /etc/ldap/ssl/ldap_ca.cert
olcTLSCertificateFile: /etc/ldap/ssl/ldap.cert
olcTLSCipherSuite: HIGH:!aNull:!MD5:@STRENGTH
olcTLSProtocolMin: 3.1

Вы должны добавить это через ldapmodify.

У меня была такая же проблема с настройкой сертификатов от Позволяет зашифровать с участием OpenLDAP

Ошибка:

~ # ldapmodify -Y EXTERNAL -H ldapi:/// -f add_ssl.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"
ldap_modify: Other (e.g., implementation specific) error (80)

Файлы журнала содержат:

... apparmor="DENIED" operation="open" profile="/usr/sbin/slapd" name="/etc/letsencrypt/archive/your.domain.tld/fullchain1.pem" ...

Я нашел следующее решение:

  1. Редактировать файл /etc/apparmor.d/usr.sbin.slapd
  2. Добавить строку: /etc/letsencrypt/archive/your.domain.tld/* r,
  3. Начать сначала *apparmor*:перезапуск сервисного приложения
  4. А теперь выполните ldapmodify очередной раз

У меня была та же проблема, и через несколько часов я нашел простейшее решение: скопировать файлы pem в / etc / openldap / certs и использовать fullchain.pem для olcTLSCACertificateFile. (Корневой центр сертификации не нужен). Также важно: права доступа olcTLSCertificateFile и olcTLSCertificateKeyFile должны быть 644 ldap ldap и 600 ldap ldap соответственно.

Возможный сценарий для этого будет выглядеть примерно так, чтобы упростить автоматизацию:

- hosts: ldap
  gather_facts: false
  become: true
  tasks:
    - name: Copy cert.pem
      copy: 
        src: "/mnt/data/main/ansible/letsencrypt/config/live/appdev.elabs.svcs.entsvcs.com/cert.pem"
        dest: "/etc/openldap/certs/olcTLSCertificateFile"
        backup: yes
        owner: ldap
        group: ldap
        mode: '0644'
    - name: Copy fullchain.pem
      copy: 
        src: "/mnt/data/main/ansible/letsencrypt/config/live/appdev.elabs.svcs.entsvcs.com/fullchain.pem"
        dest: "/etc/openldap/certs/olcTLSCACertificateFile"
        backup: yes
        owner: root
        group: root
        mode: '0644'
    - name: Copy privkey.pem
      copy: 
        src: "/mnt/data/main/ansible/letsencrypt/config/live/appdev.elabs.svcs.entsvcs.com/privkey.pem"
        dest: "/etc/openldap/certs/olcTLSCertificateKeyFile"
        backup: yes
        owner: ldap
        group: ldap
        mode: '0600'

Мне это удалось, когда я сменил "живой" путь на "архив":

dn: cn=config
changetype: modify
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/letsencrypt/archive/SOMEDOMAIN/fullchain1.pem
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/letsencrypt/archive/SOMEDOMAIN/cert1.pem
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/letsencrypt/archive/SOMEDOMAIN/privkey1.pem

и позволяя пользователю openldap читать эти файлы, используя, например: setfacl -m "u: openldap: r" /etc/letsencrypt/archive/SOMEDOMAIN/{fullchain1,cert1,privkey1}.pem

вам вообще не нужно настраивать CA, когда у вас есть fullchain.pem, потому что этот файл уже содержит корневой CA, промежуточные звенья и сертификат сервера.

Использовать fullchain.pem так как olcTLSCertificateFile и privkey.pem как olcTLSCertificateKeyFile.

Если вы получили ошибку 80 => (Другая (например, ошибка реализации) (80)):

  1. Важно изменить оба атрибута одним ldapmodify (это не сработает, если вы установите сначала olcTLSCertificateKeyFile, а затем olcTLSCertificateFile, и наоборот)
  2. проверьте, что режим файла privkey.pem равен 600, владельцем является ваш SLAPD_USER и что SLAPD_USER может читать файл по полному пути.
  3. проверьте, является ли режим файла fullchain.pem 644, владельцем является ваш SLAPD_USER и что SLAPD_USER может читать файл по полному пути.
  4. проверьте, блокируют ли apparmor, selinux и т. д. доступ для SLAPD_USER

напишите файл ldapmodify - ssl.mod:

dn: cn=config
changetype: modify
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /path/to/your/letsencrypt/privkey.pem
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /path/to/your/letsencrypt/fullchain.pem

применить конфигурацию:

ldapmodify -Y EXTERNAL -H ldapi:/// -f ssl.mod

И что самое интересное, вы можете использовать последнюю команду как certbot --deploy-hook и повернуть сертификат без перезапуска slapd при возобновлении.