Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> статьи —> FreeBSD —> почтовые системы —> maildrop & postfix

Настройка альтернативного MDA для postfix

Автор: fr33man.


Решил попробовать какой-нить другой MDA, вместо стандартного virtual. В портах нашел две штуки:


mail@/usr/ports> make search key='delivery agent'
Port:   maildrop-2.0.2
Path:   /usr/ports/mail/maildrop
Info:   Mail delivery agent (MDA) with filtering abilities
Maint:  sergei@FreeBSD.org
B-deps: pcre-6.7 perl-5.8.8
R-deps: pcre-6.7 perl-5.8.8
WWW:    http://www.courier-mta.org/maildrop/

Port:   procmail-3.22_6
Path:   /usr/ports/mail/procmail
Info:   A local mail delivery agent
Maint:  ache@FreeBSD.org
B-deps:
R-deps:
WWW:    http://www.procmail.org/

mail@/usr/ports>

О первом наслышан был больше, поэтому ставить решил его. Итак, установка:


mail@/usr/ports> cd mail/maildrop/
mail@/usr/ports/mail/maildrop> make WITH_AUTHLIB=yes \
? MAILDROP_TRUSTED_USERS=virtual install clean

В менюшке выбираем AUTH_LDAP и AUTH_USERDB. После этого, началось и конфигурирование... И тут вылезла ошибка, что чего-то там не указано для configure.. Пошарив инет, понял, что по Nfs установить не удастся.. У меня /usr/ports/ монтируется с другого сервера. Ладно, все равно есть локальная копия портов, обновив их(локальную копию) я отправился ставить maildrop. Опции такие же как и в первый раз. В этот раз
все затянулось и вылетело на сборке:


... skipped ...
Linking maildirkw
/usr/local/lib/libfam.a(fam.o)(.text+0x35): In function `FAMOpen2':
: undefined reference to `operator new(unsigned int)'
/usr/local/lib/libfam.a(fam.o)(.text+0x5f): In function `FAMOpen2':
: undefined reference to `operator delete(void*)'
/usr/local/lib/libfam.a(fam.o)(.text+0x8e): In function `FAMOpen2':
: undefined reference to `operator delete(void*)'
/usr/local/lib/libfam.a(fam.o)(.text+0x150): In function `FAMClose':
: undefined reference to `operator delete(void*)'
/usr/local/lib/libfam.a(fam.o)(.text+0x25e): In function
`FAMMonitor(FAMConnection*, char const*, FAMRequest*, void*, int)':
: undefined reference to `operator delete[](void*)'
/usr/local/lib/libfam.a(fam.o)(.text+0x279): In function
`FAMMonitor(FAMConnection*, char const*, FAMRequest*, void*, int)':
: undefined reference to `operator delete[](void*)'
/usr/local/lib/libfam.a(fam.o)(.text+0x4c8): In function
`FAMMonitorCollection':
: undefined reference to `operator delete[](void*)'
/usr/local/lib/libfam.a(fam.o)(.text+0x4e3): In function
`FAMMonitorCollection':
: undefined reference to `operator delete[](void*)'
/usr/local/lib/libfam.a(fam.o)(.text+0x6d4): In function
`GroupStuff::GroupStuff()':
: undefined reference to `operator new[](unsigned int)'
... skipped ...

Недолго думая, пошел озадачивать гугл. Решение нашел быстро. Итак, выполняем:

mail@/usr/ports/mail/maildrop> cd /usr/local/lib/
mail@/usr/local/lib/> mv libfam.a libfam.a.old
mail@/usr/local/lib/> ln -s libfam.so libfam.a

После это, все нормально скомпилировалось и установилось. Не знаю в чем проблема, но главное — мы ее решили! ))) Теперь можно переходить к конфигурированию maildrop'а.
Пробежавшись по диагонали по man maildrop, я понял, что для фильтрации нужно создать файл /usr/local/etc/maildroprc, где описаны глобальные опции для всех, или если его не существует, то maildrop будет читать конфиг $HOME/.mailfilter, если же и его не существует, то maildrop просто доставит письмо, без какой либо обработки. Я решил, что сначала лучше протестировать работу maildrop без конфигов, поэтому просто поменял строку в /usr/local/etc/postfix/master.cf:

maildrop  unix  -       n       n       -       -       pipe
  flags=DRhu user=virtual argv=/usr/local/bin/maildrop -d ${recipient}

На:

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

Флаг -w указывает, что при заполнение ящика на 90%(в данном случае) нужно отослать пользователю предупреждение об этом. После этого я поменял
transport для своего домена:

mail@/usr/local/etc/postfix> cat > transport.conf
mail.teachers   maildrop
^D
mail@/usr/local/etc/postfix> makemap hash transport.conf.db < transport.conf
mail@/usr/local/etc/postfix>

Раньше транспорт был virtual,  а не maildrop. Усе, теперь можно тестировать. Шлем сообщение пользователю fr33man@mail.teachers, а в логах наблюдаем следующее:


mail@/usr/ports/mail/maildrop> tail /var/log/maillog
Nov 10 21:26:29 mail postfix/pickup[89047]: 
AF7EBCF21C: uid=0 from=<root>
Nov 10 21:26:29 mail postfix/cleanup[89153]: 
AF7EBCF21C: message-id=<20061110182629.AF7EBCF21C@mail.teachers>
Nov 10 21:26:29 mail postfix/qmgr[89048]: 
AF7EBCF21C: from=<root@mail.teachers>, size=2011, 
nrcpt=1 (queue active)
Nov 10 21:26:30 mail maildrop[89156]: 
Temporary authentication failure.
Nov 10 21:26:30 mail postfix/pipe[89155]: 
AF7EBCF21C: to=<fr33man@mail.teachers>, relay=maildrop, 
delay=0.63, delays=0.27/0.11/0/0.26, dsn=4.3.0, status=deferred 
(temporary failure. Command output: ERR: authdaemon: s_connect() 
failed: Permission denied /usr/local/bin/maildrop: Temporary 
authentication failure. )

Мда.. Не работает, постфиксу прав не хватает, быставлем SUID бит на maildrop:


mail@/> ll `which maildrop`
-rwxr-xr-x  1 root  mail   156K 10 ноя 21:11 /usr/local/bin/maildrop
mail@/> chmod u+s `which maildrop`
mail@/> ll `which maildrop`
-rwsr-xr-x  1 root  mail   156K 10 ноя 21:11 /usr/local/bin/maildrop
mail@/>

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


mail@/usr/ports/mail/maildrop> tail -f /var/log/maillog
Nov 10 22:04:08 mail postfix/pickup[89724]: F0015CF265: 
uid=0 from=<root>
Nov 10 22:04:09 mail postfix/cleanup[90292]: F0015CF265:
 message-id=<20061110190408.F0015CF265@mail.teachers>
Nov 10 22:04:09 mail postfix/qmgr[89725]: F0015CF265: 
from=<root@mail.teachers>, size=2011, nrcpt=1 (queue active)
Nov 10 22:04:09 mail authdaemond: Authenticated: 
sysusername=<null>, sysuserid=1981, sysgroupid=1981, 
homedir=/var/spool/mail/fr33man/, address=fr33man@mail.teachers, 
fullname=fr33man, maildir=fr33man/, quota=10485760, options=<null>
Nov 10 22:04:09 mail authdaemond: Authenticated: 
clearpasswd=<null>, passwd={SSHA}SxlcxiAqmSIBXitBSFXf7WYogoyhEfT1
Nov 10 22:04:09 mail maildrop[90295]: Unable to open mailbox.
Nov 10 22:04:09 mail postfix/pipe[90294]: F0015CF265: 
to=<fr33man@mail.teachers>, relay=maildrop, delay=0.49, 
delays=0.27/0.04/0/0.18, dsn=4.3.0, status=deferred (temporary failure. 
Command output: /usr/local/bin/maildrop: Unable to open mailbox. )

Я долго не понимал в чем проблема, пока не вспомнил, что maildrop по умолчанию пытается открыть не homedirectory, а maildir. Поэтому пришлось лезть в LDAP и менять аттрибут, отвечающий за место расположение почтового ящика, а именно mailMessageStore. Я написал еще один скриптик:


#!/usr/bin/perl

open(USERS, "<users" );
@all = <USERS>;
close(USERS);

open(LDIF, ">/tmp/".$user.".modify.ldif");
foreach $user (@all)
{
        chomp($user);
        open(LDIF, ">/tmp/".$user.".modify.ldif");
        print LDIF "dn: cn=".$user.",ou=users,dc=l1523,dc=ru\n";
        print LDIF "changetype: modify\n";
        print LDIF "replace: mailMessageStore\n";
        print LDIF "mailMessageStore: /var/spool/mail/mail.teachers/".$user."/\n";
        print LDIF "-\n";
        close(LDIF);
        system("/usr/local/bin/ldapmodify -x -D \"cn=root,dc=l1523,dc=ru\" -w \
		ROOT_PASSWORD -f /tmp/".$user.".modify.ldif");
        system("rm -rf /tmp/".$user.".modify.ldif");
}

Комменты излишни, он похож, на тот про который я в статье про Postfix & LDAP писал. Итак, заполняем файлик users именами пользователей и запускаем скрипт. После этого можно менять настройки uthdaemon, /usr/local/etc/authlib/authldaprc, а именно изменяем только эти параметры:


# Так как в переменной mailMessageStore абсолютный 
# путь к maildir'у, то указываем его в LDAP_MAILDIR.
LDAP_MAILDIR            mailMessageStore
# Тоже самое и для homedir'а
LDAP_HOMEDIR            mailMessageStore
# Комментируем нафиг mailroot
#LDAP_MAILROOT        /var/spool/mail

Так же не забудьте отредактировать imapd-ssl, закомментировав строку:

#MAILDIRPATH=.

После этого можно все это дело перезапускать:

mail@/usr/local/etc/postfix> /usr/local/etc/rc.d/courier-authdaemond.sh \
? restart
mail@/usr/local/etc/postfix> /usr/local/etc/rc.d/courier-imap-imapd-ssl.sh \
? restart
Stopping courier_imap_imapd-ssl.
Starting courier_imap_imapd-ssl.
mail@/usr/local/etc/postfix>

Вы можете спросить, а почему я не изменил параметров в main.cf(конфиг postfix). Это хороший вопрос, а ответ на который еще лучше.
Так как maildrop берет настройки от courier-authdaemon, я имею в виду homedir, maildir, quota и тд., то в конфиге postfix'а про LDAP можно вообще ничего не писать, если вы не собираетесь использовать MDA virtual.
Ну вот, теперь еще раз пробуем письмо отправить:


mail@/usr/ports/mail/maildrop> tail -f /var/log/maillog
Nov 10 22:29:12 mail postfix/pickup[90944]: 40DFFCF051: 
uid=0 from=<root>
Nov 10 22:29:12 mail postfix/cleanup[91201]: 40DFFCF051: 
message-id=<20061110192912.40DFFCF051@mail.teachers>
Nov 10 22:29:12 mail postfix/qmgr[90945]: 40DFFCF051: 
from=<root@mail.teachers>, size=2011, nrcpt=1 (queue active)
Nov 10 22:29:12 mail authdaemond: Authenticated: 
sysusername=<null>, sysuserid=1981, sysgroupid=1981, 
homedir=/var/spool/mail/mail.teachers/fr33man/, 
address=fr33man@mail.teachers, fullname=fr33man, 
maildir=/var/spool/mail/mail.teachers/fr33man/, 
quota=10485760, options=<null>
Nov 10 22:29:12 mail authdaemond: Authenticated: 
clearpasswd=<null>, passwd={SSHA}SxlcxiAqmSIBXitBSFXf7WYogoyhEfT1
Nov 10 22:29:12 mail postfix/pipe[91203]: 40DFFCF051: 
to=<fr33man@mail.teachers>, relay=maildrop, delay=0.41,
 delays=0.23/0.04/0/0.14, dsn=2.0.0, status=sent (delivered
 via maildrop service)
Nov 10 22:29:12 mail postfix/qmgr[90945]: 40DFFCF051: removed

Ну вот, теперь оно успешно доставлено. Единственное, с чем я столкнулся из неприятного то, что maildrop не создает maildir'ы, если их нет. Их можно создавать, создав грамотный maildroprc, но у меня в сети не получится так легко это сделать. Ну ладно, не будем о грустном. Я вот скриптик написал для создания maildir'ов, все стандартно, имена юзверей в файлик и запускаем скрипт:


#!/usr/bin/perl

open(U,"<users");
@all=<U>;
close(U);

foreach $user (@all)
{
    chomp($user);
    system("maildirmake /var/spool/mail/mail.teachers/".$user."/");
    system("maildirmake -f Spam /var/spool/mail/mail.teachers/".$user."/");
}
system("chown -R virtual:virtual /var/spool/mail/");

Вот так, после того, как все maildir'ы созданы, можно переходить к рассмотрению преимуществ maildrop, а именно фильтрцию писем. Для начала составим грамотный maildroprc, чтобы каждый пользователь смог задавать сви собственные настройки.

/usr/local/etc/maildroprc:


# Используем shell
SHELL="/bin/sh"
# Проверяем существует ли файл с настройками пользователя
`test -r $HOME/.mailfilter`
# Если да, то ...
if ($RETURNCODE=0)
{
# ... подключаем его
    include $HOME/.mailfilter
}

Установим на него необходимые права:

mail@/usr/local/etc> chown virtual:virtual maildroprc
mail@/usr/local/etc> chmod +x maildroprc

Вот такой простенький конфиг. Давайте теперь создадим конфиг для пользователя, например для меня:


mail@/> cd /var/spool/mail/mail.teachers/fr33man/
mail@/var/spool/mail/mail.teachers/fr33man> touch .mailfilter
mail@/var/spool/mail/mail.teachers/fr33man> chown virtual:virtual .mailfilter
mail@/var/spool/mail/mail.teachers/fr33man> chmod 0600 .mailfilter

Редактируем .mailfilter до такого состояния:

if ("/^X-Spam-Flag:.YES/")
{
    to "$HOME/.Spam"
}
to "$HOME"

По сути, фильтурем спам, перемещая его в папку Spam, итак, пробуем:

mail@/var/spool/mail/mail.teachers/fr33man> echo "X-Spam-Flag: YES" \
? | mail fr33man@mail.teachers
mail@/var/spool/mail/mail.teachers/fr33man> ll
total 14
drwx------   6 virtual  virtual   512B 10 ноя 23:37 .
drwxr-xr-x  82 virtual  virtual   1,5K 10 ноя 23:29 ..
drwx------   5 virtual  virtual   512B 10 ноя 23:29 .Spam
-rw-------   1 virtual  virtual    63B 10 ноя 23:37 .mailfilter
drwx------   2 virtual  virtual   512B 10 ноя 23:29 cur
drwx------   2 virtual  virtual   1,0K 10 ноя 23:32 new
drwx------   2 virtual  virtual   512B 10 ноя 23:32 tmp
mail@/var/spool/mail/mail.teachers/fr33man> ll .Spam/new/
total 6
drwx------  2 virtual  virtual   512B 10 ноя 23:42 .
drwx------  5 virtual  virtual   512B 10 ноя 23:29 ..
-rw-------  1 virtual  virtual   360B 10 ноя 23:42 1163191330.
M307388P94097V0000004EI000F18A5_0.mail,S=360
mail@/var/spool/mail/mail.teachers/fr33man> cat .Spam/new/1163191330.
M307388P94097V0000004EI000F18A5_0.mail,S=360
Return-Path: <root@mail.teachers>
Delivered-To: fr33man@mail.teachers
Received: by mail.teachers (Postfix, from userid 0)
        id 0E91CCF02B; Fri, 10 Nov 2006 23:42:09 +0300 (MSK)
To: fr33man@mail.teachers
Message-Id: <20061110204210.0E91CCF02B@mail.teachers>
Date: Fri, 10 Nov 2006 23:42:09 +0300 (MSK)
From: root@mail.teachers (Vasiliy Ozerov)

X-Spam-Flag: YES
mail@/var/spool/mail/mail.teachers/fr33man>

Как видите, письмо действительно было перемещено в папку .Spam.

Как вы видите, можно создавать свои правила фильтрации, причем существует достаточно много переменных, которые поддерживаются maildrop, о них можно почитать здесь.

Вот и все. Удачи!



размещено: 2006-11-11,
последнее обновление: 2006-11-11,
автор: fr33man


lissyara, 2006-11-11 в 0:31:45

А не про блокировку ли вылезло, на NFS-e?
Ключик -L рулит...

fr33man, 2006-11-11 в 11:53:53

Да, как раз про блокировку. Я даже менял WRKDIRPREFIX, но не помогло..

Виталий, 2006-12-05 в 16:10:51

Есть ещё один MDA - dovecot. Вот только настроить проблема его - документов мало на русском(

fr33man, 2006-12-05 в 19:06:07

Будет время — потестирую.

boba, 2008-01-06 в 17:19:38

должно быть $RETURNCODE=1 иначе все наоборот

так правильно

SHELL="/bin/sh"
# Проверяем существует ли файл с настройками пользователя
`test -r $HOME/.mailfilter`
# Если да, то ...
if ($RETURNCODE=1)
{
# ... подключаем его
   include $HOME/.mailfilter
}

Xtremist, 2008-10-04 в 21:56:14

SUID бит помог, надо сразу было мне  внимательнее маны читать -
/usr/local/share/doc/maildrop/INSTALL

SUID надо ставить, но есть другой путь, на папку authdaemond сделать

chmod +x /var/run/authdaemond

и работает без suid maildrop

Allan Sundry, 2009-07-24 в 10:59:15

Исправьте опечатку "быставлем SUID бит на maildrop"



 

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

© lissyara 2006-10-24 08:47 MSK

Время генерации страницы 0.2009 секунд
Из них PHP: 62%; SQL: 38%; Число SQL-запросов: 77 шт.
Исходный размер: 44416; Сжатая: 9432