ejabberd с авторизацией через LDAP

Здесь описывается как поднять корпоративный jabber-сервер на основе eJabberd и использовать LDAP для аутентификации пользователей и управления учётными записями.

Исходные данные

— ОС: FreeBSD 5.4
— На сервере несколько сайтов, в т. ч. и сайт нашей компании с доменом company.ru (дабы не быть обвинённым в саморекламе — название изменено :-)
— LDAP-сервер на ldap.company.local (наши сервера объединены в локальную сеть company.local)
— ejabberd 1.1.4_2 (самая последняя версия в портах FreeBSD на момент установки)

Все указанные в заметке пути специфичны для FreeBSD, в других системах они могут быть иными.

Установка

Я устанавливал ejabberd из портов FreeBSD без каких-либо затруднений. Почитать про установку на других системах можно в Руководстве по ejabberd<.

Настройка

Важно понимать как ejabberd работает с настройками. У него есть два источника:

  1. БД с текущей конфигурацией (/var/spool/ejabberd/)
  2. Текстовые файлы (/usr/local/etc/ejabbrd/)

Так же имеется веб-интерфейс для управления. Так вот:

  • ejabberd использует конфигурацию, записанную в БД;
  • веб-интерфейс меняет данные только в БД;
  • конфигурационные файлы читаются только один раз при старте ejabberd;
  • конфигурационные файлы переписывают информацию в БД, но не всю, а только указанную часть (какую — см. ниже про override_XXX).

Из этого надо сделать два важных вывода:

  1. Изменения, внесённые через веб-интерфейс могут быть потеряны при перезапуске ejabberd
  2. Изменения, внесённые в конфигурационный файл могут не оказать влияния конфигурацию ejabberd

Понимание этого сэкономит много времени, нервов и волос на голове.

Немного о синтаксисе файлов конфигурации

Комментарии начинаются символом % и заканчиваются с концом строки.

Команды должны заканчиваться точкой.

Параметры указываются примерно так:

{параметр, значение}
<

Списки указываются в квадратных скобках. Элементы списка разделяются запятыми. После последнего элемента запятая не ставится.

На первое время этого хватит.

Начальная настройка

Первоначальная настройка производится редактированием файла /usr/local/etc/ejabberd/ejabberd.cfg<.

Первым делом надо указать, какую часть конфигурации (хранящейся в БД) мы хотим изменить. Для этого существует три команды:

  • override_global — глобальные параметры, касающиеся всех узлов в кластере (что такое кластер, на первых порах, не очень важно)
  • override_local — параметры только текущего узла (сервера)
  • override_acls — только параметры прав доступа

Веб-интерфейс я буду использовать только для просмотра, а не для редактирования настроек, поэтому пусть все настройки берутся из файла — очищаем всё:

override_global.
override_local.
override_acls.
<

Порты и сервисы

Следующий шаг — привязка сервисов ejabberd к TCP-портам и настройка этих сервисов. Всего есть четыре сервиса (или модуля):

  • ejabberd_c2s — обслуживает соединения клиентов с сервером
  • ejabberd_s2s_in — обслуживает входящие соединения от других jabber-серверов
  • ejabberd_service — взаимодействует с внешними компонентами (транспортами)
  • ejabberd_http — обслуживает HTTP-соединения

Вот что получилось у меня:

{listen, [
  % Клиент-сервер
  {5222, ejabberd_c2s, [
    starttls, {certfile, "./server.pem"}  % Используем StartTLS. Путь к сертификату указывает относительно
                                          % файла конфигурации. Сам сертификат server.pem создадим позже.
  ]},

  % Сервер-сервер. Если мы хотим общаться не только внутри нашего домена
  {5269, ejabberd_s2s_in, [
  ]},

  % HTTP-сервис
  {5280, ejabberd_http, [
    web_admin % Предоставлять веб-интерфейс
  ]}
]}.
<

Если мы хотим общаться не только друг с другом, но и с пользователями других серверов, надо провести дополнительную настройку соединений s2s:

{s2s_use_starttls, true}. % Использовать StartTLS для межсерверного общения
{s2s_certfile, "/usr/local/etc/ejabberd/server.pem"}. % Сертификат. создадим позже.
{outgoing_s2s_port, 5269}. % Не знаю точно что это, но без этого у меня не заработало :-)
<

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

{acl, admins, {user, "my_login", "company.ru"}}. % admins - произвольное имя списка, my_login - моя учётка в LDAP,
                                        % company.ru - виртуальный домен, на котором будет работать сервер
{access, configure, [{allow, admins}]}. % configure - разрешение на конфигурирование сервера, admins - имя списка
<

Настройка доменов

ejabberd может обслуживать несколько виртуальных доменов с различной конфигурацией. У меня в списке только один домен:

{hosts, ["company.ru"]}.
<

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

{host_config, "company.ru", [
...здесь я будут указывать параметры хоста company.ru...
]}.
<

Подключение к LDAP

В виртуальный хост добавляю команды:

{auth_method, ldap}, % Метод аутентификации - LDAP
{ldap_servers, ["ldap.company.local"]}, % Адрес LDAP-сервера
{ldap_port, 389}, % Его порт
{ldap_base, "ou=people,dc=company,dc=local"} % Базовый DN учётных записей пользователей
<

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

Для использования SSL понадобится сертификат.

В директории конфигурационных файлов (/usr/local/etc/ejabberd) выполняю следующие команды:

openssl req -newkey rsa:1024 -keyout server.pem -nodes -x509 -days 3650 -out server.cer
echo "" >> server.pem
cat server.cer >> server.pem
chown ejabberd:ejabberd server.pem
chmod 0400 server.pem
<

После этого файл server.cer можно безболезненно удалить.

Первый запуск

Этой конфигурации достаточно, чтобы проверить работу сервера. Выполняю /usr/local/etc/rc.d/ejabberd start< и смотрю лог /var/log/ejabberd/sasl.log<. Если в нём нет записей CRASH REPORT, значит сервер запустился нормально. Для проверки можно подключиться Jabber-клиентом к company.ru используя логин [email protected] (my_login — мой LDAP-логин, а company.ru — виртуальный хост, прописанный в ejabberd) и пароль из LDAP. Если не получается — надо проверить соединение с LDAP, ldap_base и, конечно же, логи.

У меня всё получилось с первой попытки. Теперь попробуем веб-интерфейс. В моей конфигурации он расположен по адресу:

http://company.ru:5280/admin/<

Для авторизации надо указать те же данные, что и при использовании Jabber-клиента.

Здесь можно зайти в «Виртуальные хосты — company.ru — Пользователи» и посмотреть список пользователей, которые могут пользоваться этим jabber-сервером.

UPD: Чтобы можно было посмотреть список, надо добавить в конфигурацию хоста строки:

{modules, [
  {mod_last, []},
  {mod_offline, []}
]}
<

Заключение

При работе с новой программой или технологией самое сложное — это начать. Лично меня поначалу смутил пример файла конфигурации, смутил непривычным синтаксисом и размерами. Да и документация, признаться, тоже. Поэтому я постарался создать минимальную конфигурацию, которая позволила хотя бы запустить сервер и подключиться к нему. Имея на руках работающий сервер, можно уже дальше настраивать его, навешивать модули, тюнинговать и так далее. Главное — твёрдый фундамент под ногами.

Надеюсь в ближайшее время у меня дойдут руки написать про дальнейшую настройку. А может, это сделает кто-то другой ;-)

Получившийся конфиг

%
% SHARED OPTIONS
%

% Override all settings

override_global.
override_local.
override_acls.

% Ports and services
{listen, [

        % Client to server
        {5222, ejabberd_c2s, [
                starttls, {certfile, "/usr/local/etc/ejabberd/server.pem"}
        ]},

        % Server to server
        {5269, ejabberd_s2s_in, [
        ]},

        % HTTP service
        {5280, ejabberd_http, [
                web_admin
        ]}

]}.

% Use STARTTLS+Dialback for S2S connections
{s2s_use_starttls, true}.
{s2s_certfile, "/usr/local/etc/ejabberd/server.pem"}.

% If SRV lookup fails, then port 5269 is used to communicate with remote server
{outgoing_s2s_port, 5269}.

% Webadmin access
{acl, admins, {user, "my_login", "company.ru"}}.
{access, configure, [{allow, admins}]}.

% Host config

{hosts, ["company.ru"]}.

%
% HOST: company.ru
%

{host_config, "company.ru", [

        {auth_method, ldap},
        {ldap_servers, ["ldap.company.local"]},
        {ldap_port, 389},
        {ldap_base, "ou=people,dc=3wstyle,dc=local"}

]}.
<

Несколько замечаний

Иногда, после аварийного завершения, ejabberd отказывается запускаться. Проверьте не висят ли процессы beam и empd или другие приложения erlang.

Чтобы управлять через веб-интерфейс всеми виртуальными доменами, запись {access, configure, ...} должна располагаться в глобальной области, а не в конфигурации виртуального хоста.

При использовании LDAP-бэкенда, на клиенте обязательно включение опции «Allow plaintext login» (Разрешить авторизацию открытым текстом). UPD: Это не является угрозой безопасности пароля, если используется SSL. В этом случае сначала устанавливается шифрованное соединение с сервером, а потом уже передаётся открытый пароль. Например в клиенте Psi это настраивается так: Encrypt connection: Always; Allow plaintext authentication: Over encrypted connection.

Story URL: