
В итоге чаще всего серьёзные фирмы выбирают сложный путь — поддерживать все необходимые сервисы на собственных серверах. Этот путь, конечно, даёт массу преимуществ. Системный администратор компании сможет настроить что угодно и как угодно. Однако есть и один существенный недостаток: если у Google всё уже настроено и связано воедино, то вам придётся настраивать всё вручную. Плюс вы вряд ли сможете обеспечить вашу систему таким же красивым и удобным веб-интерфейсом.
Однако, как показывает практика, развернуть гибкую и мощную инфраструктуру для компании можно легко и не прибегая к помощи Google. Под катом я расскажу как интегрировать XMPP сервер с почтовой системой, чтобы получилось в итоге значительно лучше, чем у Google.

Почтовый сервер
Для начала вам потребуется почтовый сервер. Разумным выбором MTA является Postfix, как один из самых модульных, гибких и при этом надёжных. Для доставки почты конечным получателям без вариантов необходим IMAP сервер, в качестве которого я использую Dovecot.
Dovecot позволяет легко использовать в качестве базы пользователей практически любое стандартное хранилище. Я, например, использую AD. Кроме того, Dovecot предоставляет сторонним приложениям возможность авторизовываться через себя, в частности, это умеет делать Postfix. Таким образом получается весьма удобная схема: за общение с БД пользователей отвечает Dovecot, а все остальные компоненты системы просто обращаются к нему за проверкой авторизации. Преимущество очевидно: захотелось вам поменять БД (например, отказаться от AD в пользу OpenLDAP) — ничего перенастраивать не надо, достаточно просто направить Dovecot на новое хранилище.
Как настраивать связку Dovecot+Postfix написано в документации к этим программам. В результате настройки я лично обзавёлся SMTP и IMAP серверами, авторизовываются на которых пользователи по доменному логину/паролю. Кстати, у Dovecot и Postfix очень хорошая документация — это тоже немаловажное преимущество этих продуктов. Поэтому уверен, что с настройкой этой связки проблем возникнуть не должно.
Jabber сервер
Осталось дело за малым: надо прикрутить к уже имеющейся почтовой системе Jabber сервер. Сделать это до смешного элементарно. Для начала потребуется установить ejabberd. Почему его? Хотя бы потому, что он самый гибкий. О богатых возможностях этого продукта написана масса статей, поэтому перейду сразу к организации авторизации ejabberd через Dovecot. К всеобщему счастью ejabberd поддерживает внешнюю авторизацию, и всё, что нужно сделать — это написать скрипт проверки пользовательских данных через Dovecot.
Небольшое отступление: внешние механизмы авторизации через Dovecot работают через два UNIX сокета, создаваемых Dovecot. Параметры этих сокетов указываются в конфиге Dovecot, подробней про них можно почитать на официальной вики.
Порывшись немного в интернете я нашёл такой вот фрукт: http://search.cpan.org/~sasha/Authen-SASL-Authd-0.04/lib/Authen/SASL/Authd.pm
Нагло потырив из него кода и добавив необходимое для ejabberd поведение получил конечный вариант:
#!/usr/bin/perl
use 5.010;
use IO::Socket::UNIX;
use IO::Select;
use MIME::Base64 qw(encode_base64);
# Сокеты Dovecot
$dovecot_auth_master = '/var/run/dovecot/auth-master';
$dovecot_auth_client = '/var/spool/postfix/private/auth-client';
sub read_until {
my ($sock, $re, $timeout) = @_;
my $sel = new IO::Select($sock);
my $result = '';
while ($result !~ /$re/m) {
$sel->can_read($timeout) or die "Timed out while waiting for response";
defined recv($sock, my $buf, 256, 0) or die 'Error while reading response';
$result .= $buf;
}
return $result;
}
sub dovecot_auth {
my ($login, $passwd) = @_;
utf8::encode($login);
utf8::encode($passwd);
my $base64 = encode_base64("\0$login\0$passwd",'');
my $service = "ejabberd";
my $timeout = 3;
my $sock = new IO::Socket::UNIX(Type => SOCK_STREAM, Peer => $dovecot_auth_client) or die;
my $resp = read_until($sock,'DONE',$timeout);
die unless $resp =~ /^VERSION\t1\t\d+$/m;
die unless $resp =~ /^MECH\tPLAIN/m;
$sock->send("VERSION\t1\t0\nCPID\t$$\nAUTH\t1\tPLAIN\tservice=$service\tsecured\tresp=$base64\n") or die;
$resp = read_until($sock,'\n',$timeout);
$sock->close;
return $resp =~ /OK/;
}
sub dovecot_user {
my $login = shift @_;
utf8::encode($login);
my $service = "ejabberd";
my $timeout = 3;
my $sock = new IO::Socket::UNIX(Type => SOCK_STREAM, Peer => $dovecot_auth_master) or die;
my $resp = read_until($sock,'VERSION',$timeout);
die unless $resp =~ /^VERSION\t1\t\d+$/m;
$sock->send("VERSION\t1\t0\nUSER\t1\t$login\tservice=$service\tsecured\n") or die;
$resp = read_until($sock,'\n',$timeout);
$sock->close;
return $resp =~ /USER/;
}
# Reading information from ejabberd
while(1) {
my $nread = sysread STDIN, my $buf, 2;
unless ($nread == 2) { exit }
my $len = unpack "n", $buf;
$nread = sysread STDIN, $buf, $len;
my ($op,$user,$domain,$passwd) = split /:/, $buf;
# Filter dangerous characters
$user =~ s/[."\n\r'\$`]//g;
$passwd =~ s/[."\n\r'\$`]//g;
$domain =~ s/[."\n\r'\$`]//g;
my $result = 0;
if ($op =~ /auth/i) {
$result = dovecot_auth($user, $passwd) ? 1 : 0;
} elsif ($op =~ /isuser/i) {
$result = dovecot_user($user) ? 1 : 0;
}
my $out = pack "nn", 2, $result;
syswrite STDOUT, $out;
}
Небольшое замечание: исходный модуль из CPAN в данный момент вряд ли заработает. Для корректного взаимодействия с Dovecot при вызове функции encode_base64 необходимо указывать в качестве второго аргумента пустую строку. В представленном выше скрипте это конечно учтено.
Тут стоит обратить внимание, что для авторизации через Dovecot процесс ejabberd должен иметь права на чтение и запись в сокеты авторизации Dovecot. Работает ejabberd от имени пользователя ejabberd, который по странному стечению обстоятельств состоит в группе ejabberd. Таким образом не забудьте дать права rw для этого пользователя (или группы) на оба сокета Dovecot и на каталоги, в которых они находятся (про последний пункт почему-то часто забывают).
Осталось добавить в конфиг ejabberd наш скрипт:
{auth_method, external}.
{extauth_program, "/etc/ejabberd/auth.pl"}.
Собственно, на этом содержательная часть заканчивается. Теперь кроме почты пользователи смогут заходить под своими доменными логинами ещё и в Jabber. А если при настройке почтовой системы вы не сильно извращались, то JID и email у каждого пользователя будут совпадать и выглядеть как username@domain.com.
Однако осталось ещё догнать и перегнать Google. Чтож, это сделать очень просто. Достаточно совершенно стандартным способом включить нужные функции в ejabberd. Вот самые интересные с моей точки зрения возможности:
- Конференции, они же MUC. За их поддержку отвечает стандартный модуль mod_muc, настраивать нужно разве что желаемые параметры по умолчанию.
- Логгирование конференций. За это отвечает модуль mod_muc_log. Он кладёт все логи конференций в одну папочку в виде HTML файликов, остаётся только натравить на эту папочку Apache и разрешить доступ к полученному ресурсу только из локальной сети.
- Логгирование личной переписки. Для включения этой возможности вам потребуется доустановить модуль mod_log_chat, который будет складывать все логи в одну папку опять-таки, в виде HTML файликов. Дальше можно написать простейший скрипт, который периодически будет сканировать эту папку и рассылать нужные файлы по нужным адресам электронной почты. Таким образом получим сходный с Google функционал.
- Общие ростеры. Крайне полезная возможность в рамках компании. За неё отвечает mod_shared_rosters. Позволяет гибко управлять ростерами пользователей, добавляя в них целые группы.
- Поддержка оффлайновых сообщений. Просто не отключайте её (mod_offline если что)
- Транспорты. Я думаю, этот пункт в комментариях не нуждается. Вы можете предоставить своим сотрудникам лёгкий способ общаться через любую существующую сеть IM.
На всякий случай обращу ваше внимание на то, что т.к. мы настраивали совмещённую с почтой (и в моём случае даже с AD) систему авторизации, то всё, связанное с регистрацией, на Jabber сервере стоит отключить. Например, тот же mod_register. Просто чтоб глаза не мозолил.
Резюме
Вот так простым скриптом можно связать воедино почту и Jabber, при этом оставив себе практически неограниченную свободу настройки всего и вся в рамках используемых продуктов. А поскольку были использованы одни из самых функциональных, гибких и надёжных инструментов в своих областях, то фактически получается чуть ли не самая мощная система из всех возможных в рамках поставленной задачи (почта+IM для корпоративного общения). Никакие интегрированные решение вроде Exchange и уж тем более Google Apps конечно и близко не могут обеспечить подобного функционала. При этом с точки зрения пользователя полученная система абсолютно прозрачна и максимально проста в использовании, да и с точки зрения администратора тоже. Разве что администратору надо разобраться во всём при настройке (и правильно всё настроить!), а дальнейшая поддержка чуть менее чем элементарна.
P.S. Если будет кому-нибудь интересно — могу рассказать ещё как выжать много чего интересного из связки Dovecot+Postfix (IMAP ACL, админский прямой доступ к любому ящику из любого клиента, рассылки, общие папки, подписки, делегирование прав самими пользователями etc) и как организовать гибкую настройку любых параметров почтового клиента Thunderbird через сервер, избавив пользователей от необходимости (а при желании и возможности) вообще что-либо изменять в своём клиенте.