Что такое TLS можно почитать тут>>>.
Наша задача — обеспечить шифрование между LDAP-сервером и его клиентом — phpLdapAdmin. Хотя они и работают в данном случае на одном хосте — но даже в таком случае это имеет смысл, особенно — если на сервере имеются учётные записи для других пользователей с доступом к консоли. Почему — будет показано в конце.
Настройка выполняется на:
# uname -ro FreeBSD 9.1-RELEASE-p5
В роли LDAP-сервера установлен:
# pkg_info | grep openldap openldap-client-2.4.38 Open source LDAP client implementation openldap-server-2.4.38_1 Open source LDAP server implementation
И:
# pkg_info | grep ldapadmin phpldapadmin-1.2.3_2,1 PHP application to administer LDAP over the web
Про установку OpenLDAP на FreeBSD можно почитать тут>>>.
Первым делом — генерируем необходимые ключи.
Кратко:
key
— приватный ключ сервера;
csr
— certificate signing request, файл запроса для получения подписанного сертификата;
crt
— собственно, сам сертификат сервера, он же — публичная часть ключа key
.
Создаём ключ:
# openssl genrsa -out slapd.key Generating RSA private key, 512 bit long modulus ...........++++++++++++ ..........++++++++++++ e is 65537 (0x10001)
Создаём файл csr
, который сами же потом подпишем.
Важно: в Common Name
крайне рекомендуется указывать полное имя домена сервера:
# openssl req -new -key slapd.key -out slapd.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:UA State or Province Name (full name) [Some-State]: Locality Name (eg, city) []:Kiev Organization Name (eg, company) [Internet Widgits Pty Ltd]:ServerName Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:domain.in.ua Email Address []:[email protected] Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
Создаём и подписываем сертификат:
# openssl x509 -req -in slapd.csr -days 365 -signkey slapd.key -out slapd.crt Signature ok subject=/C=UA/ST=Some-State/L=Kiev/O=Domain/CN=domain.in.ua/[email protected] Getting Private key
Создаём каталог, в котором будут храниться файлы:
# mkdir /home/domain/.ssh
# mv slapd.* /home/domain/.ssh
# chown -R ldap:ldap /home/domain/.ssh/
# chmod -R 500 /home/domain/.ssh/
Будьте внимательны с правами доступа к директории — не забывайте, что для доступа в неё требуется бит выполнения.
Например — если директория .ssh
открыта всем:
# ls -la ../ | grep ssh drwxr-xr-x 5 setevoy setevoy 512 Feb 16 18:33 .ssh
А ключи будут храниться во вложенной директории, и на неё у пользователя не будет права на выполнение:
# ls -l | grep slapd dr-------- 2 ldap ldap 512 Feb 16 18:31 slapd
То LDAP не запустится:
# service slapd restart Stopping slapd. Waiting for PIDS: 41615. Starting slapd. /usr/local/etc/rc.d/slapd: WARNING: failed to start slapd
Переходим к настройке самого сервера OpenLDAP:
# vim /usr/local/etc/openldap/slapd.conf
Раскомментируем строку:
security ssf=1 update_ssf=112 simple_bind=64
Тут:
ssf=1
— требовать шифрование;
update_ssf=112
— использовать 112-bit шифрование для операций с обновлениями записей;
simple_bind=64
— использовать 64-bit шифрвание при простой аутентификации.
Далее добавляем указание пути к используемым файлам:
TLSCertificateFile /home/domain/.ssh/slapd.crt TLSCertificateKeyFile /home/domain/.ssh/slapd.key TLSCACertificateFile /home/domain/.ssh/slapd.crt
Сохраняем, выходим и проверяем корректность файла конфигурации:
# slaptest -u config file testing succeeded
Перезапускаем сервер:
# service slapd restart Stopping slapd. Waiting for PIDS: 61268. Starting slapd.
# service slapd status slapd is running as pid 61294.
Можно уже проверить — работает ли наш TLS на стороне сервера. Для этого — попробуем добавить ldif
-файл с помощью ldapadd
и ключём -Z
, который явно указывает использовать TLS:
# ldapadd -Z -x -D "cn=root,dc=domain" -W -f base.ldif ldap_start_tls: Connect error (-11) additional info: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (self signed certificate) Enter LDAP Password: ldap_result: Can't contact LDAP server (-1)
Редактируем настройки ldap-клиента openldap-client-2.4.38
, который устанавливается вместе с самим сервером и который используется phpLdapAdmin для подключения к серверу:
# vim /usr/local/etc/openldap/ldap.conf
Указываем корневую запись каталога (suffix
в конфигурации LDAP-демона — /usr/local/etc/openldap/slapd.conf
):
BASE dc=domain URI ldap://localhost
Указываем о необходимости использования TLS:
ssl start_tls
И путь к публичной части ключа сервера:
tls_cacert /home/domain/.ssh/slapd.crt
И снова проверяем:
# ldapadd -Z -x -D "cn=root,dc=domain" -W -f base.ldif
Если получаем ошибку такого плана:
# ldapadd -Z -x -D "cn=root,dc=domain" -W -f base.ldif ldap_start_tls: Connect error (-11) Enter LDAP Password: ldap_result: Can't contact LDAP server (-1)
Добавьте ключи -d -1
что бы запустить ldapadd
в debug
-режиме и увидеть точное описание ошибки:
# ldapadd -Z -d -1 -x -D "cn=root,dc=domain" -W -f base.ldif ... ldap_msgfree TLS: could not load verify locations (file:`/home/domain/.ssh/slapd.csr',dir:`').
Сначала — проверьте права на доступ к каталогу/файлу публичного сертификата. Если всё в порядке — замените tls_cacert
на tls_cacertdir
, и укажите не путь к самому файлу — а путь к директории:
tls_cacertdir /home/domain/.ssh/
Ещё одна возможная ошибка выглядит так:
# ldapadd -Z -x -D "cn=root,dc=domain" -W -f base.ldif ldap_start_tls: Connect error (-11) additional info: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (self signed certificate)
Так как в данному случае используется самоподписанный сертификат — добавте опцию tls_reqcert
и отключите вообще запрос на проверку валидности сертификата (never
), либо установите в try
опцию tls_reqcert
:
tls_reqcert never
В итоге — файл /usr/local/etc/openldap/ldap.conf
будет иметь примерно такой вид:
BASE dc=domain URI ldap://localhost ssl start_tls tls_cacertdir /home/domain/.ssh/ tls_reqcert never
Сохраняем, переходим к настройке phpLdapAdmin:
# cd /usr/local/www/phpldapadmin/config/ # vim config.php
Раскомментируем и редактируем строки:
$servers->setValue('server','host','127.0.0.1'); $servers->setValue('server','port',389);
Чуть ниже находим строку:
// $servers->setValue('server','tls',false);
И меняем false
(отключено) на true
:
$servers->setValue('server','tls',true);
Сохраняем.
Теперь — немного о том, зачем включать шифрование.
Первый пример — без использования TLS.
Запускаем tcpdump
с ключём -X
(выводить содержимое перехваченных пакетов), и подключаемся к серверу с аутентификацией, например:
# ldapsearch -D "cn=root,dc=domain" -w PASSWORD
Или — просто заходим через phpLdapAdmin.
В результатах tcpdump
видим:
# tcpdump -i lo0 -X -s 1024 port 389 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo0, link-type NULL (BSD loopback), capture size 1024 bytes ... ..1. 13:24:56.434552 IP localhost.36413 > localhost.ldap: Flags [P.], seq 1:45, ack 1, win 1120, options [nop,nop,TS val 296891025 ecr 2568106421], length 44 0x0000: 4500 0060 ddab 4000 4006 0000 7f00 0001 E..`..@.@....... 0x0010: 7f00 0001 8e3d 0185 c8ee eea7 6886 d0f3 .....=......h... 0x0020: 8018 0460 fe54 0000 0101 080a 11b2 3291 ...`.T........2. 0x0030: 9912 31b5 302a 0201 0160 2502 0103 0414 ..1.0*...`%..... 0x0040: 636e 3d72 6f6f 742c 6463 3d66 7265 6570 cn=root,dc=doma 0x0050: 726f 7879 800a 4e30 7761 7272 616e 7479 in..PASSWORD
В последних двух строках видно, что во время аутентификации логин/пароль передаются в открытом виде.
Теперь — повторяем ту же операцию, но уже с активным TLS:
13:26:22.928932 IP localhost.63566 > localhost.ldap: Flags [P.], seq 32:171, ack 15, win 1120, options [nop,nop,TS val 296977517 ecr 3091728088], length 139 0x0000: 4500 00bf de6b 4000 4006 0000 7f00 0001 E....k@.@....... 0x0010: 7f00 0001 f84e 0185 4c26 bbcc 8a1e 9387 .....N..L&...... 0x0020: 8018 0460 feb3 0000 0101 080a 11b3 846d ...`...........m 0x0030: b848 06d8 8089 0103 0100 6000 0000 2000 .H........`..... 0x0040: 0039 0000 3800 0035 0000 8800 0087 0000 .9..8..5........ 0x0050: 8400 0016 0000 1300 000a 0700 c000 0033 ...............3 0x0060: 0000 3200 002f 0000 4500 0044 0000 4103 ..2../..E..D..A. 0x0070: 0080 0000 0500 0004 0100 8000 0015 0000 ................ 0x0080: 1200 0009 0600 4000 0014 0000 1100 0008 ......@......... 0x0090: 0000 0604 0080 0000 0302 0080 0000 ff3f ...............? 0x00a0: 12e4 7ae2 0157 103b 9f51 f49a 5eb5 80ad ..z..W.;.Q..^... 0x00b0: ac52 b8e0 ccce f91e 02ed a903 97af d2 .R.............
Логина/пароля уже не видно, что и требовалось.
При включенном TLS-шифровании — для консольных утилит необходимо использовать ключ -Z
:
# ldapsearch -Z -b 'dc=domain' 'uid=sysuser' | tail -n 1 # numResponses: 1