Электронные подписи и централизованная адресная книга в каталоге LDAP.

Автор: Афлетдинов Андрей
Оригинал: andrek.ipsp.ru

В организации стал вопрос по созданию корпоративной почты с поддержкой электронных сертификатов пользователей.
Имеем внутренний настроенный dns с доменом domain.ru
Сервер где поднимаем LDAP называем ldap.domain.ru

Создание сертификата организации

openssl genrsa -des3 -out ca.key 2048 openssl req -new -x509 -days 1825 -utf8 -key ca.key -out ca.cert

Создание пользовательского подписанного сертификата
openssl genrsa -out user.key 1024 openssl req -new -key user.key -out user.csr -utf8 openssl x509 -req -in user.csr -out user.cert -CA ca.cert -CAkey ca.key -CAcreateserial -days 1095

Приватный ключ ca.key надежно сохраняем, а публичный ключ ca.cert в дальнейшем распространим по машинам и пользователям.
По умолчанию в системе RedHat:

Большая часть сетевых служб использует сертификат формата service.pem
Формат этого файла подразумевает оба ключа (публичный и приватный) в одном файле: cat service.key > service.pem cat service.cert >> service.pem

В системе установлен пакет:

Вся настройка проводилась именно для ветки 2.2 OpenLDAP.

Настройка серверной части openldap

Файл конфигурации /etc/openldap/slapd.conf по умолчанию,
из опций добавлено:

TLSCertificateFile /usr/share/ssl/private/slapd.pem TLSCertificateKeyFile /usr/share/ssl/private/slapd.pem TLSCACertificateFile /usr/share/ssl/certs/ca.cert suffix "dc=domain,dc=ru" rootdn "cn=admin,dc=domain,dc=ru" Генерируем публичный и приватный ключ как описано выше.
Отвечаем на вопросы, не забываем про самый главный ответ (в моей системе было так) Common Name (eg, YOUR name) []: ldap.domain.ru Устанавливаем права: chmod 440 /usr/share/ssl/private/slapd.pem chown .ldap /usr/share/ssl/private/slapd.pem Запускаем service ldap start Проверяем netstat -atn | grep LISTEN tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:636 0.0.0.0:* LISTEN Отлично! Редактируем строку запуска сервиса в файле /etc/rc.d/init.d/ldap (для систем RedHat) #daemon ${slapd} -u ldap -h 'ldap:/// ldaps:///' $OPTIONS $SLAPD_OPTIONS daemon ${slapd} -u ldap -h 'ldaps:///' $OPTIONS $SLAPD_OPTIONS Командуем service ldap restart netstat -atn | grep LISTEN Результат: tcp 0 0 0.0.0.0:636 0.0.0.0:* LISTEN Это то, что нам нужно!

Настройка клиентской части openldap

Файл конфигурации /etc/openldap/ldap.conf, добавляем:

BASE dc=domain,dc=ru URI ldaps://ldap.domain.ru TLS_CACERT /usr/share/ssl/certs/ca.cert Создадим базовый ldif файл, с содержанием: dn: dc=domain,dc=ru objectClass: dcObject objectClass: organization dc: domain o: Organization dn: cn=admin,dc=domain,dc=ru objectClass: organizationalRole cn: admin description: Administrator LDAP И добавим его в базу: ldapadd -D"cn=admin,dc=domain,dc=ru" -W -x -f base.ldif Enter LDAP Password: adding new entry "dc=domain,dc=ru" adding new entry "cn=admin,dc=domain,dc=ru" Таким образом имеем работающие ldap сервер и клиент с SSL поддержкой.

Авторизация LDAP

Настраиваем на примере клиентскую систему с именем redhat72.domain.ru
Так же в системе провели настройку клиентской части openldap, как описано выше.
В системе установлен пакет:

Файл конфигурации /etc/nsswitch.conf, изменяем строки: passwd: files ldap shadow: files ldap group: files ldap Файл конфигурации /etc/ldap.conf:

host ldap.domain.ru base dc=domain,dc=ru rootbinddn cn=login,dc=domain,dc=ru scope one nss_base_passwd ou=users,dc=domain,dc=ru?one nss_base_shadow ou=users,dc=domain,dc=ru?one nss_base_group ou=group,dc=domain,dc=ru?one ssl yes В файл конфигурации /etc/openldap/slapd.conf на сервере ldap.domain.ru добавляем необходимые схемы include /etc/openldap/schema/cosine.schema include /etc/openldap/schema/nis.schema include /etc/openldap/schema/inetorgperson.schema Создаем ниже пользователя login, которому доступны необходимые данные для чтения, для этого определим права ACL:
access to attr=userPassword by self write by anonymous auth by dn.base="cn=admin,dc=domain,dc=ru" write by dn.base="cn=login,dc=domain,dc=ru" read by * none access to attr=userPKCS12 by self write by anonymous auth by dn.base="cn=admin,dc=domain,dc=ru" write by * none access to * by self write by dn.base="cn=admin,dc=domain,dc=ru" write by * read Файл login.ldif: dn: cn=login,dc=domain,dc=ru objectClass: top objectClass: person cn: login sn: login userPassword: {CRYPT}lVT9EK/cNnd/2 Для генерации хеша пароля, используем команду: slappasswd -h{crypt} Так же и в файле /etc/ldap.secret необходимо сохранить етот пароль.
Далее сохраняем все в базу: ldapadd -D"cn=admin,dc=domain,dc=ru" -W -x -f login.ldif Enter LDAP Password: adding new entry "cn=login,dc=domain,dc=ru" Создаем две группы, файл group.ldif: dn: ou=users,dc=domain,dc=ru objectClass: top objectClass: organizationalUnit ou: users dn: ou=group,dc=domain,dc=ru objectClass: top objectClass: organizationalUnit ou: group Сохраняем в базе: ldapadd -D"cn=admin,dc=domain,dc=ru" -W -x -f group.ldif Enter LDAP Password: adding new entry "ou=users,dc=domain,dc=ru" adding new entry "ou=group,dc=domain,dc=ru" Создаем пользователя nikolas: dn: cn=nikolas,ou=users,dc=domain,dc=ru objectClass: top objectClass: account objectClass: posixAccount objectClass: shadowAccount cn: nikolas uid: nikolas uidNumber: 3001 gidNumber: 3001 homeDirectory: /home/nikolas loginShell: /bin/bash userPassword: {CRYPT}Dre676jtUt6tg dn: cn=nikolas,ou=group,dc=domain,dc=ru objectClass: top objectClass: posixGroup cn: nikolas gidNumber: 3001 memberUid: nikolas Заносим в базу, стандартной последовательностью команд.
Проверяем стандартной последовательностью команд, в списках пользователей и групп должны быть и наши данные: [test@redhat72 test]$ getent passwd . . . . test:x:500:500::/home/test:/bin/bash sandy:x:3001:3001:sandy:/home/sandy:/bin/bash nikolas:x:3002:3002:nikolas:/home/nikolas:/bin/bash [test@redhat72 test]$ getent shadow sandy:x:::::::0 nikolas:x:::::::0 [test@redhat72 test]$ getent group . . . . test:x:500: sandy:x:3001:sandy nikolas:x:3002:nikolas [test@redhat72 test]$ Так же в файл /etc/pam.d/login, полезно добавить: session optional /lib/security/pam_mkhomedir.so umask=077 После этого можно подключиться пользователем nikolas локально в систему: Red Hat Linux release 7.2 (Enigma) Kernel 2.4.26-grsec on an i686 redhat72 login: nikolas Password: Creating directory '/home/nikolas'. [nikolas@redhat72 nikolas]$ cd .. [nikolas@redhat72 home]$ ls -la total 12 drwxr-x-r-x 3 root root 4096 May 5 15:56 . drwxr-x-r-x 19 root root 4096 May 5 10:00 .. drwx------- 2 nikolas nikolas 4096 May 5 15:50 nikolas После установки пакета: Желательно в файле /etc/ssh/sshd_config раскомментировать опцию: UsePAM yes После этих манипуляций также подключаемся и удаленно. [andrek@boss andrek]$ ssh -lnikolas redhat72 Password: Last login: Wed May 5 16:15:45 2004 [nikolas@redhat72 nikolas]$

Сервер электронной почты.

В системе установлены пакеты:

Настраиваем авторизацию в системе, как описано выше.
После этой процедуры, службы ( pop, imap, sendmail) будут работать с пользователями как с локальными.

Для включения встроенных функций поддержки ldap в sendmail, его необходимо собрать с поддержкой ldap, если используете стандартный из дистрибутива, то она присутствует по умолчанию.
Иначе при сборке необходимо в файл devtools/Site/site.config.m4 добавить строки: APPENDDEF(`confMAPDEF',`-DLDAPMAP') APPENDDEF(`confLIBS',`-lldap -llber -lldap_r') Добавляем поддержку необходимой схемы sendmail.shema в файл конфигурации slapd.conf на стороне сервера ldap.domain.ru. include /etc/openldap/schema/sendmail.schema Включаем альясы в файле конфигурации sendmail, путем определения параметров в файле sendmail.mc: define(`confLDAP_CLUSTER', `servers') define(`confLDAP_DEFAULT_SPEC',`-w 3 -H ldaps:///ldap.domain.ru -b ou=aliases,dc=domain,dc=ru') define(`ALIAS_FILE',`ldap:') Работоспособность альяса будет ограничена в рамках значения sendmailMTACluster = servers
Ключи -w (использовать протокол LdapV3) и -H появились именно в ветке 8.13.

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

На сайте предложено решение переопределить значение: define(`ALIAS_FILE',`ldap: -k (&(objectCla ... и т.д.
Но не смотря на многочисленные варианты у меня это не сработало, у кого хватило терпения разобраться в проблеме прошу поделиться вариантом решения.
Я поступил проще - добавил как служебных пользователей.

Для поддержки SSL при сборке необходимо в файл devtools/Site/site.config.m4 добавить строки: APPENDDEF(`confENVDEF',`-DSTARTTLS') И в файле конфигурации sendmail.mc определить: define(`confCACERT_PATH',`/usr/share/ssl/certs') define(`confCACERT',`/usr/share/ssl/certs/ca.cert') define(`confSERVER_CERT',`/usr/share/ssl/private/sendmail.pem') define(`confSERVER_KEY',`/usr/share/ssl/private/sendmail.pem') DAEMON_OPTIONS(`Port=smtps, Name=TLSMTA, M=s') И не забываем перегенерировать: m4 sendmail.mc > sendmail.cf Пакет imap-2004 рекомендую собирать также c поддержкой SSL: make lnp SSLDIR=/usr SSLCERTS=/usr/share/ssl/private

Соответственно в каталоге /usr/share/ssl/private должны быть сертификаты ipop3d.pem и imapd.pem .

Централизованная адресная книга, и пользовательские сертификаты в каталогах LDAP.
Краткое вступление:

Процесс этот утомительный, если в системе порядочное количество пользователей.
Я позволил себе написать (небольшой скрипт управления корпоративной почты) CGI сценарий, с помощью которого можно решать следующие задачи:

При добавлении пользователя, сертификаты автоматически добавляются в каталог LDAP.

Несколько скриншотов:

Взять можно здесь.
Настройка вся в файле конфигурации.
Система работает естественно с глюками :))
Планирую в дальнейшем добавить полную поддержку sendmail, а также более упрощеный вариант управления служб DNS и DHCP.

Небольшая информация о клиентских программах.

Замеченные ошибки, умные мысли и комментарии приветствуются!


Иркутск, лето 2004г. Андрей Афлетдинов