Интеграция Postfix, Maildrop и DSPAM во FreeBSD


Данное руководство не ставит своей целью полное описание процесса настройки и интеграции МТА Postfix и спам-фильтра DSPAM. Это всего
попытка рассказать о том способе взаимодействия между программами, который понравился автору. В частности, делался упор на обработку писем, обучение и корректировку словаря только средствами почтовой системы. В данной схеме нет необходимости использовать DSPAM CGI или подобные средствами требующими web-сервер.

Почтовая система установлена на FreeBSD 5.4 и использованы следующие компоненты:

1) МТА - Postfix 2.2.7
2) DSPAM 3.4.8
3) Mysql 5.0.16
4) LDA - Maildrop 1.8
5) Courier-authlib 0.58 (сюда же входят courier-authlib-base 0.58,
courier-authlib-mysql 0.58)
6) Courier-IMAP 4.0.6
7) p5-DBI-1.49 (p5-DBD-mysql50-3.0002)

(здесь конечно же перечислены не все компоненты, но этого достаточно для понимания функционирования моей схемы)

На момент начала интеграции вы должны иметь установленную почтовую систему, или установить её со следующими условиями:

1) Пофигс должен быть собран с поддержкой виртуальных пользователей, backend - mysql. Помимо этого, скрипт LDA рассчитан на то, что у нас
есть поддержка индивидуальных квот (корзина не учитывается), формат ящиков - maildir (путь складывается из каталога с ящиками + имя пользователя + maildir/), список папок:

INBOX.
Outbox
Sent
Trash

Инструкция предусматривает многодоменность. Пользователей хранить в таблице, как имя@домен.

2) В mysql создана база и все необходимые таблицы для функционирования почтовой системы.
Создан пользователь имеющий доступ к этим таблицам.

3) В качестве IMAP/POP3 сервера я использую Courier-IMAP это и послушило причиной сборки LDA maildrop с использованием Courier-authlib. Вы
можете использовать всё что угодно и тогда можно включить доступ из maildrop к таблицам mysql другими средствами.

1. Mysql

Предполагается, что данная СУБД уже установлена.

В ней создана база postfix, и в ней таблица mailbox следующей структуры:

+----------+--------------+------+-----+---------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------------------+-------+
| username | varchar(255) | NO | PRI | | |
| password | varchar(255) | NO | | | |
| name | varchar(255) | YES | | NULL | |
| maildir | varchar(255) | NO | | | |
| quota | int(10) | NO | | 0 | |
| domain | varchar(255) | NO | | | |
| created | datetime | NO | | 0000-00-00 00:00:00 | |
| modified | datetime | NO | | 0000-00-00 00:00:00 | |
| active | tinyint(1) | NO | | 1 | |
| dspam | tinyint(1) | NO | | 0 | |
+----------+--------------+------+-----+---------------------+-------+

2. Courier-Authlib

# cd /usr/ports/security/courier-authlib
# make config (выбираем в появившемся меню: AUTH_MYSQL)
# make install


Идём в /usr/local/etc/authlib и правим файлы authdaemonrc и authmysqlrc, вид их должен быть примерно следующий:

# more authdaemonrc
authmodulelist="authmysql"
authmodulelistorig="authmysql"
daemons=5
subsystem=mail
authdaemonvar=/var/run/authdaemon
DEBUG_LOGIN=2
DEFAULTOPTIONS="wbnodsn=1"

# more authmysqlrc
MYSQL_SERVER место_где_живёт_mysql
MYSQL_USERNAME имя_пользователя
MYSQL_PASSWORD секретный_пароль
MYSQL_SOCKET сокет
MYSQL_PORT порт (обычно 3306)
MYSQL_OPT 0
MYSQL_DATABASE postfix
MYSQL_USER_TABLE mailbox
MYSQL_CLEAR_PWFIELD password
DEFAULT_DOMAIN ваш_домен_по_умолчанию (хотя, для maildrop это необязательно)
MYSQL_UID_FIELD владелец_файлов_в_почтовом_каталоге (у меня здесь postfix или 125)
MYSQL_GID_FIELD группа_владелец_файлов_в_почтовом_каталоге (то же самое)
MYSQL_LOGIN_FIELD username
MYSQL_HOME_FIELD почтовый_каталог (например, '/mailboxes/')
MYSQL_NAME_FIELD name
MYSQL_MAILDIR_FIELD maildir
MYSQL_QUOTA_FIELD quota
MYSQL_WHERE_CLAUSE active='1'

Далее идём в /usr/local/etc/rc.d и делаем

# ./courier-authdaemond.sh start

3. Maildrop

Шагаем в /usr/ports/mail/maildrop и компилим

# make WITH_AUTHLIB=yes MAILDROP_TRUSTED_USERS=courier
# cd /usr/local/bin
# chown postfix:mail maildrop
# chmod u+s maildrop

Сочиняем maildrop скрипт, должно быть так:

# more /usr/local/etc/maildroprc
SHELL="/bin/sh"
SENDER=$1
`test -d $HOME$DEFAULT`
if ($RETURNCODE!=0)
{
`mkdir -p -m 0700 $HOME$DEFAULT`
`mkdir -m 0700 $HOME$DEFAULT/cur`
`mkdir -m 0700 $HOME$DEFAULT/new`
`mkdir -m 0700 $HOME$DEFAULT/tmp`
}
QUOTA="$MAILDIRQUOTA"'S'
`maildirmake -q $QUOTA $HOME$DEFAULT`
if ($LOGNAME ne "spam@ваш_домен" && $LOGNAME ne "nospam@ваш_домен")
{
DSPAM=`/usr/local/etc/spam $LOGNAME`
if ($DSPAM eq "1" && $SIZE < 2048000)
{
xfilter "/usr/local/bin/dspam --user $LOGNAME --stdout --process --deliver=innocent,spam"
if (/^X-DSPAM-Result: Spam/)
{
`test -d $HOME$DEFAULT/.Trash`
if ($RETURNCODE!=0)
{
`/usr/local/bin/maildirmake $HOME$DEFAULT/.Trash`
}
to "$HOME$DEFAULT/.Trash"
}
else
{
to "$HOME$DEFAULT"
}
}
else
{
to "$HOME$DEFAULT"
}
}
if ($LOGNAME eq "spam@ваш_домен")
{
DSPAM=`/usr/local/etc/spam $SENDER`
if ($DSPAM eq "1" && $SIZE < 2048000)
{
xfilter "/usr/local/bin/dspam --user $SENDER --class=spam --source=error"
}
}
if ($LOGNAME eq "nospam@ваш_домен")
{
DSPAM=`/usr/local/etc/spam $SENDER`
if ($DSPAM eq "1" && $SIZE < 2048000)
{
xfilter "/usr/local/bin/dspam --user $SENDER --class=innocent --source=error"
}
}


4. DBI

# cd /usr/ports/databases/p5-DBI
# make install
# cd ../p5-DBD-mysql50
# make install


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

# more spam
#!/usr/bin/perl
use DBI;
my $mysql_host = "где_живёт mysql";
my $mysql_db = "postfix";
my $mysql_user = "postfix";
my $mysql_pw = "ваш_пароль";

my $dbh = DBI->connect("DBI:mysql:$mysql_db:$mysql_host","$mysql_user","$mysql_pw",
{RaiseError=> 0, PrintError => 0} )
or err_trap("Connection Error ");
if ($ARGV[0] ne "")
{
$query = "SELECT dspam FROM mailbox WHERE username='$ARGV[0]'";
$qresult = $dbh->prepare($query);
$qresult->execute() or die "Can't execute $query: " . $dbh->errstr . " ";
if ($qresult->rows() ne "0")
{
$dspam = $qresult->fetchrow_array();
print "$dspam";
}
else
{
print "9";
}
$qresult->finish();
}
else { print "9"; }
$dbh->disconnect();


5. Пофигс

Я интегрировал DSPAM уже в существующую систему, с настроенными main.cf и master.cf, поэтому я не буду останавливаться на настройке MTA (это тема другой инструкции).
Для успешной работы системы вам надо изменить параметр в main.cf:

virtual_transport = maildrop


И подправить master.cf таким образом:

maildrop unix - n n - - pipe
flags=DRhu user=courier argv=/usr/local/bin/maildrop -w 90 -d ${recipient} ${sender}

6. DSPAM

Теперь пришёл тот самый ответственный момент, которого каждый человек ждёт всю свою жизнь :)

# cd /usr/ports/mail/dspam
# make config (оставляем крыжики: DEBUG, PREF_EXT, GRAHAM_BAYES, BURTON_BAYES, RPV, TEST_COND,
TRUSTED_USERS, MYSQL50, VIRT_USERS, DOMAIN_SCALE, MAILDROP_LDA)
# make install
# chown root:courier /usr/local/bin/dspam
# cd /usr/local/etc
# cp dspam.conf.sample dspam.conf

Меняем следующие параметры в dspam.conf...

Доверенные пользователи:

Trust root
Trust mail
Trust courier


Свойства:

Feature noise
Feature chained
Feature tb=5
Feature whitelist

СУБД:

MySQLServer место_где_живёт_сокет_mysql
MySQLPort или_можно_порт указать
MySQLUser dspam
MySQLPass свой_суперсекретный_пароль )
MySQLDb dspam

Notifications off (я не хочу чтобы DSPAM отсылал всякие там письма моим пользователям)

SystemLog off (и статистику я тоже не хочу собирать)
UserLog off


Вытаскиваем из дистрибутива каталог tools.mysql.drv, делаем жутко хитрые манипуляции:

# mysqladmin -uroot -p create dspam
# mysql -uroot -p dspam < tools.mysql.drv/mysql_objects-4.1.sql
# mysql -uroot -p dspam < tools.mysql.drv/virtual_users.sql
# mysql -uroot -p dspam
mysql> grant all on dspam.* to dspam@localhost identified by 'свой_суперсекретный_пароль';
mysql> exit


Впихиваем в /etc/crontab строку

1 1 * * * nobody /usr/local/bin/mysql -udspam
-pсвой_суперсекретный_пароль dspam < tools.mysql.drv/purge-4.1.sql
(ваш путь к файлу очистки базы может отличаться от этого)


7. Пробуем отправить письмо на какой-нибудь свой почтовый ящик (не забываем поставить dspam = 1)

После того, как проверили результаты работы, делаем один из следующих вариантов (можно выбрать несколько):

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


Плюсы такой схемы:

а) нет необходимости использовать cgi, все манипуляции делаются почтовой системой (IMAP + The Bat рулят)
б) индивидуальные словари для каждого пользователя
в) высокая степеть эффективности (99% отсеивание спама начиналось после отправки 5-7 писем на spam@)

Минус:

При большом количестве пользователей, DSPAM'у необходимо хранить очень большие объёмы информации (примерно по 1Мб на каждого пользователя, и это лишь только начало :) Быстро достаём калькуляторы и считаем какого размера получаются базы (особо умные могут считать в уме!).

У меня, например, щас 2,5 тыс. пользователей, хотя спам-фильтром пользуются не все.

Послесловие:

1. От минуса можно избавиться, например включив поддержку сжатия баз при компиляции DSPAM'а, или в ущерб индивидуальности сделать один общий словарь. Ещё как вариант, если вы не параноидальный извращенец, как я, можно включить метод обучения toe, базы станут меньше, но и эффективность фильтра меньше. Можно пойти совсем другим способом - поставить Postgresql или Oracle и радоваться. Я как раз выбрал последний вариант, проблема ведь не в дисковом пространстве, а больше, в неформальных ограничениях на размер mysql базы.

2. Писал я эту инструкцию по памяти + во время работы сервера переходил от транспорта virtual к maildrop (не один из пользователей при работах
не пострадал :) поэтому, в некоторых местах получилось немного криво, но тем не менее работает эффективно. Сразу прошу не пинать меня, если у вас что-то не заработает или не состыкуется при применении этой инструкции, можете писать мне на email: dezz@sibmail.com или попытаться найти меня в IRC, сеть RUSNET, канал #tfug (ник: Dezzs)

3. В инструкции не затрагиваются аспекты безопасности. Так же вырезаны "проверки" из скриптов.

4. Если какие-то печатные издания, типа "Системного администратора" захотят со мной сотрудничать, могу расширить инструкцию, дополнить её скриншотами. Могу так же написать статьи на другие темы (c сохранением моего авторства), что-нибудь типа "Безопасное почтовое ядро выполненное на free-ПО для почтовой системы", "Анализ и выбор посредника для MTA Postfix и антивируса ClamAV", "Подробное описание DSPAM", могу что-нибудь на тему безопасности Apache написать... вообщем, приглашаю к сотрудничеству.

Обновлено: 12.03.2015