UMGUM.COM (лучше) 

Конфигурирование Jabberd2 ( Поверхностное конфигурирование XMPP-сервера Jabberd2. )

17 июля 2012  (обновлено 31 января 2015)

OS: Linux Debian Squeeze.
Application: XMPP server Jabberd2 (version 2.2.16).

Задача: базовая конфигурация свежеустановленного XMPP-сервера Jabberd2, с целью запустить его в работу, пусть и не в самом оптимальном пока режиме. Не забываем, что мы правим конфигурационные файлы полученные от разработчиков с набором исходных кодов и предустановленными настройками "по умолчанию". Полное содержимое используемых сервером конфигурационных файлов выложено здесь.


Предварительно создаем на сервере разрешения доменных имён соответствующие нашему сервису записи (пример для Bind9):

прямую запись типа "A": jabber0.local. A x.x.x.x
запись типа "SRV" для сервера (устаревшая): _jabber._tcp.jabber0.local. IN SRV 5 0 5269 jabber0.local.
запись типа "SRV" для сервера: _xmpp-server._tcp.jabber0.local. IN SRV 5 0 5269 jabber0.local.
запись типа "SRV" для клиента: _xmpp-client._tcp.jabber0.local. IN SRV 5 0 5222 jabber0.local.

Записи типа "SRV" для XMPP протокола играют роль схожую с записями типа "MX" для почтового протокола, они помогают размещать и описывать компоненты сервиса на хостах с доменами отличных от указанного в акаунте пользователя сервиса. Если реальное доменное имя сервера и наименование, указанное в акаунте совпадает, то получается ситуация, которая вполне описывается выражением: "кашу маслом не испортишь" В любом случае, лучше указать записи SRV, чем не указать.

Проведем подготовительный работы на СУБД, выбранной нами для хранения данных - MySQL.

В комплекте исходных кодов Jabberd2 есть набор скриптов, позволяющих создать структуры хранения данных. Воспользуемся скриптом "/usr/src/jabberd-2.2.16/tools/db-setup.mysql", применительно к выбранному нами MySQL:

# mysql -h localhost -u root -p
mysql> source /usr/src/jabberd-2.2.16/tools/db-setup.mysql;

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

Database changed
Query OK, 0 rows affected (0.05 sec)
Query OK, 0 rows affected (0.01 sec)
...
Query OK, 0 rows affected (0.00 sec)

Создадим пользователя, от имени которого XMPP-сервер будет обращаться к своим базам:

mysql> GRANT select,insert,delete,update ON jabberd2.* to jabberd2@localhost IDENTIFIED by 'password';
mysql> quit;

После того, как структура хранения данных Jabberd2 будет создана, возможно захочется по быстрому, не используя сторонние средства администрирования сервиса, вручную внести в неё данные о первом пользователе XMPP-сервера.

Для этого переключим рабочий контекст MySQL-клиента на базу XMPP-сервера:

mysql> use jabberd2;

Элементарно вставим в таблицу "authreg" имя, домен сервера и пароль нового пользователя:

mysql> insert into authreg (username, realm, password) values ('username', 'jabber0.local', 'userpassword');

По умолчанию Jabberd2 без особого указания не создаёт полной структуры окружения пользователя, полагая, что она должна быть описана заранее. Таким образом, аутентифицировав подключающегося клиента по логину, домену и паролю, способ внесения в базу которых мы отработали выше, Jabberd2 не создаст полноценной сессии, указывая в журнале событий на отсутствие описания окружения (ростер, статусы и тому подобное). Честно говоря, я не понимаю "сермяжной сути" такого подхода разработчиков; рекомендую сразу пройти в конфигурационный файл менеджера сессий соответствующего "сервера" и раскомментировать строку, включающую автоматическое создание окружения пользователя, буде таковое ещё не создано:

# cat /etc/jabberd/sm-domain.name.xml

....
  <user>
    <auto-create/>
  ....
  </user>
....

Если мы переносим базу пользователей со старого сервера в пределах линейки Jabberd2, то можно осуществить вывод данных базы на старом сервере в резервную копию и перенести её на новый. При смене версий с "2.2.9" на "2.2.16" изменения в структуре таблиц незначительны и выражаются в удалении одной из служебных таблиц, что не может отразится на общем функционале в плане прямого переноса данных.

Создаем резервную копию таблиц базы Jabberd2 (необходимо оперировать от имени пользователя, который имеет право блокировать таблицы на сервере для исключения внесения изменений в таблицы во время создания резервной копии так как пользователь jabberd2 таких привилегий не имеет; можно просто остановить сервер MySQL на период изготовления резервной копии и убрать из вызова команды ключ "--first-slave"):

# mysqldump --verbose --first-slave --add-locks --no-create-db --no-create-info --complete-insert --host=localhost --databases jabberd2 --result-file=/path.to.file/jabberd2.sql --user=user --password=password

-- Connecting to localhost...
-- Retrieving table structure for table active...
-- Sending SELECT query...
-- Retrieving rows...
...
-- Retrieving table structure for table vcard...
-- Sending SELECT query...
-- Retrieving rows...
-- Disconnecting from localhost...

Применяем "дамп" на сервере MySQL:

# mysql -h localhost -u root -p -e "source /path.to.file/jabberd2.sql" jabberd2

Лучше бы раскрывать "дамп" непосредственно в консоли MySQL, так как в приведённом выше примере мы не получим вывода информационных сообщений о прохождении вставки данных. Лучше это делать так:

mysql -h localhost -u root -p
mysql> use jabberd2;
mysql> source /path.to.file/jabberd2.sql;
mysql> quit;

Далее работаем с конфигурационными файлами, расположенными в директории "/etc/jabberd".

Сервис Jabberd2 построен по модульному принципу с аутентификацией модулей по отношению друг к другу. Определимся, с тем, что для всех модульных сервисов нашего Jabberd2 сервера и акаунта сервера баз данных мы применим одинаковые реквизиты доступа, для простоты (все равно, далее localhost обращения не пойдут). Это не имеет никакого отношения к авторизации пользователей сервиса, просто метод обеспечения проверки подлинности подключения модулей. По умолчанию логин и пароль в блоке авторизации модуля равны "jabber" и "secret"; логин оставим неизменным, а вот пароль повсеместно следует сменить на свой. Пример блока авторизации:

# cat /etc/jabberd/c2s.xml

<router>
  <!-- Username/password to authenticate as -->
  <user>jabberd</user>
  <pass>password</pass>  <!-- default: secret -->

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

# cat /etc/jabberd/c2s.xml:

<!-- Router connection configuration -->
<router>
<!-- File containing a SSL certificate and private key to use when setting up an encrypted channel with the router. If this is commented out, or the file can't be read, no attempt will be made to establish an encrypted channel with the router. -->
  <pemfile>/usr/local/etc/jabberd/server.pem</pemfile>

Обозначим в конфигурационных файлах модулей место расположения PID-файлов XMPP-сервера, для того, чтобы мы могли корректно запускать и останавливать наш Jabberd2. Во всех конфигурационных файлах устанавливаем путь к pid файлу "/var/jabberd/pid/*.pid" по принципу, приведённому в примере (обращаем внимание на то, чтобы модули со сходными названиями не использовали чужие файлы pid):

<pidfile>/var/jabberd/pid/c2s.pid</pidfile>

Мне нравится иметь вывод событий каждого приложения или модуля в отдельном файле, а не в общей свалке syslog. Добьемся этого соответствующими исправлениями конфигурационных файлов. Добиваемся примерно такого вида блока "log" в каждом конфигурационном файле с соответствующей адаптацией (обращаем внимание на то, чтобы модули со сходными названиями не использовали чужие журнальные файлы):

<!-- Log configuration - type is "syslog", "file" or "stdout" -->
  <log type='file'>
    <file>/var/jabberd/log/c2s.log</file>
  </log>

Кому-то, возможно, имеет смысл дублировать логи в файл и syslog, особенно, если ведётся централизованная обработка syslog. Думаю, можно попробовать использовать два блока описания журналирования в конфигурационном файле.

Корректируем конфигурационные файлы, доводя до сведения Jabberd2 параметры хранилища данных и реквизиты доступа к нему:

# cat /etc/jabberd/sm-domain.name.xml:

<!-- Storage database configuration -->
  <storage>
    <driver>mysql</driver>
....
<!-- MySQL driver configuration -->
  <mysql>
    <host>localhost</host>
    <port>3306</port>
    <dbname>jabberd2</dbname>
    <user>jabberd2</user>
    <pass>password</pass>
    <transactions/>
</mysql>

# cat /etc/jabberd/c2s.xml:

<!-- Authentication/registration database configuration -->
  <authreg>
    <!-- Backend module to use -->
    <module>mysql</module>
....
<!-- MySQL module configuration -->
<mysql>
  <host>localhost</host>
  <port>3306</port>
  <dbname>jabberd2</dbname>
  <user>jabberd2</user>
  <pass>secret</pass>
</mysql>

Применим доменные имена нашего jabber сервера, в нашем случае это "jabber0.local" и "jabber1.local" в соответствующих файлах конфигурации менеджера сессий:

# cat /etc/jabberd/sm-jabber0.local.xml:

<!-- Session manager configuration -->
  <sm>
    <id>jabber0.local</id>
....
<!-- Local network configuration -->
<local>
  <id>jabber0.local</id>
</local>

Заставляем модуль "router" прослушивать только localhost, для обеспечения ещё одного уровня безопасности и обеспечения невозможности несанкционированного подключения модулей с отличных от localhost узлов:

# cat /etc/jabberd/router.xml:

<!-- Router configuration -->
<router>
  <!-- Local network configuration -->
  <local>
    <!-- IP address to bind to (default: 0.0.0.0) -->
    <ip>127.0.0.1</ip>

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

В конфигурационном файле "/etc/jabberd/c2s.xml" есть блок описания, в котором можно задать параметры аутентификации для нашего XMPP-сервера, разрешить или запретить регистрацию новых пользователей, смену пароля пользователем, параметры шифрование трафика между клиентом и сервером применительно к каждому "серверу" (в блоке "id realm"), используемому нами (необходимо создать индивидуальные блоки для каждого используемого доменного имени, иначе говоря - сервера). Параметры имеют "говорящие" имена и значения.

Jabberd2 поддерживает подключение клиента к серверу тремя способами:

незащищённое, открытое для перехвата трафика;
защищённое "по старому", семейством протоколов SSL;
защищённое современным протоколом TLS.

Напомню, что протокол SSL (Secure Socket Layers), первоначально разработанный и развиваемый некоторое время компанией Netscape, был передан на стандартизацию сообществу IETF (Internet Engineering Task Force). К тому времени SSL добрался до третьей версии; по ходу переработки стандарта IETF переименовало протокол SSL в TLS (Transport Layer Security). TLS основан на третьей версии протокола SSL (SSLv3) и пока отличается от последнего довольно слабо, из-за чего термины "SSL" и "TLS" не верно используются взаимозамещающим образом.

Требования обратной совместимости могут потребовать использования как SSL, так и TLS на серверах. Мне в этом необходиомсти нет и я буду допускать клиентские подключения лишь самым современным образом, с помощью протокола TLS, отбрасывая все иные.

Далее в конфигурационном файле "/etc/jabberd/c2s.xml" отключаем устаревший метод подключения фиксированного SSL на порт "5223", оставляя для прослушивания только порт "5222", требуя на нём при подключении запуска обязательного шифрования TLS (require starttls):

<!-- Local network configuration -->
  <local>
    <id realm='domain.name'
        pemfile='/usr/local/etc/jabberd/server.pem'
        require-starttls='true'
    >domain.name</id>
....
    <ip>0.0.0.0</ip>
....
    <port>5222</port>
    <!-- <ssl-port>5223</ssl-port> -->
....
  </local>

В надежде на то, что клиентское программное обеспечение достаточно современно и поддерживает компрессию трафика в соответствии с особой спецификацией, включаем ее поддержку на сервере, убрав комментарии в файле "/etc/jabberd/c2s.xml" на указанный блок:

<!-- Enable XEP-0138: Stream Compression -->
  <compression/>

Поработаем над описанием механизма аутентификации клиента на сервере. В Jabberd2 поддерживается раздельные описания набора механизмов для разных способов подключения, в блоке "" и, для работы с фиксированным SSL, в блоке "". От устаревшего SSL мы отказались выше, так что просто удаляем весь блок (который существует для обратной совместимости со старыми версиями сервера), начинающийся с "" и заканчивающийся "".

Учитывая то, что ранее мы решили принудительно переводить все соединения в режим защиты с помощью протокола TLS, вообще не принципиально, каким образом будет производится передача данных для аутентификации клиента на сервере - они всё равно будут зашифрованы на транспортном уровне. Потому просто оставим в качестве гарантированно работающего варианта передачу пароля открытым текстом, добавив в качестве альтернативы способ аутентификации с помощью "хэша". И да, раз уж мы скомпилировали Jabberd2 с SASL на борту, предоставим таковой возможность показать себя, в дополнение к встроенной в Jabberd2 аналогичной подсистеме:

<!-- Authentication/registration database configuration -->
<authreg>
  <!-- Dynamic authreg modules path -->
  <path>/usr/lib/jabberd</path>
....
  <!-- Available authentication mechanisms -->
    <mechanisms>
      <traditional>
        <plain/>
        <digest/>
      </traditional>
      <sasl>
        <plain/>
        <digest-md5/>
      </sasl>
    </mechanisms>
....
</authreg>

Сейчас можно перезапустить jabberd2 и почитать вывод модулей в журнале событий.

# /etc/init.d/jabberd2.sh restart

Terminating Jabberd2 processes ...
  Stopping [router]...
  Stopping [sm-jabber0.local]...
  Stopping [sm-jabber1.local]...
  Stopping [c2s]...
  Stopping [s2s]...
Initializing Jabberd2 processes ...
  Starting [router]...
  Starting [sm-jabber0.local]...
  Starting [sm-jabber1.local]...
  Starting [c2s]...
  Starting [s2s]...

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


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )