Копирование почты с помощью sendmail (sendmail carboncopy filter mail)
Ключевые слова: sendmail , carboncopy , filter , mail , (найти похожие документы )
From: O. Koreshkov <okor salut.ru>
Date: Mon, 25 Dec 2002 13:01:37 +0000 (UTC)
Subject: Копирование почты с помощью sendmail
Оригинал: http://www.freeman.org.ua/doc/sendmail/cpsendmail.html
Копирование почты с помощью sendmail.
_________________________________________________________________
Нижеизложенный материал не претендует на полноту, четкость, ясность
или достоверность изложения и предоставляется автором "КАК ЕСТЬ".
Автор не несет никакой отвественности за любое использование данного
материала. Любое использование, копирование, цитирование, полностью
или частично должно включать данный текст, ссылку на данный ресурс, а
так же следующию строку без изменений:
© 2001-2002, O. Koreshkov <okor salut.ru>.
_________________________________________________________________
Принцип работы копирования почтовых сообщений с помощью 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 следует дополнить по аналогии с
приведенным примером.
_________________________________________________________________
copymail.m4 (Вариант 1):
PUSHDIVERT(-1)
ifdef(`COPYMAIL_MAILBOX',,
`define(`COPYMAIL_MAILBOX', `postmaster')')dnl
POPDIVERT
#########################################
### COPYMAIL Mailer specification ###
#########################################
VERSIONID(`$Id: cpsendmail.html,v 1.2 2002/06/14 18:39:10 freeman Exp $')dnl
LOCAL_CONFIG
D{COPYMAIL}COPYMAIL
C{CP}${COPYMAIL}
LOCAL_RULE_0
# Send all mail to copymail mailer
R$* < @ $+ . $~{CP} . > $#copymail $@ $2 . $3 . ${COPYMAIL} $: $1 @ $2
. $3 . ${COPYMAIL}
# if mail has been processed by copymail mailer, process it usual way...
R$* < @ $* . ${COPYMAIL} > $1 < @ $2 . >
# Send message to original recipient + additional mailbox: COPYMAIL_MAILBOX
Mcopymail, P=/usr/sbin/sendmail, F=fmSDFMu, S=0, R=0,
A=sendmail -N never COPYMAIL_MAILBOX.${COPYMAIL} $u
_________________________________________________________________
copymail.m4 (Вариант 2):
PUSHDIVERT(-1)
ifdef(`COPYMAIL_MAILBOX',,
`define(`COPYMAIL_MAILBOX', `postmaster')')dnl
ifdef(`NOCOPY_CONFIG',,
`errprint(`*** You must define NOCOPY_CONFIG for copymail mailer!!! ***')')dnl
POPDIVERT
#########################################
### COPYMAIL Mailer specification ###
#########################################
VERSIONID(`$Id: cpsendmail.html,v 1.2 2002/06/14 18:39:10 freeman Exp $')dnl
LOCAL_RULE_0
# Send all mail to copymail mailer
R$* < @ $+ . > $* $#copymail $@ localhost $: $1 < @ $2 . > $3
# Send message to original recipient + additional mailbox: COPYMAIL_MAILBOX
Mcopymail, P=/usr/sbin/sendmail, F=fmSDFMu, S=0, R=0,
A=sendmail -N never -C NOCOPY_CONFIG COPYMAIL_MAILBOX $u
_________________________________________________________________
copymail.m4 (Вариант 3):
PUSHDIVERT(-1)
ifdef(`COPYMAIL_MAILBOX',,
`define(`COPYMAIL_MAILBOX', `postmaster')')dnl
ifdef(`NOCOPY_USERS',,
`define(`NOCOPY_USERS', `-o /etc/mail/nocopy-users')')dnl
ifdef(`NOCOPY_CONFIG',,
`errprint(`*** You must define NOCOPY_CONFIG for copymail mailer!!! ***')')dnl
POPDIVERT
#########################################
### COPYMAIL Mailer specification ###
#########################################
VERSIONID(`$Id: cpsendmail.html,v 1.2 2002/06/14 18:39:10 freeman Exp $')dnl
LOCAL_CONFIG
F{NOCOPY}NOCOPY_USERS
LOCAL_RULE_0
# Send all mail (except $={NOCOPY}) to copymail mailer
R$* < @ $+ . > $* $: $1 < @ $2 . > $3 $| $1 @ $2
R$* < @ $+ . > $* $| $={NOCOPY} $@ $1 <@ $2 . > $3
R$* < @ $+ . > $* $| $* $: $1 <@ $2 . > $3 $| $&{client_addr}
R$* < @ $+ . > $* $| $={NOCOPY} $@ $1 <@ $2 . > $3
R$* < @ $+ . > $* $| $* $: $1 <@ $2 . > $3 $| $&f
R$* < @ $+ . > $* $| <$*> $: $1 <@ $2 . > $3 $| $4
R$* < @ $+ . > $* $| $={NOCOPY} $@ $1 <@ $2 . > $3
R$* < @ $+ . > $* $| $* $#copymail $@ localhost $: $1 < @ $2 . > $3
# Send message to original recipient + additional mailbox: COPYMAIL_MAILBOX
Mcopymail, P=/usr/sbin/sendmail, F=fmSDFMu, S=0, R=0,
A=sendmail -N never -C NOCOPY_CONFIG COPYMAIL_MAILBOX $u
_________________________________________________________________
copymail.m4 (Вариант 4):
PUSHDIVERT(-1)
ifdef(`COPYMAIL_MAILBOX',,
`define(`COPYMAIL_MAILBOX', `postmaster')')dnl
ifdef(`COPY_USERS',,
`define(`COPY_USERS', `-o /etc/mail/copy-users')')dnl
ifdef(`NOCOPY_CONFIG',,
`errprint(`*** You must define NOCOPY_CONFIG for copymail mailer!!! ***')')dnl
POPDIVERT
#########################################
### COPYMAIL Mailer specification ###
#########################################
VERSIONID(`$Id: cpsendmail.html,v 1.2 2002/06/14 18:39:10 freeman Exp $')dnl
LOCAL_CONFIG
F{COPY}COPY_USERS
LOCAL_RULE_0
# Send mail $={COPY} to copymail mailer
R$* < @ $+ . > $* $: $1 < @ $2 . > $3 $| $1 @ $2
R$* < @ $+ . > $* $| $={COPY} $#copymail $@ localhost $: $1 < @ $2 . > $3
R$* < @ $+ . > $* $| $* $: $1 <@ $2 . > $3 $| $&{client_addr}
R$* < @ $+ . > $* $| $={COPY} $#copymail $@ localhost $: $1 < @ $2 . > $3
R$* < @ $+ . > $* $| $* $: $1 <@ $2 . > $3 $| $&f
R$* < @ $+ . > $* $| <$*> $: $1 <@ $2 . > $3 $| $4
R$* < @ $+ . > $* $| $={COPY} $#copymail $@ localhost $: $1 < @ $2 . > $3
R$* < @ $+ . > $* $| $* $: $1 <@ $2 . > $3
# Send message to original recipient + additional mailbox: COPYMAIL_MAILBOX
Mcopymail, P=/usr/sbin/sendmail, F=fmSDFMu, S=0, R=0,
A=sendmail -N never -C NOCOPY_CONFIG COPYMAIL_MAILBOX $u
_________________________________________________________________
copymail.m4 (Вариант 5):
PUSHDIVERT(-1)
ifdef(`COPYMAIL_MAILBOX',,
`define(`COPYMAIL_MAILBOX', `postmaster')')dnl
ifdef(`NOCOPY_CONFIG',,
`errprint(`*** You must define NOCOPY_CONFIG for copymail mailer!!! ***')')dnl
POPDIVERT
#########################################
### COPYMAIL Mailer specification ###
#########################################
VERSIONID(`$Id: cpsendmail.html,v 1.2 2002/06/14 18:39:10 freeman Exp $')dnl
LOCAL_CONFIG
H?{COPIED}?X-Privacy-violation: The copy of this message was sent to <COPYMAIL_
MAILBOX> due to business requirements
Kiscopied macro
LOCAL_RULE_0
# Send all mail to copymail mailer
R$* < @ $+ . > $* $#copymail $@ localhost $: $1 < @ $2 . > $3 $(iscopied {COPIED} $@ YES $)
# Send message to original recipient + additional mailbox: COPYMAIL_MAILBOX
Mcopymail, P=/usr/sbin/sendmail, F=fmSDFMu, S=0, R=0,
A=sendmail -N never -C NOCOPY_CONFIG COPYMAIL_MAILBOX $u
_________________________________________________________________
Расположение ${CFDIR} в некоторых OS:
Solaris /usr/lib/mail
Linux /usr/lib/sendmail-cf
FreeBSD /usr/share/sendmail/cf
_________________________________________________________________
Список литературы:
* Sendmail installation and operation guide by Eric Allman
* Эви Немет & Co. UNIX: руководство системного администратора. 1997,
ISBN 5-7315-0021-5.
* Эхоконференции ru.unix.* .
* http://www.sendmail.org
Special thanks to: Lev Walkin.
P.S. Поправки приветствуются...
1 , iav (ok ), 21:58, 04/10/2005 [ответить ]
+ /–
Метод имеет один недстаток:
при отправке локального сообщения нескольким адресатам с ошибкой в адресе сервер ответит, что в адресе ошибка, а вместо ошибочного адреса выдаст весь список адресатов.