Принцип работы копирования почтовых сообщений с помощью sendmail,
описанный в данной статье, состоит в описании своего майлера(mailer),
называемого в дальнейшем copymail, а так же в задании набора правил,
который "передает" всю проходящую почту на наш майлер. Copymail,
получив почтовое сообщение, действует как обычный транспортный агент,
доставляя письмо оригинальному получателю, а так же на дополнительный
адрес, заданный администратором. Почтовый адрес, на который будет
копироваться почта, не обязательно должен быть локальным для данной
машины. Описанный майлер (copymail) представляет из себя sendmail с
"оригинальным" (без изменений) конфигурационным файлом.
A
-------> [sendmail (1)]
|
| B
V
B <------- [sendamil (2)]
|
D <--------/
Рис. 1
sendmail(1), работающий в режиме daemon (-bd) получает (A) письмо и
передает (B) его sendmail(2). ( sendmail(2) -- это вышеописанный
майлер copymail). sendmail(2) отсылает письмо оригинальному получателю
(C) и дополнительному получателю (D).
Далее описаны несколько вариантов, конфигурации sendmail, для
различных требований к копированию почтовых сообщений.
При описании, автор подразумевает, что читатель обладает некоторым
"специфическим" набором знаний, а именно:
* знает что такое sendmail (http://www.sendmail.org/) :) .
* знает что такое m4 (http://www.sendmail.org/m4/basics.html)
* умеет из .mc (http://www.sendmail.org/m4/intro.html) файла получить .cf.
* знает где находится ${CFDIR}.
* знает куда должны помещаться конфигурационные файлы sendmail.
_________________________________________________________________
Вариант 1.
(C одним конфигурационным файлом sendmail)
* Следует поместить файл copymail.m4 (Вариант 1) ^1 в
директорию ${CFDIR}/mailer.
* В файл конфигурации sendmail (.mc) добавить следующие
строчки:
define(`COPYMAIL_MAILBOX',`user@domen')
MAILER(copymail)
заменив 'user@domen' на пользователя который должен получать копии
всех сообщений (он не обязательно должен быть локальным
пользователем на данной машине).
* Скомпилировать и установить новый конфиг.
* Перезапустить sendmail.
Вся проходящая почта будет (дополнительно) пересылаться на заданный
почтовый адрес.
Недостатки:
* В логах будут сообщения вида: Oct 11 15:59:54 mx.domen.ru
sendmail[9151]: g1EsNvk01649: to=user2@somewere.com.COPYMAIL ... .
* При генерации уведомлений об ошибках доставки, в сообщениях будут
указываться адреса вида user@domen.COPYMAIL.
^1. В этом и последующих примерах можно помещать строки из copymail.m4
непосредственно в конфигурационный файл sendmail(.mc), не забывая о
правильном порядке директив (http://www.sendmail.org/m4/intro.html).
MAILER следует помещать в конце конфигурационного файла, а define
-- до MAILER.
_________________________________________________________________
Вариант 2.
(C двумя конфигурационными файлами sendmail)
* Следует поместить copymail.m4 (Вариант 2) в директорию
${CFDIR}/mailer
* Скопируйте ваш конфигурационный файл sendmail (.mc) в файл под
именем sendmail.copy.mc
* Добавить следующие строчки в файл sendmail.copy.mc:
define(`COPYMAIL_MAILBOX',`user@domen')
define(`NOCOPY_CONFIG',`/etc/mail/sendmail.cf')
MAILER(copymail)
* Скомпилировать sendmail.copy.mc и установить как sendmail.copy.cf
* Остановить sendmail и запустить, следующим образом:
/usr/sbin/sendmail -bd -C /etc/mail/sendmail.copy.cf
/usr/sbin/sendmail -q30m -C /etc/mail/sendmail.cf
N.B. Такой запуск sendmail необходим для того, что бы письмо,
находящееся в очереди не копировалось каждые N минут, при каждой
попытке доставки. Первая копия (-bd) работает как SMTP daemon,
принимая письма (и копируя их). Вторая копия (-q30) работает
обработчиком (queueing) очереди, доставляя письма находящиеся в
очереди (и не копируя их, так как перед тем как попасть в очередь
письма уже были скопированы).
ВНИМАНИЕ! Если вы допустите ошибку при конфигурировании sendmail
(например вместо конфигурационного файла "nocopy", вы укажете "copy"),
sendmail уйдет в "вечный" цикл, с доставкой писем самой себе и с
потреблением всех ресурсов системы.
_________________________________________________________________
Вариант 3.
(C возможностью избирательно копировать почту)
Желательно иметь возможность как то управлять процессом копирования
почты. Например, избирательно копировать сообщения от какой либо
группы пользователей или наоборот -- не копировать. Для этого
предназначен copymail.m4 (Вариант 3). Sendmail следует
сконфигурировать как по Варианту 2, только вместо copymail.m4
(Вариант 2) возьмите copymail.m4 (Вариант 3)
Следует, так же создать файл /etc/mail/nocopy-users и поместить в него
почтовые адреса (в виде user@FQDN-domen ) или IP адреса (в форме
X.X.X.X). Почтовые сообщения приходящие на почтовые адреса ^1,
перечисленные в /etc/mail/nocopy-users или отправлямые от почтового
адреса или с IP адреса, перечисленных в /etc/mail/nocopy-users,
не будут копироваться.
Для достижения обратного результата, т.е. копирования почтовых
сообщений от определенных почтовых адресов или на определенные
почтовые адреса, и прохождения всех остальных почтовых сообщений без
копирования, следует воспользоваться copymail.m4 (Вариант 4).
Так же, следует создать файл /etc/mail/copy-users и поместить в него
"копируемые" адреса (формат адресов см. выше).
^1. Имеется в виду rcpt to: <addr>
Имеется в виду mail from: <addr>
_________________________________________________________________
Тестирование и отладка.
Прежде чем запускать sendmail в "боевом" режиме, я советую проверить
полученную конфигурацию. Для этого следует запустить sendmail в режиме
тестирования адреса (ключ -bt). Рассмотрим результат преобразования
адреса, который должен получиться при использовании copymail.m4
(Вариант 1):
mx# sendmail -bt -C /etc/mail/sendmail.cf
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> 3,0 user@domen.ru
canonify input: user @ domen . ru
Canonify2 input: user < @ domen . ru >
Canonify2 returns: user < @ domen . ru . >
canonify returns: user < @ domen . ru . >
parse input: user < @ domen . ru . >
Parse0 input: user < @ domen . ru . >
Parse0 returns: user < @ domen . ru . >
ParseLocal input: user < @ domen . ru . >
ParseLocal returns: $# copymail $@ domen . ru . COPYMAIL $: user @ domen . ru . COPYMAIL
parse returns: $# copymail $@ domen . ru . COPYMAIL $: user @ domen . ru . COPYMAIL
>
В результате должен вызваться майлер copymail и адрес должен
переписаться в виде user@domen.ru.COPYMAIL. Теперь следует проверить
"обратное" преобразование, т.е. письмо принятое от copymail должно
разрешиться в "нормальный" адрес:
> 3,0 user@domen.ru.COPYMAIL
canonify input: user @ domen . ru . COPYMAIL
Canonify2 input: user < @ domen . ru . COPYMAIL >
Canonify2 returns: user < @ domen . ru . COPYMAIL >
canonify returns: user < @ domen . ru . COPYMAIL >
parse input: user < @ domen . ru . COPYMAIL >
Parse0 input: user < @ domen . ru . COPYMAIL >
Parse0 returns: user < @ domen . ru . COPYMAIL >
ParseLocal input: user < @ domen . ru . COPYMAIL >
ParseLocal returns: user < @ domen . ru . >
Parse1 input: user < @ domen . ru . >
MailerToTriple input: < > user < @ domen . ru . >
MailerToTriple returns: user < @ domen . ru . >
Parse1 returns: $# esmtp $@ domen . ru . $: user < @ domen . ru . >
parse returns: $# esmtp $@ domen . ru . $: user < @ domen . ru . >
>
В результате адрес должен разрешиться в один из майлеров, кроме
copymail. К примеру адрес может разрешиться в локальный майлер ($#
local $: user) или в майлер esmtp ($# esmtp $@ domen . ru . $: user < @ domen . ru . >).
Теперь рассмотрим результат преобразования адреса при использовании
copymail.m4 (Вариант 2 (3,4)):
mx# sendmail -bt -C /etc/mail/sendmail.copy.cf
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> 3,0 user@domen.ru
canonify input: user @ domen . ru
Canonify2 input: user < @ domen . ru >
Canonify2 returns: user < @ domen . ru . >
canonify returns: user < @ domen . ru . >
parse input: user < @ domen . ru . >
Parse0 input: user < @ domen . ru . >
Parse0 returns: user < @ domen . ru . >
ParseLocal input: user < @ domen . ru . >
ParseLocal returns: $# copymail $@ localhost $: user < @ domen . ru . >
parse returns: $# copymail $@ localhost $: user < @ domen . ru . >
>
В результате должен вызваться майлер copymail: $# copymail $@
localhost $: user < @ domen . ru . >.
Если в результате тестирования адресов у вас не получается то, что вы
ожидаете, например используется copymail.m4 (Вариант 3),
пользователь user@domen.ru включен в /etc/mail/nocopy-users, а в
результате почта для этого пользователя все равно копируется, то
попробуйте воспользоваться следующими рекомендациями:
* Не забывайте перезапускать sendmail после установки нового
конфигурационного файла.
* Не забывайте перезапускать sendmail после изменения списка адресов
в файлах /etc/mail/nocopy-users или /etc/mail/copy-users.
* Не забывайте что правая и левая части в правилах подстановки (R)
отделяются табуляцией.
* Проверьте что вы правильно указали sendmail файл
/etc/mail/nocopy-users и sendmail загрузил список в класс NOCOPY.
(Конструкция $={NOCOPY} позволяет просмотреть содержимое класса).
mx# sendmail -bt -C /etc/mail/sendmail.copy.cf
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> $={NOCOPY}
> user@domen.ru
>
* Поробуйте воспользоваться отладочным режимом (-d) sendmail, что бы
получить больше информации о процессе преобразования адресов:
mx# sendmail -bt -d21.12 -C /etc/mail/sendmail.copy.cf
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> 3,0 user@domen.ru
...
-----callsubr ParseLocal (98)
ParseLocal input: user < @ domen . ru . >
-----trying rule: $* < @ $+ . > $*
-----rule matches: $: $1 < @ $2 . > $3 $| $1 @ $2
rewritten as: user < @ domen . ru . > $| user @ domen . ru
-----trying rule: $* < @ $+ . > $* $| $={NOCOPY}
-----rule matches: $@ $1 < @ $2 . > $3
rewritten as: user < @ domen . ru . >
ParseLocal returns: user < @ domen . ru . >
rewritten as: user < @ domen . ru . >
...
parse returns: $# local $: user
>
_________________________________________________________________
Privacy violation.
(Морально-этические стороны вопроса)
Копирование почты является нарушением морально-этических (а возможно
даже и юридических) прав, если только пользователь не был предупрежден
об этом до начала процесса копирования почты (а ещё лучше до того как
получил почтовый ящик)... Предлагаемый ниже вариант copymail.m4
позволяет вставить в каждое копируемое письмо некоторый заголовок
(например назовем его X-Privacy-violation), в котором будет честно
сказано что данное письмо было скопировано, а так же будет указано
кому и зачем оно было скопировано. По такому же принципу можно
изменить/дополнить один из стандарных заголовков, например To: или
Subject:.
...
Date: Wed, 20 Feb 2002 17:25:13 +0300 (MSK)
From: User
To: user2@domen.ru
Subject: TEST
...
Другие варианты copymail.m4 следует дополнить по аналогии с
приведенным примером.
_________________________________________________________________