Создай свой сервер мгновенного обмена сообщениями на базе Ejabberd и IServerd
Сергей «grinder» Яремчук (grinder@ua.fm, )
Сегодня как никогда популярны различные системы мгновенного обмена сообщениями, вроде ICQ, Jabber, AOL, MSN, Yahoo, где общение происходит в реальном времени. Если ранее во многих организациях администраторы просто блокировали такой трафик, чтобы перекрыть возможный канал утечки информации, то сейчас неоспоримым является тот факт, что применение IM систем часто повышает производительность. Так давай на учебе/работе установим свой собственный Jabber и/или ICQ сервер.
Содержание:
- Jabber vs ICQ
- Сервера Jabber
- Установка ejabberd
- Конфигурационный файл ejabberd
- Настраиваем DNS, заводим администраторов
- Транспорт ICQ <-> Jabber
- Настройка IServerd
Не смотря на то, что пользователи больше знают о ICQ, самым популярным среди открытых проектов, занимающихся разработкой IM сервера, является Jabber. Jabber использует открытый протокол XMPP (eXtensible Messaging and Presence Protocol), использующий для быстрого обмена сообщениями и информацией о присутствии между любыми двумя абонентами не plain текст, а XML. Хотя это и несколько увеличивает объем сообщения и требует наличия XML парсеров, которые потребляют некоторую часть ресурсов. Но в обмен Jabber дает гибкость и расширяемость. Благодаря гибкости протокола, jabber-сервер способен поддерживать множество протоколов — ICQ, IRQ, MSN, RSS, Yahoo и др. Да, если ICQ — это только обмен сообщениями между двумя пользователями, то Jabber совмещает в себе и возможности IRC. Поэтому вместо двух серверов (ICQ и IRC), вполне возможно обойтись и одним. Так будет гораздо удобнее как администраторам, так и пользователям. В Jabber изначально используется Unicode, поэтому проблем с кодировками не существует. Также jabber отличает продуманная система защиты информации, все реализации серверов поддерживают SSL, клиенты — шифрование с помощью PGP/GPG, пароли передаются не в открытом виде, а используются md5-хеши. Протокол XMPP, в отличие от ICQ, стандартизирован и открыт, поэтому список серверов, реализующих его, на порядок больше чем ICQ.
Вероятно, самый полный список серверов, реализующих Jabber, можно найти по адресу . После просмотра столбцов «Feature Score» и «License=Gnu GPL» из всех присутствующих можно отобрать лишь четыре — jabberd 1.x и 2.x, OpenFire и ejabberd. Список поддерживаемых операционных систем у всех одинаков — AIX, *BSD, HP-UX, Linux, MacOS X, Solaris, Windows. Поэтому смотрим функциональность и удобство. Первые два очень хорошие серверы, славятся своей стабильностью в работе, написаны на языке С. По возможностям эти серверы являются лишь базой, т.к. большая их часть вроде конференций, поиска пользователей и некоторых других, реализована посредством плагинов. Чтобы заставить работать некоторые комбинации, придется изрядно попотеть. К тому же версия 1.x уже практически не развивается. Сервер OpenFire (до февраля 2007 — WildFire) самый простой в установке, т.к. для его запуска потребуется лишь наличие Java Runtime Environment. Да, он написан на Java, но сегодня это никого уже пугать не должно. Для тех, кто не хочет использовать внешнюю базу данных (MySQL, Postgres, Microsoft SQL Server, DB2), в наличии есть встроенная HSQLDB. Все настройки осуществляются через удобный веб-интерфейс. В установке по умолчанию OpenFire имеет большое количество возможностей, остальное (Asterisk, широковещательные сообщения, IM шлюз, контент фильтр и прочее) реализуется посредством плагинов. И последний . Практически все возможности, заложенные в протоколе, реализованы из коробки. Написан на языке и в качестве базы данных используется Mnesia (поддерживаются и другие — MySQL, PostgreSQL). Язык Erlang предназначен создания отказоустойчивых распределенных приложений. Результат — ejabberd может работать в кластере, т.е. один домен физически могут обслуживать несколько серверов, синхронизируя информацию через единую базу данных. Откомпилированные приложения выполняются в Erlang (JAM) emulator, в этом он несколько похож на Java. Этот сервер и выбираем для установки.
На странице закачки проекта ejabberd можно найти ссылки на установочные файлы для Windows, Mac OS X (PowerPC и Intel), Linux и исходные тексты. В репозитариях дистрибутивов Debian, Ubuntu, Mandriva, OpenSUSE, Fedora, FreeBSD имеются пакеты для установки ejabberd. Для компиляции, помимо make и gcc, понадобятся библиотеки OpenSSL и Zlib, а также Erlang/OTP. Установка последнего несколько не обычна, но проста.
Скачиваем дистрибутив:
$ wget –c http://erlang.org/download/otp_src_R11B-4.tar.gz
Создаем каталог для установки:
$ sudo mkdir /usr/local/erlang $ cd /usr/local/erlang $ sudo mkdir otp_r11b $ cd otp_r11b
Распаковываем дистрибутив:
$ sudo gunzip -c /home/grinder/otp_src_R11B-4.tar.gz | tar xfp -
Запускаем установочный скрипт:
$ sudo ./Install /usr/local/erlang/otp_r11b
Скрипт начнет задавать вопросы, в большинстве случаев достаточно оставлять значение по умолчанию, т.е. просто нажимать Enter. По окончании установки, для удобства создаем символическую ссылку на исполняемый файл:
$ sudo ln -s /usr/local/erlang/otp_r11b/bin/erl /usr/bin/erl
Установка ejabberd из исходных текстов стандартна, т.е. «./configure; make; sudo make install«. В Ubuntu и других дистрибутивах, имеющих в репозитарии ejabberd, процесс установки выглядит на порядок проще:
$ sudo apt-get update $ sudo apt-get install ejabberd
В результате будет установлен не только сервер ejabberd, но и все зависимости, включая erlang. Пакет с расширением bin для установки в Linux и exe для Windows предлагают графический инсталлятор, позволяющий по ходу установки произвести основные настройки.
Конфигурационный файл ejabberd
Все настройки находятся в конфигурационном файле /etc/ejabberd/ejabberd.cfg, при загрузке демон считывает этот файл, анализирует и сохраняет в базу данных. Конфигурационный файл содержит последовательность условий Erlang. Все строки, начинающиеся со знака ‘%’, считаются комментариями и игнорируются. Любое условие состоит из названия параметра, которое стоит на первом месте, и далее идет одно или несколько его возможных значений. В конце условия *обязательно* ставится точка. Также следует помнить, что в условиях не должно быть разрывов, т.е. лишних строк, для правки желательно использовать редактор, умеющий ставить Unix’овый одиночный символ окончания строки.
Если какое либо из условий не будет определено в конфигурационном файле, используются значения, сохраненные в базе данных. Чтобы их аннулировать, используются конструкции: override_global, override_local, override_acls. Обычно условия сразу вставляют в конфигурационный файл, чтобы не путаться в том, какие настройки сервер знает, а какие нет. При установке, как с использованием исходных текстов, так и с помощью пакетов, создается шаблон, остается его лишь немного подправить:
# vi ejabberd.cfg
override_acls.
% Список домена(ов), который обслуживает сервер
{hosts, ["grinder.com", "localhost"]}.
% Язык сообщений сервера.
{language, «ru»}.
% Пользователи с привилегиями администратора
{acl, admin, {user, «grinder»}}.
{acl, admin, {user, «sergej»}}.
% Список заблокированных пользователей
{acl, blocked, {user, «test»}}.
% Разрешаем локальных пользователей
{acl, local, {user_regexp, «»}}.
% Разрешаем только администраторам использовать конфигурационный интерфейс
{access, configure, [{allow, admin}]}
% Разрешаем регистрацию пользователей
{access, register, [{allow, all}]}.
% Так можно запретить самостоятельную регистрацию пользователей,
% сделав сервер закрытым
%{access, register, [{deny, all}]}.
% Сообщение при регистрации, можно использовать русские буквы
{welcome_message,
{«Welcome!», «Welcome Grinder Jabber Service.»}}.
% Кому отсылать сообщения о регистрации новых пользователей
{registration_watchers, ["grinder@grinder.com"]}.
% Разрешаем только админам отсылать многоадресные объявления
{access, announce, [{allow, admin}]}.
% Только незаблокированные пользователи могут соединяться с севером
{access, c2s, [{deny, blocked}, {allow, all}]}.
% Администраторы сервера являются и администраторами MUC (Multi User Chat)
{access, muc_admin, [{allow, admin}]}.
% Разрешаем всем пользователям подключаться к MUC
{access, muc, [{allow, all}]}.
% Используем встроенную базу данных
{auth_method, internal}.
% Порты, на которых будут работать сервисы ejabberd
{listen,
% Обычный сервис client-2-server
[{5222, ejabberd_c2s, [{access, c2s},
starttls, {certfile, "/etc/ssl/certs/ejabberd.pem"},
{shaper, c2s_shaper}]},
% Сервис client-2-server с использованием SSL
{5223, ejabberd_c2s, [{access, c2s},
tls, {certfile, "/etc/ssl/certs/ejabberd.pem"},
{shaper, c2s_shaper}]},
% Порт для работы server-2-server
{5269, ejabberd_s2s_in, [{shaper, s2s_shaper}]},
{outgoing_s2s_port, 5269}.
% Транспорт Jabber <-> ICQ
{5347, ejabberd_service, [{ip, {127, 0, 0, 1}}, {access, local},
{host, ["icq.grinder.com", "sms.localhost"], [{password, "secret"}]}]},
% Веб-интерфейс
{5280, ejabberd_http, [http_poll, web_admin]}]}.
% Используемые модули и параметры
{modules,
[
{mod_announce, [{access, announce}]},
…
]}.
В принципе, конфигурационный файл понятен, только следует быть внимательным при его заполнении.
Настраиваем DNS, заводим администраторов
В этом же каталоге находится еще один важный файл — inetrc, отвечающий за работу со службой DNS. Если сервер ejabberd используется в локальной сети, где нет смысла настраивать DNS-сервер, необходимо указать на использование /etc/hosts:
{file, hosts, «/etc/hosts»}.
{file, resolv, «/etc/resolv.conf»}.
% сначала ищем записи в hosts, а затем обращаемся к DNS
{lookup, [file, dns]}.
В файле /etc/hosts должна быть запись, указывающая на соответствие IP-адреса и имени компьютера:
127.0.0.1 localhost
192.168.1.158 grinder.com
Теперь запускаем/перезапускаем сервер. Это можно сделать двумя способами. Стандартным:
$ sudo /etc/init.d/ejabberd restart
Или с использованием утилиты ejabberdctl:
$ sudo ejabberdctl restart
Проверяем статус работ сервера:
$ sudo ejabberdctl status Node ejabberd@grinder is started. Status: started
Если в ответ получаем другое сообщение, просматриваем вывод «netstat -na«. Если в выводе нет открытых портов, указанных в конфигурационном файле, значит, сервис не запустился (или запустился частично). Останавливаем его работу и проверяем ejabberd.cfg. Если же порты в списке есть, то начинать следует с разрешения имен.
Теперь необходимо завести пользователей, имеющих права администратора. В нашем случае — это grinder и sergej:
$ sudo ejabberdctl register sergej grinder.com super_password
Проверяем, что пользователь успешно создан:
$ sudo ejabberdctl registered-users sergej@grinder.com
Все нормально, аналогично заводим и второго админа. Теперь, если был разрешен веб-интерфейс, вызываем веб-браузер и заходим на страницу . На запрос имени пользователя и пароля вводим параметры учетной записи администратора. Только к имени добавляем и домен, т.е. вместо sergej следует вводить sergej@grinder.com. Веб-интерфейс позволяет в удобной и наглядной форме настраивать списки управления доступом, заводить и удалять пользователей, просматривать статистику. Следует помнить, что все настройки, произведенные через веб-интерфейс, в конфигурационном файле не сохраняются. При наличии записей override_* они будут действительны до первой перезагрузки. Все, сервер к работе готов, можно зазывать пользователей.
Некоторые пользователи, вероятно, не захотят отказываться от ICQ. Для них можно настроить транспорт ICQ <-> Jabber. Организуется он с помощью PyICQt (), для работы которого дополнительно потребуются библиотеки Twisted, PyCrypto и PyOpenSSL (). В Ubuntu/Debian их очень просто установить одной командой:
$ sudo apt-get install python-twisted python-crypto python-pyopenssl
Так мы установим Python и прочие недостающие программы и библиотеки. Теперь скачиваем и распаковываем PyICQt. Переименовываем шаблон конфигурационного файла config_example.xml в config.xml и редактируем:
# vi config.xml
<pyicqt>
<jid>icq.grinder.com</jid>
<!— здесь указан текущий каталог,
ejabberd должен иметь право на запись в него —>
<spooldir>.</spooldir>
<pid>PyICQt.pid</pid>
<mainServer>127.0.0.1</mainServer>
<mainServerJID>ejabberd.localhost</mainServerJID>
<!— веб-интерфейс нужен nevow (www.nevow.org) —>
<website>http://jabber.localhost/</website>
<webport>12345</webport>
<port>5347</port>
<!— пароль для доступа к ejabberd, должен совпадать с ejabberd.cfg —>
<secret>secret</secret>
<!— язык для сообщений об ошибках —>
<lang>en</lang>
<encoding>cp1251</encoding>
<icqServer>login.icq.com</icqServer>
<icqPort>5190</icqPort>
<!— блокируем регистрацию (по желанию) —>
<disableRegister/>
<enableAutoInvite/>
<!— <disableXHTML/> —>
<!— <disableMailNotifications/> —>
<disableDefaultAvatar/>
<admins>
<jid>grinder@localhost</jid>
</admins>
</pyicqt>
Теперь запускаем шлюз командой «python PyICQt.py«. Открываем Jabber-клиент и в браузере ресурсов находим «icq.grinder.com», вводим свой UIN и пароль. Если все настроено правильно, то в списке должен появиться агент с именем «ICQ Transport» или подобный. После чего можно добавлять контакты ICQ в форме UIN@grinder.com.
Тем, кто все же остается приверженцем протокола ICQ, посвятим эту часть статьи. Выбор ICQ сервера упрощается практическим отсутствием альтернатив. Единогласно на всех ресурсах рекомендуется один сервер — (ICQ server daemon). Изначально работает только под Unix-совместимыми системами, но автор говорит, что, возможно, он скомпилируется при помощи cygwin под Windows. На настоящий момент существует две ветви проекта: стабильная (2.x.x или stable) и версия для разработчиков (3.x.x). Для установки будем использовать последний на момент написания статьи IServerd-stable (2.5.5). Кроме него потребуется PostgreSQL. Последняя используется для хранения информации обо всех зарегистрированных пользователях, включая пароли, записей о подключенных пользователях, отложенных сообщениях и прочее. Установка IServerd стандартна: «./configure --prefix=/usr --with-russian; make; make install«. Запускаем PostgreSQL.
$ sudo /etc/init.d/postgresql start
В подкаталоге script архива с исходными текстами находим файл db_manage, который поможет создать все необходимые базы:
$ sudo chmod +x ./db_manage $ su postgres $ ./db_manage.sh create
Скрипт спросит имя новой базы (users_db), пользователя для доступа (iserverd) и пароль. Переходим в каталог /etc/iserverd и копируем:
$ sudo cp iserv.conf.default iserv.conf
C остальными файлами, имеющими префикс default, поступаем аналогично. Основной конфигурационный файл называется iserv.conf. Необходимо подправить в нем ряд параметров:
# vi iserv.conf
# по умолчанию IServerd будет ожидать соединения на всех интерфейсах
Bind interface = 0.0.0.0/32
# файл трансляции из каталога translate, чтобы все данные в базе данных были в общепринятой для данного языка кодировке
Translate table = RUSSIAN_WIN
# кому отправлять сообщения
Admin email = grinder@localhost
Info Password = super_password
# параметры подключения к БД
database user = iserver
database password = password
database addr = 127.0.0.1
database port = 5432
users db name = users_db
# подключаем файлы с описанием протоколов
Include = etc/v3_proto.conf
Include = etc/v5_proto.conf
Include = etc/v7_proto.conf
Чтобы клиенты могли регистрироваться самостоятельно, в файле v3_proto.conf устанавливаем следующие параметры (в файлах v5_proto.conf и v7_proto.conf есть аналогичный параметр):
V3 auto registration = Yes
V3 post-register info = etc/texts/post_reg_auto.txt
Пользователей можно заводить и вручную. Для этой цели в комплекте имеется утилита icquser:
$ su pgsql $ cd /etc/iserverd/db $ ./icquser add UIN
Для автоматического запуска сервера в каталоге script подготовлены два скрипта: iserverd.sh и iserverd.sh.asp. Второй ориентирован на RedHat и производные от него дистрибутивы. В общем случае копируем iserverd.sh в /etc/init.d и создаем символическую ссылку на нужный уровень запуска:
$ sudo script/iserverd.sh /etc/init.d/iserverd $ sudo ln –s /etc/init.d/iserverd /etc/rc3.d/S98iserverd
Стартуем:
$ sudo /etc/init.d/iserverd start
Также стоит обратить внимание на наличие веб-интерфейса для IServerd — isdwm (). C его помощью можно легко найти, просмотреть параметры, добавить, блокировать и удалить учетную запись, очистить список отложенных сообщений и прочее. Будет также полезен и для сбора статистики .
Надеюсь, теперь установка своего ICQ или Jabber сервера не должна вызвать проблем. Успехов.
Статья опубликована в июньском номере журнала «Xakep» за 2007 год.





