Аутсорсинг ИТ, Web-разработка
|
Этот документ описывает функционал Postfix 2.1 и последующих версий .
Обычно Postfix принимает почту, помещает ее в очередь и затем доставляет. С помощью внешней фильтрации содержимого, описанной в этом документе, Вы можете фильтровать почту ПОСЛЕ ее помещения в очередь. Этот подход отделяет процесс приема почты от процесса фильтрации и дает Вам возможность запускать несколько процессов фильтрации почты параллельно.
Схема фильтрация после помещения в очередь:
Сетевые или
локальные пользователи-> Очередь
Postfix-> Фильтр
содержимого-> Очередь
Postfix-> Сетевой или локальный
почтовый ящик
Этот документ описывает реализации процесса фильтрации, которые используют один экземпляр Postfix для всех задач: получение почты, фильтрация содержимого и доставка. Варианты использования двух отдельных экземпляров Postfix будут описаны в последующих версиях данного документа.
Фильтрация писем после их помещения в очередь не конфликтует с методом, описанным в документе Фильтрация ДО помещения в очередь, где фильтрация входящей SMTP-почты происходит ДО ее помещения в очередь Postfix.
Этот документ описывает два варианта фильтрации ВСЕЙ почты, а также некоторые возможности для ВЫБОРОЧНОЙ фильтрации почты в Postfix.
Внешний фильтр содержимого писем получает нефильтрованную почту от Postfix (как описано ниже) и предпринимает одно из следующих действий:
Возвращает письмо обратно в Postfix, возможно изменив содержмое и/или место назначения.
Отклоняет письмо (отправив соответствующий код статуса обратно в Postfix). Postfix вернет почту отправителю..
ЗАМЕЧАНИЕ: Учитывая огромное количество почтовых червей и нежелательной почты (СПАМ), возвращать письмо отправителю - ПЛОХАЯ ИДЕЯ. Адрес отправителя почти наверняка не является создателем сообщения. Лучше просто отбрасывать известные вирусы и помещать подозрительные письма в карантин, тем самым предоставляя людям возможность решать, что с ними делать.
Первый пример фильтрации весьма прост в установке. Postfix принимает нефильтрованную почту из сети с помощью сервера smtpd(8), затем передает ее фильтру, используя агент доставки pipe(8) . Фильтр содержимого внедряет письма обратно в Postfix с помощью команды sendmail(1), таким образом Postfix может доставить их конечному адресату.
Соответственно данной схеме работы, почта, которая поступает в Postfix с использованием команды sendmail(1) фильтроваться не может.
На схеме, приведенной ниже, имена со следующими за ними цифрами - это команды или демоны Postfix. Смотрите также обзор архитектуры Postfix.
Нефильтрованная почта
->
smtpd(8)
pickup(8)>- cleanup(8) ->
Очередь
Postfix qmgr(8)-< local(8)
smtp(8)
pipe(8)->
->
Отфильтрованная почта
Отфильтрованная почта
^
||
vmaildrop
queue<- Postfix
postdrop(1)<- Postfix
sendmail(1)<- Фильтр
содержимого
Фильтр содержимого может быть простым shell-скриптом, например, таким:
1 #!/bin/sh
2
3 # Простой фильтр на shell. Он должен вызываться следующим образом:
4 # /path/to/script -f отправитель получатели...
5
6 # Localize these.
7 INSPECT_DIR=/var/spool/filter
8 SENDMAIL="/usr/sbin/sendmail -i"
9
10 # Коды выхода (из <sysexits.h>)
11 EX_TEMPFAIL=75
12 EX_UNAVAILABLE=69
13
14 # Очистка по завершении работ (или экстренном завершении).
15 trap "rm -f in.$$" 0 1 2 3 15
16
17 # Начинаем обработку..
18 cd $INSPECT_DIR || {
19 echo $INSPECT_DIR не существует; exit $EX_TEMPFAIL; }
20
21 cat >in.$$ || {
22 echo Не могу сохранить письмо в файл; exit $EX_TEMPFAIL; }
23
24 # Фильтрация должна быть здесь..
25 # filter <in.$$ || {
26 # echo Содержимое сообщения отклонен; exit $EX_UNAVAILABLE; }
27
28 $SENDMAIL "[email protected]" <in.$$
29
30 exit $?
Комментарии:
Строка 21: Сначала сохраняем полученное письмо в файл, а затем пропускаем содержимое файла через сторонний фильтр..
Строка 22: Если письмо не может быть сохранено в файл, то доставка откладывается путем завершения работы с кодом выхода 75 (EX_TEMPFAIL). Postfix помещает письмо в очередь отложенной почты (deferred mail queue) и пытается доставить его позже.
Строка 25: Вам нужно указать здесь название реального фильтра, который получает содержимое письма со стандартного ввода.
Строка 26: Если фильтр сталкивается с проблемой, письмо возвращается адресату (bounced) путем выхода с кодом 69 (EX_UNAVAILABLE). Postfix вернет сообщение отправителю (в качестве письма, которое не может быть доставлено).
ЗАМЕЧАНИЕ: Учитывая огромное количество почтовых червей и нежелательной почты (СПАМ), возвращать письмо, содержащее вирусы или являющееся СПАМом, отправителю - ПЛОХАЯ ИДЕЯ. Адрес отправителя почти наверняка не является создателем сообщения. Лучше просто отбрасывать известные вирусы и помещать подозрительные письма в карантин, тем самым предоставляя людям возможность решать, что с ними делать.
Строка 28: Если содержимое в порядке, то оно передается на вход команды Postfix sendmail. Код выхода команды sendmail мы возвращаем при выходе из нашего фильтра. Postfix доставляет письмо как обычно.
Строка 30: Возвращаем код выхода команды sendmail.
Предполагается, что Вы будете запускать данный скрипт вручную, пока не убедитесь, что он работает верно. Скрипту необходимо подавать реальное сообщение (заголовки + содержимое) на стандартный вход:
% /path/to/script -f отправитель получатель... <message-file
Как только вы убедились в праильной работе скрипта, можно действовать далее:
Создайте пользователя, от имени которого будет выполняться фильтр, назовем его "filter". Этот фильтр обрабатывает все потенциально опасное содержимое, именно поэтому он должен выполняться отдельным аккаунтом. Не используйте для этой цели "nobody", а тем более "root" или "postfix".
Создайте директорию /var/spool/filter и сделайте ее доступной только пользователю "filter". В ней фильтр контента будет хранить свои временные файлы.
Настройте Postfix на доставку почты фильтру с помощью агента доставки pipe(8).
/etc/postfix/master.cf: # ============================================================= # service type private unpriv chroot wakeup maxproc command # (yes) (yes) (yes) (never) (100) # ============================================================= filter unix - n n - 10 pipe flags=Rq user=filter argv=/path/to/script -f ${sender} -- ${recipient}
В приведенной конфигурации Postfix может запускать вплоть до 10-ти процессов фильтрации параллельно. Вам следует изменить это количество в соответствии со своими нуждами. Проверка содержимого обычно потребляет достаточно много ресурсов системы, поэтому Вам не следует запускать слишком много процессов одновременно.
Чтобы включить фильтрацию только приходящей через SMTP почты, добавьте "-o content_filter=filter:dummy" в элемент файла master.cf, описывающий SMTP сервер Postfix:
/etc/postfix/master.cf: # ============================================================= # service type private unpriv chroot wakeup maxproc command # (yes) (yes) (yes) (never) (100) # ============================================================= smtp inet ...other stuff here, do not change... smtpd -o content_filter=filter:dummy
Строка "content_filter" заставляет Postfix добавлять по одному запросу к фильтру контента на каждое входящее сообщение. Содержимое запроса - "filter:dummy". Эта запись прерывает нормальную маршрутизацию почты, перенаправляя письма к фильтру.
Синтаксис конфигурационного параметра content_filter аналогичен синтаксису правой части транспортной таблицы Postfix.
Выполните команду "postfix reload", чтобы применить изменения.
С shell-скриптом, приведенным выше, производительность Postfix при обработке транзитной почты (приходит и уходит по SMTP) уменьшится где-то в четыре раза. Также неизбежны потери производительности при записи/удалении каждого временного файла в процессе фильтрации. Уменьшение производительности менее значимо для почты, которая поступает и/или доставляется локально, т.к. этот процесс уже более медленный, чем SMTP-транзит почты.
Основная проблема фильтров, аналогичных нашему, - это относительно низкая надежность. Причина в том, что программное обеспечение в данном случае не использует четко определенный протокол для взаимодействия с Postfix. Если shell-скрипт аварийно завершает работу из-за каких-либо проблем с памятью, то он не вернет правильный код выхода, как показано в файле /usr/include/sysexits.h. Как следствие, вместо помещения письма в очередь отложенных сообщений (deferred queue), Postfix просто вернет его отправителю с сообщением о невозможности доставки. Подобный недостаток надежности может иметь место и в том случае, когда само фильтрующее ПО столкнется с отсутствием/недостатком тех или иных ресурсов.
Простой метод фильтрации не совместим с действиями фильтра, которые вызываются через header_checks или body_checks. После повторного внедрения писем в Postfux с помощью команды sendmail, эти действия будут выполнены повторно. Таким образом, мы получаем зацикленную фильтрацию. Расширенный способ проверки содержимого (см. ниже) позволяет использовать выключать проверки header_checks и/или body_checks для уже отфильтрованной почты.
Чтобы выключить фильтр:
В файле master.cf удалите строку "-o content_filter=filter:dummy" из элемента, описывающего SMTP сервер Postfix.
Выполните команду "postsuper -r ALL", чтобы удалить информацию, связанную с фильтром содержимого, из существующих файлов очереди.
Выполните команду "postfix reload".
Этот пример фильтра сложнее, но позволяет достичь большей производительности. Данный фильтр более надежен, гораздо меньше вероятность возврата писем с сообщением о невозможности доставки в том случае, сли фильтр столкнулся с недостатком ресурсов. Фильтр получает нефильтрованную почту по протоколу SMTP локально на порту 10025, проверенные письма отсылаются обратно в Postfix по SMTP локально на порт 10026.
Для фильтров, не поддерживающих SMTP, Bennett Todd написал SMTP прокси, который представляет собой неплохой PERL/SMTP каркас для реализации фильтрования. Ссылка: http://bent.latency.net/smtpprox/.
На схеме, приведенной ниже, имена со следующими за ними цифрами - это команды или демоны Postfix. Смотрите также обзор архитектуры Postfix.
Нефильтрованная почта
Нефильтрованная почта->
->smtpd(8)
pickup(8)>- cleanup(8) -> qmgr(8)
Очередь
Postfix-< smtp(8)
local(8)->
->Отфильтрованная почта
Отфильтрованная почта^
||
vsmtpd(8)
10026smtp(8)
^
||
vФильтр содержимого 10025
В данном примере фильтруется вся почта, как приходящая по SMTP, так и поступившая локально через клманду sendmail. В конце данного документа приведена информация о том, как отключить проверку почты от локальных пользователей и как настроить фильтрацию в зависимости от назначения письма.
Производительность Postfix снизится где-то в два раза для почты, которая приходит и уходит по протоколу SMTP, если фильтр в процессе работы не создает временных файлов. Каждый дополнительный временный файл, создаваемый почтовым фильтром, вносит дополнительные потери производительности.
Чтобы включить проверку всей почты с помощью фильтра, укажите в файле main.cf:
/etc/postfix/main.cf: content_filter = scan:localhost:10025 receive_override_options = no_address_mappings
Строка "content_filter" заставляет Postfix добавлять для каждого входящего письма один запрос на обращение к фильтру. Сожержимое запроса - "scan:localhost:10025". Эти запрсы на обработку фильтром добавляются серверами smtpd(8) и pickup(8) (и qmqpd(8), если Вы включили данный сервис).
Запрсы на обработку почты фильтром хранятся в файлах очереди. Таким образом Postfix определяет, какие письма нуждаются в фмльтрации. Если файл очереди содержит запрос на обработку фильтром содержимого, то менеджер очереди передаст письмо соответствующему фильтру, независимо от того, куда адресовано данное письмо.
Строка "receive_override_options" отключает манипуляции с адресами до обработки почты фильтром. Таким образом фильтр может работать с оригинальными адресами, а не результатом применения алиасов, канонических преобразований, автоматического копирования, маскировки адресов и т.п.
В этом примере "scan" - это экземпляр SMTP клиента Postfix с немного отличающейся конфигурацией. В конфигурационном файле master.cf это выглядит следующим образом:
/etc/postfix/master.cf: # ============================================================= # service type private unpriv chroot wakeup maxproc command # (yes) (yes) (yes) (never) (100) # ============================================================= scan unix - - n - 10 smtp -o smtp_send_xforward_command=yes
В приведенной конфигурации Postfix может запускать вплоть до 10-ти процессов фильтрации параллельно. Вам следует изменить это количество в соответствии со своими нуждами. Проверка содержимого обычно потребляет достаточно много ресурсов системы, поэтому Вам не следует запускать слишком много процессов одновременно.
Благодаря параметру "-o smtp_send_xforward_command=yes" транспорт "scan" пытается передать оригинальное имя и IP адрес клиента процессу smtpd, который принимает почту после обработки фильтром. Таким образом отфильтрованная почта регистрируется с реальным IP и именем хоста клиента. Более подробная информация в документах smtp(8) и XFORWARD_README.
Фильтр контента может быть запущен с помощью сервиса spawn в Postfix. Spawn является аналогом inetd в Postfix. Например, запустить до 10 процессов фильтрации на адресе localhost с портом 10025 можно таким образом:
/etc/postfix/master.cf: # =================================================================== # service type private unpriv chroot wakeup maxproc command # (yes) (yes) (yes) (never) (100) # =================================================================== localhost:10025 inet n n n - 10 spawn user=filter argv=/path/to/filter localhost 10026
"filter" - это выделенный для фильтра пользовательский аккаунт. Этот пользователь никогда не будет входить в систему, поэтому ему легко может быть назначен пароль "*", несуществующие оболочка и домашняя директория. С правами этого пользователя фильтруется весь потенциально опасный контент, именно поэтому следует использовать отдельного пользователя.
Если Вы хотите, чтобы Ваш фильтр самостоятельно "слушал" 10025 порт, то следует запускать его отдельно (т.е. точно так же, как принято запускать других демонов в вашей UNIX-среде), без использования spawn сервиса Postfix.
Задача фильтра содержимого либо отклонить (bounce) почту, вернув соответствующий диагностический код, либо передать отфильтрованное письмо обратно, отправив его выделенному smtpd серверу Postfix, ждущему соединений локально на порту 10026.
Самый простой фильтр может просто копировать SMTP команды и данные со своего входа на выход. Если возникают проблемы, все, что должен сделать фильтр - передать `550 content rejected' после поступления '.' на входе, а также разорвать соединение на выходе, не отправив `.'.
/etc/postfix/master.cf: # =================================================================== # service type private unpriv chroot wakeup maxproc command # (yes) (yes) (yes) (never) (100) # =================================================================== localhost:10026 inet n - n - 10 smtpd -o content_filter= -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks -o smtpd_helo_restrictions= -o smtpd_client_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o mynetworks=127.0.0.0/8 -o smtpd_authorized_xforward_hosts=127.0.0.0/8
ПРИМЕЧАНИЕ: Не используйте пробелы вокруг "=" и ",".
ПРИМЕЧАНИЕ: В SMTP сервере Postfix, принимающем отфильтрованную почту, ограничение по кол-ву процессов не должно быть меньше, чем кол-во параллельных процессов фильтра.
Строка "-o content_filter=" переопределяет настройки в файле main.cf и отменяеь обработку фильтром уже отфильтрованной почты. Это сделано для предотвращения непрерывного цикла фильтрации.
Строка "-o receive_override_options" переопределяет настройки файла main.cf. Это дополнение к опциям, которые указаны в файле main.cf:
Отключаем попытки проверки адресов получателей, проверки заголовков/тела писем. Эта работа уже была проделана до передачи письма фильтру контента, поэтому выполнять ее повторно - расточительная трата ресурсов.
Задействовать алиасы, канонические преобразования, автоматическое копирование, маскировку адресов и прочие манипуляции с адресами.
Манипуляции, соответствующие receive_override_options выполняются либо самим SMTP сервером, либо передаются сервису cleanup.
Опции "-o smtpd_xxx_restrictions" и "-o mynetworks=127.0.0.0/8" переопределяют настройки в файле main.cf. Они отключают проверки на нежелательную почту, которые были бы в данном месте излишней тратой времени.
Опция "-o smtpd_authorized_xforward_hosts=127.0.0.0/8" указывает smtpd серверу на адреса, от которых он будет принимать информацию о реальных IP адресе/имени хоста клиента Более подробная информация может быть найдена в документах XFORWARD_README и smtpd(8).
В подходе к проверке почты типа "слоеный пирог", который описан здесь, важно правильно сбалансировать количество параллельных процессов, учитывая имеющиеся в наличии ресурсы (память, ввод/вывод, время процессора). При слишком малом количестве процессов проверки контента почты письма будут скапливаться в очереди активных сообщений (active queue) даже при малом почтовом трафике. При слишком большом количестве процессов фильтрации Postfix начнет помещать почту, предназначенную для фильтра, в отложенную очередь, если фильтр столкнется с ошибками из-за нехватки ресурсов.
На данный момент настройка производительности фильтра - это процесс проб и ошибок. Анализ сложен, так как отфильтрованная и нефильтрованная почта находятся в одной и той же очереди. Как было сказано во вступлении, фильтрация содержимого с использованием нескольких экземпляров Postfix будет описана в последующих редакциях этого документа.
Для отключения "улучшенного" фильтра содержимого:
Удалите или закомментируйте следующие две строки в файле main.cf. Другие изменения, внесенные при настройке не производят эффекта, кодка фильтрация выключена.
/etc/postfix/main.cf: content_filter = scan:localhost:10025 receive_override_options = no_address_mappings
Выполните команду "postsuper -r ALL" чтобы удалить информацию о фильтре из существующих файлов очереди.
Выполните команду "postfix reload".
Самый простой способ - настроить один экземпляр Postfix с несколькими адресами SMTP сервера в конфигурационном файле master.cf:
Два IP адреса SMTP сервера для почты только от внутренних пользователей. Фильтрация выключена.
/etc/postfix.master.cf: # ================================================================== # service type private unpriv chroot wakeup maxproc command # (yes) (yes) (yes) (never) (100) # ================================================================== 1.2.3.4:smtp inet n - n - - smtpd -o smtpd_client_restrictions=permit_mynetworks,reject 127.0.0.1:smtp inet n - n - - smtpd -o smtpd_client_restrictions=permit_mynetworks,reject
Один IP адрес SMTP сервера для внешних пользователей с включеной фильтрацией почты.
/etc/postfix.master.cf: # ================================================================= # service type private unpriv chroot wakeup maxproc command # (yes) (yes) (yes) (never) (100) # ================================================================= 1.2.3.5:smtp inet n - n - - smtpd -o content_filter=filter-service:filter-destination -o receive_override_options=no_address_mappings
После этого вы можете следовать инструкциям, приведенным в описании "простого" или "улучшенного" фильтра почты, за исключением того, что Вы не должны указывать опции "content_filter" или "receive_override_options" в конфигурационном файле main.cf.
Вы можете настроить один экземпляр Postfix с несколькими IP адресами в файле master.cf. Каждому IP-фдресу соответствует свой фильтр. Конечно, не следует забывать о изменении соответствующих MX записей в случае необходимости.
/etc/postfix.master.cf: # ================================================================= # service type private unpriv chroot wakeup maxproc command # (yes) (yes) (yes) (never) (100) # ================================================================= # SMTP сервер для доменов, почта которых проверяется фильтром service1:dest1 1.2.3.4:smtp inet n - n - - smtpd -o content_filter=service1:dest1 -o receive_override_options=no_address_mappings # SMTP сервер для доменов, почта которых проверяется фильтром service2:dest2 1.2.3.5:smtp inet n - n - - smtpd -o content_filter=service2:dest2 -o receive_override_options=no_address_mappings
После этого вы можете следовать инструкциям, приведенным в описании "простого" или "улучшенного" фильтра почты, за исключением того, что Вы не должны указывать опции "content_filter" или "receive_override_options" в конфигурационном файле main.cf.
Конфигурации проверки содержимого, которые приводились ранее, статичны. Почта, которая следует определенным путем через почтовую систему либо всегда фильтруется, либо нет. Начиная с Postfix 2.0 Вы также можете настроить конфигурацию проверки контента "на лету".
Включение фильтрации содержимого в зависимости от результата поиска в таблице access(5):
/etc/postfix/access: whatever FILTER foo:bar
Включение фильтрации содержимого в зависимости от результата обработки header_checks(5) или body_checks(5):
/etc/postfix/header_checks: /whatever/ FILTER foo:bar
Вы можете использовать это в таблицах доступа сервера smtpd, равно как и в проверках заголовков/тела письма демона cleanup. Эта функциональность должна использоваться весьма осторожно: следует отключить все антиспам-проверки (UCE) в smtpd сервере, принимающем отфильтрованную почту, иначе Вы столкнетесь с зацикливанием фильтрации.
Ограничения:
Действия FILTER из таблиц доступа сервера smtpd и проверок заголовков/тела письма имеют приоритет над фильтром, указанным в конфигурационном файле main.cf параметром content_filter.
Если письмо соответствует нескольким проверкам, то выполняется лишь последняя из них.
Один и тот же фильтр применяется ко всем получателям данного письма.
© 2004-2006 ООО «ЭЛАНТЕК». | Адрес: Московская область, г. Фрязино, ул. Полевая, д.6, этаж 4, офис 20. Телефон: +7 (000) 000-00-00, E-mail: support@ricohprinters.ru |