После того, как аккаунтов Jabber (XMPP) сервера станет поболее тысячи, в полный рост встанет вопрос о необходимости наличия инструментария поиска пользователями ресурса друг друга. Нужно прикрутить модуль Jabber User Directory ("jabber-users-agent" - A Perl based Jabber User Directory), рекомендуемый к применению разработчиками Jabberd2 в разделе "5.10. Setting up a JUD Using Users-Agent" документации расположенной по адресу http://www.jabberdoc.org/AdminGuide
С этим модулем отдельная история. Написан он был лет пять-семь назад. Написан достаточно хорошо и, ввиду отсутствия настоятельной необходимости его совершенствования и потери интереса к нему разработчика - заброшен. Домашняя страничка автора уже не существует, официальный сайт (http://www.jabberstudio.org/) модулей Jabberd2 умирает, не функционален и не отдаёт запрашиваемых файлов.
Как-то так вышло, что найти "jabber-users-agent" в той каше из порнухи, троянов и дезинформационных вбросов, ныне именуемой сетью Интернет, стало непросто. Непросто настолько, что я не смог этого сделать, используя только поисковые машины, вроде Google и Yandex. Но - надо. Включаем дедуктивные способности. Где мы в последний раз встречали упоминания о успешном применении "jabber-users-agent"? Правильно - FreeBSD. Идём в "порты" на сайте http://www.freebsd.org/; выискиваем пакет "jabber-users-agent" и смотрим, откуда же берутся в нём исходные коды. Вот она, судьба заброшенных проектов энтузиастов - всего две ссылки на скачивание пакета исходных кодов, только одна из которых рабочая. Воспользуемся ею:
# cd /usr/src
# wget http://freebsd.unixfreunde.de/sources/Users-Agent-1.2.tar.gz
# wget http://freebsd.unixfreunde.de/sources/Users-Agent-1.2.tar.gz
На всякий случай оставляю этот файл здесь:
Распаковываем архив и переходим в директорию с исходными кодами:
# tar -xvf Users-Agent-1.2.tar.gz
# cd /usr/src/users-agent-1.2
# cd /usr/src/users-agent-1.2
Далее нюанс. Мы работаем в корпоративной среде и скрывать нам, по определению, от своих нечего. Потому, не будем множить сущности и создавать отдельную структуру в виде базы пользователей специально для просмотра и поиска, а привяжем работу модуля прямо к реальной базе пользователей сервера. Для изменения функционала работы модуля есть специальный патч, применение которого рекомендуется самими разработчиками Jabberd2, хоть и с оглядкой на возможные проблемы, вызванные работой непосредственно с аккаунтами пользователей. Рискнём:
# wget http://www.jabberdoc.org/tools/users-agent.vcard.patch
На всякий случай оставляю этот файл здесь:
Патч для Users-Agent-1.1. У нас - Users-Agent-1.2. Патчим патч, чуть доделываем его, чтобы он сработал для более поздней версии модуля. Ищем такой кусок текста:
@@ -296,8 +294,20 @@
$fields{email} = $query->GetEmail();
}
- $dbh->do("INSERT INTO jud VALUES(".$dbh->quote($fromJID->GetJID()).",'',".$dbh->quote($fields{first}).",".$dbh->quote($fields{last}).",".$dbh->quote($fields{nick}).",".$dbh->quote($fields{email}).");");
-
$fields{email} = $query->GetEmail();
}
- $dbh->do("INSERT INTO jud VALUES(".$dbh->quote($fromJID->GetJID()).",'',".$dbh->quote($fields{first}).",".$dbh->quote($fields{last}).",".$dbh->quote($fields{nick}).",".$dbh->quote($fields{email}).");");
-
...и меняем на нижеследующий (в точности, до пробела или точки):
@@ -295,10 +295,20 @@
$fields{email} = $query->GetEmail() if $query->DefinedEmail();
}
- $dbh->do("INSERT INTO jud VALUES(".$dbh->quote($fromJID->GetJID()).",'',".$dbh->quote($fields{first}).",".$dbh->quote($fields{last}).",".$dbh->quote($fields{nick}).",".$dbh->quote($fields{email}).");");
-
- $dbh->do("OPTIMIZE TABLE jud;");
-
$fields{email} = $query->GetEmail() if $query->DefinedEmail();
}
- $dbh->do("INSERT INTO jud VALUES(".$dbh->quote($fromJID->GetJID()).",'',".$dbh->quote($fields{first}).",".$dbh->quote($fields{last}).",".$dbh->quote($fields{nick}).",".$dbh->quote($fields{email}).");");
-
- $dbh->do("OPTIMIZE TABLE jud;");
-
Применяем патч, накладывая его на скрипт Perl "users-agent":
# patch -p0 < users-agent.vcard.patch
К сожалению, используемый патч не полностью адаптирует работу модуля к новым условиям; блок категоризованного просмотра оказался им не затронут. До поры, блокируем работу этого блока путём исключения из "объявления" соответствующего функционала; ищем и комментируем следующие три строки в итоговом скрипте Perl "users-agent":
...
"http://jabber.org/protocol/disco#items"=>{
get=>\&iqDiscoItemsGetCB,
},
...
"http://jabber.org/protocol/disco#items"=>{
get=>\&iqDiscoItemsGetCB,
},
...
Далее корректируем Perl скрипт модуля "users-agent". Найдём в скрипте строку:
$optctl{config} = "config.xml";
...и заменим её на следующую (задав искомому конфигурационному файлу более толковое имя):
$optctl{config} = "/etc/jabberd2/users-agent.xml";
Научим модуль чётко работать с UTF-8. Найдём в скрипте строку:
....
use utf8;
....
use utf8;
....
...и дополним ещё одной инструкцией:
....
use utf8;
use encoding 'utf8';
....
use utf8;
use encoding 'utf8';
....
Так же, конкретизируем параметры подключения к СУБД. Найдём в скрипте строку:
....
my $dbh = DBI->connect("DBI:mysql:database=".$config{mysql}->{dbname},$config{mysql}->{username},$config{mysql}->{password});
....
my $dbh = DBI->connect("DBI:mysql:database=".$config{mysql}->{dbname},$config{mysql}->{username},$config{mysql}->{password});
....
...и дополним ещё одной инструкцией:
....
my $dbh = DBI->connect("DBI:mysql:database=".$config{mysql}->{dbname},$config{mysql}->{username},$config{mysql}->{password});
my $setchar = $dbh->prepare("SET CHARACTER SET utf8;");
$setchar->execute();
....
my $dbh = DBI->connect("DBI:mysql:database=".$config{mysql}->{dbname},$config{mysql}->{username},$config{mysql}->{password});
my $setchar = $dbh->prepare("SET CHARACTER SET utf8;");
$setchar->execute();
....
Вышеприведённые правки можно было бы оформить в виде ещё одного патча, конечно, особенно с учётом того, что реально я гораздо в большей степени дорабатывал скрипт, для достижения требуемой функциональности, но - не здесь и не сейчас. На данный момент, основная задача состоит в том, чтобы оживить сборку из готовых решений.
Теперь модуль готов к работе. Установим и настроим его.
Инсталлируем библиотеки, необходимые для работы Perl приложения:
# aptitude install libnet-jabber-perl libnet-xmpp-perl libdbi-perl libxml-stream-perl libunicode-maputf8-perl libgetopt-long-descriptive-perl
Создаем пользователя, от имени которого будем запускать наш модуль:
# useradd --home-dir /var/jabber --shell /bin/false --gid jabberd2 users-agent
Копируем скрипт модуля в положенное ему место:
# cp ./users-agent /usr/bin
Создаём место для файлов журнала:
# mkdir -p /var/log/users-agent
# chown -R users-agent:jabberd2 /var/log/users-agent
# chown -R users-agent:jabberd2 /var/log/users-agent
Копируем конфигурационный файл в положенное ему место и защищаем его от произвольного доступа:
# cp ./config.xml /etc/jabberd/users-agent.xml
# chown users-agent:jabberd2 /etc/jabberd/users-agent.xml
# chmod o-rwx /etc/jabberd/users-agent.xml
# chown users-agent:jabberd2 /etc/jabberd/users-agent.xml
# chmod o-rwx /etc/jabberd/users-agent.xml
Корректируем настройки конфигурационного файла модуля:
# cat /etc/jabberd/users-agent.xml
<config>
<server>
<connectiontype>accept</connectiontype>
<hostname>127.0.0.1</hostname>
<port>5347</port>
<secret>strongPassword</secret>
</server>
<component>
<name>users.xmpp.local</name>
</component>
<mysql>
<dbname>jabberd2</dbname>
<username>usersagent</username>
<password>strongPassword</password>
<limit>500</limit>
</mysql>
</config>
<server>
<connectiontype>accept</connectiontype>
<hostname>127.0.0.1</hostname>
<port>5347</port>
<secret>strongPassword</secret>
</server>
<component>
<name>users.xmpp.local</name>
</component>
<mysql>
<dbname>jabberd2</dbname>
<username>usersagent</username>
<password>strongPassword</password>
<limit>500</limit>
</mysql>
</config>
Пробуем запустить наш модуль:
# /usr/bin/users-agent
Смотрим, подключился ли наш модуль к серверу:
# netstat -ap | grep perl
....
tcp 0 0 localhost:33172 localhost:5347 ESTABLISHED 23645/perl
....
tcp 0 0 localhost:33172 localhost:5347 ESTABLISHED 23645/perl
....
Если что-то идёт не так, а что - не ясно, то в теле скрипта можно включить режим отладки, выставив значение переменной "$optctl{debug}" в единицу.
Создадим по адресу "/etc/init.d/users-agent" скрипт управление сервисом:
#!/bin/bash
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
PROG="/usr/bin/users-agent"
LOG="/var/log/users-agent/users-agent.log"
case "$1" in
start)
echo "Initializing Users-Agent processes ..."
if [ "`ps wax | grep -i perl | grep -i users-agent`" ]
then
echo -ne "\tUsers-Agent already running"
exit 1
fi
echo -ne "\tStarting Users-Agent... "
/bin/su -s /bin/bash -l users-agent -c "$PROG 2>> $LOG &"
;;
stop)
echo "Terminating Users-Agent processes ..."
if [ "`ps wax | grep -i perl | grep -i users-agent`" ]
then
echo -ne "\tStopping Users-Agent... "
kill `ps wax | grep -i perl | grep -i users-agent | awk '{print $1}'`
fi
;;
restart)
$0 stop
sleep 3
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
PROG="/usr/bin/users-agent"
LOG="/var/log/users-agent/users-agent.log"
case "$1" in
start)
echo "Initializing Users-Agent processes ..."
if [ "`ps wax | grep -i perl | grep -i users-agent`" ]
then
echo -ne "\tUsers-Agent already running"
exit 1
fi
echo -ne "\tStarting Users-Agent... "
/bin/su -s /bin/bash -l users-agent -c "$PROG 2>> $LOG &"
;;
stop)
echo "Terminating Users-Agent processes ..."
if [ "`ps wax | grep -i perl | grep -i users-agent`" ]
then
echo -ne "\tStopping Users-Agent... "
kill `ps wax | grep -i perl | grep -i users-agent | awk '{print $1}'`
fi
;;
restart)
$0 stop
sleep 3
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0
Устанавливаем для управляющего скрипта разрешение на исполнение:
# chmod ugo+x /etc/init.d/users-agent
Пробуем запустить службу:
# /etc/init.d/users-agent start
Смотрим журнал и начинаем пользоваться сервисом.
Не вижу смысла обеспечивать автоматический запуск этого сервиса вместе с системой. Гораздо эффективнее зацепить управление за сервис самого jabber (XMPP) сервера, чтобы они стартовали и останавливались вместе.
Сервис работает для всех. Если жалко или просто не нужно, то можно фильтровать обращения к модулям Jabber сервиса (а сервисы у нас работают именно в виде модулей). Для ограничения доступа к сервисам редактируем конфигурационный файл "/etc/jabberd/router-filter.xml", размещая в блоке "" следующее:
....
<!-- don't allow use Users-Agent non local users-->
<rule from="*@xmpp.local" to="users.xmpp.local"/>
<rule error="not-allowed" from="*" to="users.xmpp.local" what="presence" log="yes"/>
....
<!-- don't allow use Users-Agent non local users-->
<rule from="*@xmpp.local" to="users.xmpp.local"/>
<rule error="not-allowed" from="*" to="users.xmpp.local" what="presence" log="yes"/>
....
11 марта 2011 в 18:32
11 марта 2011 в 18:55
11 марта 2011 в 19:22
11 марта 2011 в 20:06
11 марта 2011 в 20:26
11 марта 2011 в 21:27