Довольно часто возникает необходимость сделать высокоэффективную почтовую систему с возможностью масштабированияв плане увеличения mx'ов. Для этого можно воспользоваться такой связкой: на входе стоит nginx с policy, которая выполняет асинхронный резолвинг адресов и фильтрацию по rbl+regexp. На многих потоках почты, это снижает процент почты, доходящей до MTA, примерно в 2-3 раза. При этом policy выполняет балансировку между различными backend'ами на основании весов. MTA использует rmiter для выполнения различных проверок: clamav, spamd, ratelimits, greylisting, regexps. При этом, все данные greylisting'а и лимитов сохраняются в memcached, что обеспечивает очень быструю работу и возможность скалирования системы.
Итак, вначале скачиваем nginx версии 0.6.11: http://sysoev.ru/nginx/nginx-0.6.11.tar.gz Более свежие версии, к сожалению, работать не будут. Далее скачиваем libevent и применяем мой патч для поддержки TXT записей в резолвере:
libevent_txt.patch
Почему этой возможности до сих пор нет в libevent, мне не очень понятно.
После установки патченной версии libevent можно устанавливать nginx и policy.
Вначале патчим исходники nginx патчем для поддержки policy (также фиксится работа pipelining'а и включается режим работы без аутентификации). Патч лежит тут:
http://cebka.pp.ru/hg/hgwebdir.cgi/nginx-smtp-policy/file/ab33c3b8f1f1/patch-src_mail
После этого собираем nginx с поддержкой модуля mail.
Далее можно собрать policy. Скачиваем policy отсюда: http://cebka.pp.ru/hg/hgwebdir.cgi/nginx-smtp-policy/archive/tip.tar.gz
Собирается просто командой make+make install. При этом ставятся файлы nginx-smtp-policy и nginx-policy-watchdog с соответствующими стартовыми скриптами в /usr/local/etc/rc.d
Настройка policy предельно проста: в каждой строчке содержится переменная и ее значение. Строчки с # в начале считаются комментариями. Пример используемого мной конфига:
# nameserver - definition of nameserver (maybe multiply)
# special value resolv.conf is used to parse /etc/resolv.conf file
nameserver 195.19.37.129
# logfile - full path to logfile
# Default: /var/log/policy.log
logfile /var/log/policy/policy.log
# pidfile - full path to pidfile
# Default: /var/run/policy.pid
pidfile /var/log/policy/policy.pid
# backend_host - address of host that are backends for nginx (postfix address)
# Example host1:weight1,host2:weight2
# Default: 127.0.0.1
backends 127.0.0.1:1
# backend_port - port of backend
# Default: 25
backend_port 25
# listen - address of socket to listen on, maybe tcp or unix:
# tcp: listen tcp:host:port
# unix: listen unix:/path/to/sock
# Default: tcp:localhost:7070
listen tcp:localhost:7070
# loglevel - numeric value of logging verbocity
# 0 - only errors are logged
# 1 - warnings and errors are logged
# 2 - warnings, notices and errors are logged
# 3 - everything including debug messages is logged
# Default: 0
loglevel 2
# helo_regexp_file - specify path to helo regexp file and error code and error message string
# separated by ':' (maybe multiply)
# Example: helo_regexp_file /usr/local/etc/nginx-policy/helo.re:554 5.7.1:Bad address
# Default:
helo_regexp_file /usr/local/etc/postfix/maps/policy_helo_regexp:554 5.7.1:Helo rejected
# hostname_regexp_file - specify path to host regexp file and error code and error message string
# separated by ':' (maybe multiply)
# Example: hostname_regexp_file /usr/local/etc/nginx-policy/host.re:554 5.7.1:Bad address
# Default:
hostname_regexp_file /usr/local/etc/postfix/maps/policy_reverse_regexp:554 5.7.1:We do not accept mail form this dynamic pool
check_rbl xbl.spamhaus.org
check_rbl insecure-bl.rambler.ru
Файлы, которые я использую для этих регэкспов, можно найти в http://cebka.pp.ru/stuff/
Postfix ставится стандартным образом. Отдельно могу указать следующие вещи:
если мы на одном хосте пускаем policy и postfix, то в main.cf указываем
inet_interfaces = localhost
также для корректной работы rmilter нужно указать следующие опции:
milter_protocol = 4
smtpd_milters = unix:/var/run/rmilter/rmilter.sock
milter_default_action = accept
milter_mail_macros = i {auth_type} {auth_authen} {auth_author} {mail_addr} {client_addr} {client_name}
для работы XCLIENT указываем, с каких хостов он разрешен (это хост, где работает policy)
smtpd_authorized_xclient_hosts = localhost
Далее настроим nginx:
mail {
server_name host.ru;
auth_http localhost:7070/nginxauth.cgi;
smtp_auth none;
#smtp_capabilities "SIZE 28311552" PIPELINING 8BITMIME;
smtp_capabilities "SIZE 28311552" 8BITMIME;
xclient on;
smtp_helo_required on;
smtp_banner "mxi.icn.bmstu.ru ESMTP nginx\n\nSystem Info: This is a mail server at host.ru\n\n\n\nEmail contact: <abuse@host.ru>\n\n";
proxy_pass_error_message on;
server {
#listen 3525;
listen ip1:25;
listen ip2:25;
protocol smtp;
timeout  
; 300s;
}
}
Rmilter для данной системы можно поставить из портов FreeBSD - mail/rmilter
Настройка rmilter детально описано в конфиге и странице rmilter (8). Memcached для работы мильтра можно использовать любой. Для общения с memcached лучше использовать tcp. Работа в режиме udp пока нестабильна из-за кучи ошибок в реализации udp в мемкешеде.
Работа этой связки проверялась в FreeBSD 6, FreeBSD 7 и FreeBSD 8-CURRENT. Если кому-то удастся завести эту связку на других системах, шлите патчи :) Также в http://cebka.pp.ru/stuff лежат примеры конфигов и используемые нами "белые" списки.
> на входе стоит nginx с policy, которая выполняет асинхронный резолвинг адресов и фильтрацию по surbl+regexp.
ReplyDeleteТут опечатка - просто rbl, а не surbl