Всем бобра, друзья ;). Сегодня я расскажу вам о таком чуде чудном, как LDAP сервер и куда его можно пихать И так, немного теории OpenLDAP - открытая реализация LDAP (Lightweight Directory Access Protocol — «облегчённый протокол доступа к каталогам», как написано в Wiki - LDAP — относительно простой протокол), разработанная проектом OpenLDAP Project. Собственно структура следующая – есть несколько атрибутов с уникальными именами DN, пример: “CN= Вася Писькин, ou=Руководство, dc=sharaga, dc=com”. Уникальное имя состоит из нескольких - RDN (относительно уникальных имен) разделённых запятой. На одном уровне не может существовать двух записей с одинаковыми RDN. Это что касается LDAP и как можно понять из названия OpenLDAP – это его бесплатный (там своя лицензия) брат близнец для Linux. Ну и пора в бой ))) Я как и всегда пользуюсь nano
1 | yum install -y wget nano mc make |
Как обычно, ставим все что нам нужно.
1 | yum -y install openldap openldap-servers openldap-clients python python-ldap nss_ldap |
Ставим наш замечательный OpenLDAP, Python и nss_ldap – как модуль авторизации.
1 2 | cp /etc/openldap/slapd.conf /etc/openldap/slapd.conf.orig cp /etc/openldap/ldap.conf /etc/openldap/ldap.conf.orig |
Делаем backup оригинальных файликов, на всякий случай.
1 | slappasswd |
Генерим себе пароль. Выхлоп будет приблизительно такой
1 | {SSHA}s5FJ446MhK6AMqu50vOAxa9m1eNHZ981f |
Это введенный вами пароль зашифрованный в SSHA. Сохраните его, он нам еще пригодиться.
1 | nano /etc/openldap/slapd.conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | ####################################################################### # Global Directives: include /etc/openldap/schema/core.schema //Обратите внимание на количество схем. include /etc/openldap/schema/cosine.schema include /etc/openldap/schema/inetorgperson.schema pidfile /var/run/openldap/slapd.pid argsfile /var/run/openldap/slapd.args loglevel none #modulepath /usr/lib/ldap //Скорее всего у вас не закомментировано #moduleload back_hdb //Скорее всего у вас не закомментировано // Весь прикол в том, что modulepath и moduleload определяют модуль работы с базой данных, но так // как в CentOS он лежит не по тому пути, а искать его мне было лень и это не является критичным // параметром, то просто комментируем эти строки sizelimit 500 tool-threads 1 backend hdb // Вот почему не надо ))) ####################################################################### # Specific Directives for database #1, of type hdb: database hdb // Тип БД directory "/var/lib/ldap" // Путь к БД dbconfig set_cachesize 0 2097152 0 dbconfig set_lk_max_objects 1500 dbconfig set_lk_max_locks 1500 dbconfig set_lk_max_lockers 1500 index objectClass eq lastmod on # If you change the suffix, change all the "localhost" you find below as well! suffix "dc=test,dc=local" # Please change the password with the result of "slappasswd" rootdn "cn=Manager,dc=test,dc=local" // В моем случае суперпользователь Manager, но вы // можете и другово установить rootpw {SSHA}FmDp1XRguGQ0Ic4LGNpqmezdeJ3+nZCy // Наш пароль, вы ведь его не забыли? checkpoint 512 30 # Я делаю книгу для roundcube, и здесь описываю ее приватную часть access to dn.one="ou=private,ou=rcabook,dc=test,dc=local" attrs=userPassword by dn="cn=rcuser,ou=rcabook,dc=test,dc=local" write by anonymous auth by self write by * none # Для аутентификации и смены пароля access to attrs=userPassword by dn="cn=Manager,dc=test,dc=local" write by anonymous auth by self write by * none # Даем доступ к приватной книге прошедшим проверку пользователям. access to dn.regex="^.*cn=([^,]+),ou=private,ou=rcabook,dc=test,dc=local$" by dn="cn=Manager,dc=test,dc=local" write by dn="cn=rcuser,ou=rcabook,dc=test,dc=local" write by dn.exact,expand="cn=$1,ou=private,ou=rcabook,dc=test,dc=local" write # Даем доступ Roundcube пользователям ко всей адресной книге access to dn.subtree="ou=rcabook,dc=test,dc=local" by dn="cn=Manager,dc=test,dc=local" write by dn="cn=rcuser,ou=rcabook,dc=test,dc=local" write # Ну и доступ на директорию access to * by dn="cn=Manager,dc=test,dc=local" write |
Вносим необходимые изменения. Полный man по этому файлику вы можете найти здесь. Собственно – это все что касается OpenLDAP, осталось попробовать его запустить.
1 2 | service ldap start ldapsearch -xLLL -H ldap://localhost:389 -D cn=Manager,dc=test,dc=local -W -b dc=test,dc=local |
И проверить доступность. Выхлоп должен быть таким:
1 2 | Enter LDAP Password: No such object (32) |
Если все ОК, то теперь нам нужен скриптик, дабы создать наш каталог.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | nano ./rcabook-setup.sh #!/bin/bash # url нашего openldap сервера server="ldap://localhost:389"; # путь к конфиг файлу config="/etc/openldap/slapd.conf"; # Суффикс и аккаунт к ldap серверу, должен совпадать с slapd.conf suffix="dc=test,dc=local"; rootdn="cn=Manager,$suffix"; organisation="Addressbook Server"; # Связываем пользователя и пароль /bind_* поля должны соответствовать /main.inc.php abook_name="rcabook"; abook_user="rcuser"; abook_pass="rcpass"; base_dn="ou=$abook_name,$suffix"; bind_dn="cn=$abook_user,$base_dn"; bind_pass="$abook_pass"; subdir_public="public"; subdir_private="private"; echo "Этот сценарий готовит сервер OpenLDAP для адресной книги с Roundcube: server: $server org : $organisation config: $config suffix: $suffix rootdn: $rootdn "; # Проверяем, имеет ли пользователь доступ на чтение файла конфигурации slapacl -f $config -D $rootdn -b $suffix ou/write 2>&1 | grep -q "Permission denied" && { echo "Вы не можете получить доступ к файлу, выполните скрипт от root"; exit 1; } # Проверка на наличие корневого суффикса slapacl -f $config -D $rootdn -b $suffix ou/write 2>&1 | grep -q -E "ALLOWED|DENIED" || { echo -n "-создаем корневой суффикс: $suffix (как LDAP root: $rootdn) "; suffix_short=${suffix%,*}; echo " dn: $suffix objectClass: top objectClass: dcObject objectClass: organization ${suffix_short%=*}: ${suffix_short#*=} o: $organisation " | ldapadd -x -c -H $server -D $rootdn -W 2> /dev/null || { echo "ERROR-невозможно создать корневой суффикс!"; exit 1; }; } # Проверка имеет ли root LDAP право на запись slapacl -f $config -D $rootdn -b $suffix ou/write 2>&1 | grep -q "ALLOWED" || { echo "ERROR-root \"$rootdn\" неимеет право записи в \"$suffix\"! Проверьте rootdn и суффикс, они должны соответствовать файлу настроек /etc/openldap/slapd.conf "; exit 1; } # Проверка, существует ли каталог адресной книги slapacl -f $config -D $rootdn -b $base_dn ou/write 2>&1 | grep -q "ALLOWED" || { echo -n "-создаем каталог адресной книги: $base_dn (как LDAP root: $rootdn) "; echo " dn: $base_dn ou: $abook_name objectClass: top objectClass: organizationalUnit " | ldapadd -x -c -H $server -D $rootdn -W 2> /dev/null || { echo "ERROR-невозможно создать базу!"; exit 1; }; } # Проверка, наличия пользователя в адресной книге (не знаю как правильно сформировать) slapacl -f $config -D $rootdn -b $bind_dn cn/write 2>&1 | grep -q "ALLOWED" || { echo -n "-создаем пользователя адресной книги: $bind_dn (как LDAP root: $rootdn) "; echo " dn: $bind_dn cn: $abook_user userPassword: `slappasswd -s $abook_pass` objectClass: organizationalRole objectClass: simpleSecurityObject " | ldapadd -x -c -H $server -D $rootdn -W 2> /dev/null || { echo "ERROR-невозможно создать пользователя!"; exit 1; }; } # Проверка на право записи для пользователя адресной книги slapacl -f $config -D $bind_dn -b $base_dn ou/write 2>&1 | grep -q "ALLOWED" || { echo "ERROR-пользователь адресной книги \"$bind_dn\" не имеет прав на запись \"$base_dn\"! Проверьте ACL в файле конфигурации /etc/openldap/slapd.conf. После чего перезагрузите сервер LDAP "; exit 1; } # Создаем поддиректорию public contacts slapacl -f $config -D $bind_dn -b "ou=$subdir_public,$base_dn" ou/write 2>&1 | grep -q "ALLOWED" || { echo "-создаем поддиректорию public contacts: ou=$subdir_public,$base_dn (как пользователь Roundcube: $bind_dn)"; echo " dn: ou=$subdir_public,$base_dn ou: $subdir_public objectClass: top objectClass: organizationalUnit " | ldapadd -x -H $server -D $bind_dn -w $bind_pass 2> /dev/null || { echo "ERROR-невозможно создать директорию!"; exit 1; }; } # Создаем поддиректорию private contacts slapacl -f $config -D $bind_dn -b "ou=$subdir_private,$base_dn" ou/write 2>&1 | grep -q "ALLOWED" || { echo "-создаем поддиректорию private contacts: ou=$subdir_private,$base_dn (как пользователь Roundcube: $bind_dn)"; echo " dn: ou=$subdir_private,$base_dn ou: $subdir_private objectClass: top objectClass: organizationalUnit " | ldapadd -x -H $server -D $bind_dn -w $bind_pass 2> /dev/null || { echo "ERROR-невозможно создать директорию!"; exit 1; }; } # Концовка, вот почти почти echo "Адресная книга LDAP готова к использованию: base_dn: $base_dn bind_dn: $bind_dn Используйте следующую команду для чтения и проверки вашей базы: ldapsearch -xLLL -H $server -D $bind_dn -w $bind_pass -b $base_dn"; |
Далее даем права и выполняем ))) Если возникнут проблемы, проверьте кавычки, все таки с сайта копируем.
1 2 | chmod 777 ./rcabook-setup.sh ./rcabook-setup.sh |
Если все ок, то как и советовалось, проверяем нашу установку
1 | ldapsearch -xLLL -H ldap://localhost:389 -D cn=rcuser,ou=rcabook,dc=test,dc=local -w rcpass -b ou=rcabook,dc=test,dc=local |
Выхлоп у нас такой
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | dn: ou=rcabook,dc=localhost ou: rcabook objectClass: top objectClass: organizationalUnit dn: cn=rcuser,ou=rcabook,dc=test,dc=local cn: rcuser userPassword:: e1NTSEF9L3NGVmQzTlFud1IvbXNYN0ZDUTV0cjBiUWIyK3RxY0g= objectClass: organizationalRole objectClass: simpleSecurityObject dn: ou=public,ou=rcabook,dc=test,dc=local ou: public objectClass: top objectClass: organizationalUnit dn: ou=private,ou=rcabook,dc=test,dc=local ou: private objectClass: top objectClass: organizationalUnit |
А какой у вас? Теперь нам нужно проверить, можем ли мы цепляться к нашему LDAP серверу. Для этого у нас есть такая замечательная программка как LdapAdmin. Если все ОК, то наша задача, настроить Roundcube.
1 | find / -name main.inc.php |
Находим необходимый нам файлик. Обычно он лежит по пути:
1 | /var/www/roundcubemail/config/main.inc.php |
Но мало ли как у вас будет настроено.
1 | nano /var/www/roundcubemail/config/main.inc.php |
Находим в нем строчку
1 | rcmail_config['ldap_public'] |
Скорее всего она закомментирована так как существует там в качестве примера, наша задаче ее немного поправить
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | $rcmail_config['ldap_public']['TEST'] = array( 'name' => 'TEST', 'hosts' => array('localhost'), 'port' => 389, 'use_tls' => false, 'user_specific' => false, // По умолчанию логин пользователя. 'base_dn' => 'ou=public,ou=rcabook,dc=test,dc=local', 'bind_dn' => 'cn=rcuser,ou=rcabook,dc=test,dc=local', 'bind_pass' => 'rcpass', 'writable' => true, // Определяем, что мы можем писать в каталог, внимание к полям: // LDAP_Object_Classes, required_fields, LDAP_rdn 'LDAP_Object_Classes' => array("top", "inetOrgPerson"), // Какой объект используется для создания нового класса 'required_fields' => array("cn", "sn", "mail"), // Обязательные к заполнению поля. 'LDAP_rdn' => 'mail', // RDN поле, для новой записи, должно содержаться в search_fields, определяет индекс для поиска в каталоге. 'ldap_version' => 3, // используется ли LDAPv3 'search_fields' => array('mail', 'cn'), // Поля для поска в каталоге. 'name_field' => 'cn', // Отображаемое имя контакта 'email_field' => 'mail', // E-mail контакта 'surname_field' => 'sn', // Фамилия контакта 'firstname_field' => 'gn', // Имя контакта 'sort' => 'cn', // Поле для сортировки списка. 'scope' => 'sub', // тип поиска: sub|base|list 'filter' => '(mail=*)',// фильтр, не знаю как по русски описать))) 'fuzzy_search' => true); // Разрешается поиск по маске. |
По аналогии. Делаем для private.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $rcmail_config['ldap_public']['private'] = array( 'name' => 'Private Addressbook', 'hosts' => array('localhost'), 'port' => 389, 'use_tls' => false, 'user_specific' => true, 'base_dn' => 'cn=%u,ou=private,ou=rcabook,dc=test,dc=local', 'bind_dn' => 'cn=%u,ou=private,ou=rcabook,dc=test,dc=local', 'bind_pass' => '', // пароль входа в систему 'ldap_version' => 3, 'filter' => '(objectClass=inetOrgPerson)', 'groups' => array( 'base_dn' => '', 'filter' => '(objectClass=groupOfNames)', 'object_classes' => array("top", "groupOfNames"), ), ); |
Я упростил, до минимума, но вы можете построить более сложную систему, дописав необходимые поля в этот файл, не забудьте добавить их в каталог. Собственно все, ребутимся и
Добавить комментарий