вторник, 16 сентября 2014 г.

Почтовый сервер: настройка BATV

В предыдущем посте я уже касался темы backscatter спама. Когда-то такой спам стал для меня чуть ли не единственной проблемой потому, что остальной отсеивался довольно легко, а против этого мои методы не работали. Выглядело это как поток уведомлений о не доставленных сообщениях (NDN - Non-Delivery Notification) моим пользователям от разных вполне легальных почтовых серверов, которым никто из этих пользователей никогда ничего не посылал. Естественно, к каждому NDN было приложено оригинальное (якобы) письмо, содержанием которого и был спам. Ушло время на то чтобы просто понять, что происходит, узнать, что называется это backscatter и что для борьбы с ним можно использовать BATV.

Суть BATV заключается в добавлении к обратному адресу (Return-Path) каждого исходящего письма некоторого криптографического токена и проверке адресов получателей  входящих NDN на наличие этого токена. Спамер хочет чтобы сторонний сервер послал нам уведомление о невозможности доставки и посылает свой спам несуществующему пользователю стороннего сервера, прописывая в Return-Path наш почтовый адрес. Например: user@domain.tld. Сторонний сервер посылает уведомление с оригиналом письма спамера нам на user@domain.tld, но мы-то знаем, что в Return-Path писем, которые действительно отправлялись нами, никогда не может быть такого адреса. У нас работает BATV и он всегда преобразует обратные адреса исходящих писем к виду: prvs=0336dff388=user@domain.tld, где 0336dff388 - индивидуальный криптографический токен пользователя user, который не может быть подделан спамером. Все такие NDN отвергаются с порога.

В описываемые времена я нашел только одну реализацию BATV для Postfix в виде неслабого такого perl скрипта от Ralph Babel, который скрипт, кстати, до сих пор работает, и в который я, оценив могущество before-queue content filter,  еще и добавил разных не связанных с BATV функций. Сейчас, когда я перехожу на Zentyal 3.5 и сознательно делаю всю настройку с нуля, мне уже хочется каких-то более легковесных решений. И вот, покопавшись в интернетах, я нашел довольно свежий проект batv-tools от Andrew Ayer, который во-первых написан на Си, во-вторых интегрируется с Postfix как before-queue milter, что попроще в плане конфигов и демонов.

Прежде чем мы начнем, пара замечаний: 1) Все, что можно сделать через WinSCP, я делаю через него. Поэтому, если я не привожу каких-то команд, значит... вы поняли.  2) Следите за разрешениями файлов и папок. Для меня это стало основным источником проблем при настройке.

Batv-tools собирается из исходников, которые я просто скачал на свой компьютер, распаковал архив и залил конечную папку с файлами проекта batv-tools-master в каталог /tmp Zentyal через WinSCP. Теперь нужно установить средства компиляции и библиотеки необходимые проекту. В "Аdministrator console" Zentyal выполняем:

apt-get install build-essential libssl-dev libmilter-dev

Копилируем проект:

cd /tmp/batv-tools-master && make

Генерируем мастер ключ, на основе которого потом будут создаваться токены пользователей:

batv-keygen -f /etc/batv-key

Копируем конфигурационные файлы batv-tools в /etc:

cp ./doc/examples/*.conf /etc 

Копируем исполняемые файлы в /usr/sbin:

cp batv-milter batv-sendmail batv-sign batv-validate /usr/sbin

Редактируем файл /etc/batv-keys.conf:
# Sample batv-keys.conf file.
...

...
# Typical mapping for the entire example.com domain:
#@example.com        /etc/batv-key.example.com
@domain.tld    /etc/batv-key
...
Вместо domain.tld небходимо прописать имя своего домена. Вообще, как видно из описания, доменов может быть несколько, как и файлов мастер ключей. Если так, то там же нужно прописать каждый.

Редактируем файл /etc/batv-milter.conf:
# Example batv-milter.conf
...

...
# Path to the socket file. If you're using Postfix you may want
# to put the socket file in /var/spool/postfix so it's accessible
# even when Postfix is chroot'd.
#socket            /var/run/batv-milter/batv-milter.sock

socket            /var/spool/postfix/batv-milter/batv-milter.sock
...
Меняем путь к сокету, т. к. Postfix в Zentyal 3.5 работает под chroot. Также можно поменять реакцию batv-milter на backscatter. По умолчаню этот спам пропускается, но в письмо добавляется специальный заголовок: X-Batv-Status, который может быть в дальнейшем проанализирован, например с помощью SpamAssassin. Если же вы хотите, чтобы не прошедшие проверку уведомления отвергались еще на этапе smtp-диалога, то необходимо раскомментировать строку: on-invalid reject в конце предпоследнего абзаца файла.
   
Теперь необходимо создать группу и пользователя под которым будет работать batv-milter. В "Аdministrator console" Zentyal выполняем:

adduser --quiet --system --group --home /var/spool/postfix/batv-milter batv-milter

Создаем рабочую папку для batv-milter, устанавливаем владельца и права:


mkdir -p /var/spool/postfix/batv-milter
chown batv-milter:batv-milter /var/spool/postfix/batv-milter
chmod g+wrxs /var/spool/postfix/batv-milter

Добавляем пользователя postfix в группу batv-milter, чтобы он имел доступ к сокету:


usermod -a -G batv-milter postfix
 
Теперь нам необходим init-файл, чтобы запускать batv-milter демоном. Можно скачать уже подправленный мною под наши реалии, поместить его в /etc/init.d Zentyal и установить на него разрешения 755. Содержимое оригинального файла можно посмотреть на github проекта.

Настраиваем запуск batv-milter при старте системы. В "Аdministrator console" Zentyal выполняем:

update-rc.d batv-milter start 19 2 3 4 5 . stop 21 0 1 6 .

Значения 19 и 21 взяты по произволу. Не знал, что туда написать, и сделал по аналогии со стартом/остановкой Amavis и SpamAssassin в системе. Вещи ведь в чем-то схожие.

Наконец, запускаем batv-milter:

/etc/init.d/batv-milter start

после этого в каталоге /var/spool/postfix/batv-milter должны появиться файлы batv-milter.pid и batv-milter.sock. Если их нет, дело - дрянь значит что-то пошло не так. Нужно вернуться в начало и вдумчиво проверить все этапы настройки.

Интегрируем batv-milter в postfix. Для этого редактируем /etc/zentyal/stubs/mail/main.cf.mas (почему у вас нет этого файла можно прочесть здесь). Ищем в нем строчку: "% if ($filter) {" и перед ней вставляем строки выделенные зеленым: 

non_smtpd_milters = unix:/batv-milter/batv-milter.sock
smtpd_milters = unix:/batv-milter/batv-milter.sock


% if ($filter) {

Сохраняем файл, но не спешим презапускать postfix. Проблема в том, что уведомления о невозможности доставки сообщений, которые посылает нашим пользователям наш собственный сервер, не проходят через batv-milter (таков дизайн). А ведь batv-milter не только прозрачно снабжает обратный адрес исходящих писем токеном "prvs=0336dff388=", но и так же прозрачно снимает токен "prvs=0336dff388=" с адресов получателей входящих уведомлений. Необходимо понимать, что в реальности в системе нет никаких адресов вида: prvs=0336dff388=user@domain.tld - посылать на них что-то бессмысленно, ничего не дойдет. Поэтому, когда уведомления идут в обход batv-milter, без снятия токена, они идут в никуда.

Сам разработчик batv-tools предлагает истользовать так называемый "+ синтаксис", который поддерживается и в postfix. Т. е. адрес с токеном при определенных настройках postfix и batv-milter выглядел бы так: user+prvs=0336dff388=@domain.tld - все, что после "+" postfix бы игнорировал и для него такой адрес ничем не отличался бы от user@domain.tld. Это отличная идея еще и потому, что вы могли бы оставлять в разных местах интернета разные варианты своего адреса, самостоятельно придумывая часть после "+". Например: user+pornolab@domain.tld при регистрации на... В будущем это помогло бы вам разобраться где чей спам в почте просто по адресу получателя.

Как все это настроить можно прочесть в документации к batv-tools - это не сложно. Во всяком случае проще чем остаться на привычном синтаксисе, что из вредности по историческим причинам сделал я. Благо, еще Ralph Babel описал и проблему и решение.

В /etc/postfix создаем файл batv.regexp со следующим содержимым:

/^prvs=[0-9]{4}[0-9a-f]{6}=(.*@domain\.tld)$/ $1


Вместо domain\.tld ставим имя своего домена и слэш перед точкой. Теперь редактируем файл /etc/zentyal/stubs/mail/master.cf.mas. Находим строку начинающуюся со слова "cleanup" и вставляем за ней стоки выделенные зеленым:


cleanup   unix  n       -       n       -       0       cleanup
  -o canonical_classes=envelope_recipient,header_recipient
  -o canonical_maps=regexp:/etc/postfix/batv.regexp

Внимание! Лидирующие пробелы обязательны! Сохраняем файл, в веб интерфейсе Zentyal меняем что-нибудь в настройках почты и жмем "Save changes", чтобы перезапустить компонент почтового сервера. Теперь, если послать письмо из нашего домена на сторонний почтовый ящик, а потом открыть в нем заголовки полученного письма, можно увидеть следующее:


Return-Path: <prvs=0336dff388=user@domain.tld>
Delivered-To: another-user@another-domain.tld
Received: from mail.domain.tld (mail.domain.tld [192.0.2.1])
        by mail.another-domain.tld (Postfix) with ESMTP id D543C20400
        for <another-user@another-domain.tld>; Tue, 16 Sep 2014 12:00:58
...
...

From: user@domain.tld
To: another-user <another-user@another-domain.tld>
Это означает, что все работает как задумано. На всякий случай, привожу здесь список файлов, каталогов, их владельцев и разрешений. При правильной установке все это должно быть на своих местах:

/etc/batv-key                           root:root          644
/etc/batv-keys.conf                     root:root          644
/etc/batv-milter.conf                   root:root          644

/usr/sbin/batv-milter                   root:root          755
/usr/sbin/batv-sendmail                 root:root          644
/usr/sbin/batv-sign                     root:root          755
/usr/sbin/batv-validate                 root:root          755

/var/spool/postfix/batv-milter/  batv-milter:batv-milter  2775
/etc/init.d/batv-milter                 root:root          755
/etc/postfix/batv.regexp                root:root          644

Дополнительно: Еще раз о BATV

 

Комментариев нет:

Отправить комментарий