Копия статьи
Задача — требуется контролировать переписку определенных сотрудников (официальная версия — создать backup почтовой переписки с возможностью последующего просмотра). Другими словами необходимо, чтобы при отправке письма пользователем (например, user@mydomain.ru), доставлял его почту как обычно адресату, а также дублировал это письмо в определенный ящик (например, big_brother@mydomain.ru).
На первый взгляд задача довольно не простая, но как оказалось — всё довольно легко реализуется. Имеем — операционная система FreeBSD и почтовый сервер на базе Postfix. Вот какие возможности для решения этой задачи предоставляет нам Postfix:
- always_bcc = addressДоставляет копии ВСЕХ сообщений (входящих и исходящих) на указанный адрес (поддерживается с Postfix v.2.1). Например, указав в /usr/local/etc/postfix/mail.cf строку always_bcc = backup@mydomain.ru можно сделать полный бэкап всей почты на адрес backup@mydomain.ru, вот только не повезет тому, кто это всё разгребать будет.
- sender_bcc_maps = type:table и recipient_bcc_maps = type:tableТаблицы соответствия отправителя/получателя с адресами доставки копий сообщений (функция доступна в Postfix 2.1 и выше.) То что нам и нужно.
Рассмотрим 2 варианта реализации — на основе файлов (индексированных карт hash) и базы данных MySQL.
Способ с использованием индексированных hash карт
Мы можем контролиривать, что хотим получить в результате — копировать на определенный ящик только отправляемые пользователем сообщения или только входящие, а может и то и другое.
Для примера рассмотрим вариант копирования исходящих сообщений:
1. Создаем файл в каталоге /usr/local/etc/postfix/, содержащий записи о том с какого почтового адреса копировать почту и на какой отправлять копии — назовем его sender_bcc. Добавляем в него строчку в формате:
user@mydomain.ru backup@mydomain.ru
user2@mydomain.ru backup@mydomain.ru
2. Добавляем в main.cf строчку
sender_bcc_maps = hash:/usr/local/etc/postfix/sender_bcc
3. Обязательно создаем индексированный файл:
postmap /usr/local/etc/postfix/sender_bcc
4. Перезагружаем постфикс и любуемся копированием исходящей почты.
Аналогичные шаги нужно проделать для получения возможности копирования входящей почты. Вместо sender_bcc_maps следует использовать recipient_bcc_maps.
recipient_bcc_maps = hash:/etc/postfix/recipient_bcc
Внимание! После внесения изменений не забываем перестроить хэш:
postmap /usr/local/etc/postfix/recipient_bcc
postmap /usr/local/etc/postfix/sender_bcc
Способ с использованием MySQL
Подразумевается, что вы уже используете MySQL совместно с Postfix для хранения учетных записей, транспорта и т.д.
1. Создаем табличку bcc в вашей базе данных
CREATE TABLE bcc (
id int(10) unsigned NOT NULL auto_increment,
sender varchar(128) NOT NULL default '',
recipient varchar(128) NOT NULL default '',
copy varchar(128) NOT NULL default '',
PRIMARY KEY (id)
) TYPE=MyISAM;
2. в /usr/local/etc/postfix/ создаем файлы sender_bcc.cf и recipient_bcc.cf:
sender_bcc.cf
user = postfix_user
password = postfix_password
dbname = mail_database
query = SELECT copy FROM bcc WHERE sender = '%s'
hosts = 127.0.0.1
recipient_bcc.cf
user = postfix_user
password = postfix_password
dbname = mail_database
query = SELECT copy FROM bcc WHERE recipient = '%s'
hosts = 127.0.0.1
3. В main.cf добавляем строчки
sender_bcc_maps = mysql:/usr/local/etc/postfix/sender_bcc.cf
recipient_bcc_maps = mysql:/usr/local/etc/postfix/recipient_bcc.cf
4. Перезапускам Postfix для применения изменений. Изменения данных в таблице MySQL bcc применяются без перезапуска Postfix.
Избавляемся от дублирования сообщений bcc_maps
Чтобы не происходило дублирования почты при использовании bcc_maps в master.cf следует добавить строчку:
-o receive_override_options=no_address_mappings
В моём случае это выглядит так:
smtp inet n - n - - smtpd
#AntiSPAM + DrWeb
-o receive_override_options=no_address_mappings
-o content_filter=kas3scan:127.0.0.1:9026
Напоследок — неплохая статья по настройке Postfix , хотя сам несколько иначе строил, но руки пока не доходят написать свою статью полностью. Хотя есть некоторые наработки, описания которых не встречал в сети.