Сегодня мы будем строить традиционную юниксовую почтовую систему на локальной машине. В Unix вместо программ-"комбайнов" обычно используют наборы небольших специализированных программ, каждая из которых имеет небольшой набор функций, но умеет выполнять их хорошо. Так и в случае с почтой. Нам понадобятся:
1) Средство получения почты с pop3-сервера. Обычно это fetchmail. Эта программа умеет лишь скачивать письма с сервера и отдавать их локальной программе для дальнейшей обработки.
2) Почтовый сервер. Мы будем рассматривать postfix версии 2.x, но это может быть, например, qmail, exim или (ну мало ли) sendmail. В случае с postfix 1.x могут быть некоторые отличия в конфигурации. Т.к. мы не собираемся использовать свою машину как почтовый сервер для других машин (для чего в 1-ю очередь и нужны перечисленные программы), postfix у нас будет заниматься передачей почты от fetchmail программе доставки (см. ниже) и отправкой исходящих сообщений в Интернет по SMTP. Эта его функция называется MTA (Mail Transport Agent).
3) Средство локальной доставки (Mail Delivery Agent, MDA). В принципе, его функцию может выполнять и MTA, но мы будем использовать procmail. Эта часть нашей системы будет заниматься сортировкой полученных от MTA писем по папкам и, возможно, выборочным удалением писем или переписыванием их заголовков.
4) Средство чтения почты (Mail User Agent, MUA). Я использую mutt, но подойдет любой обычный почтовый клиент, умеющий отправлять письма локальному sendmail (эмулировать который будет postfix) и получать письма из локального mailbox/maildir. Например, подойдет kmail, а M2 не подойдет. MUA будет заниматься лишь чтением писем из локальных почтовых ящиков, написанием новых и отправкой их MTA.
Как всё должно работать
- fetchmail получает письма с pop3-сервера, в соответствии со своими настройками указывает в заголовках писем имя локального пользователя, которому предназначена почта, и отдает их postfix'у;
- он в соответствии с заголовками запускает procmail от имени соотв. пользователя и передает ему письма;
- procmail в соответствии со своими сколь угодно сложными настройками редактирует письма (если надо), часть удаляет (если надо), а оставшиеся раскладывает по папкам в домашнем каталоге пользователя;
- пользователь запускает свой любимый MUA, который настроен на просмотр всех папок, в которые procmail кладет письма;
- пользователь пишет в своем MUA письмо и "отправляет" его;
- MUA передает письмо postfix'у, который пытается отправить письмо указанному в настройках "вышестоящему" smtp-серверу. При этом если письмо отправить не удается (например, машина не подключена к Интернету в этот момент), оно откладывается "до лучших времен" (время от времени, с удваивающимся интервалом, postfix будет пытаться отправить все отложенные письма). Если письмо было адресовано локальному пользователю (да-да, возможно и такое - просто пишите <�логин>@<�имя компьютера> и письмо придет локальному адресату) - сразу будет вызван procmail.
Если примерно понятно, как это будет работать, можно приниматься за дело. Перечисленные программы, думаю, есть почти в любом современном дистрибутиве. После их установки необходимо настроить все элементы системы. Начнем с главной.
Настройка postfix
Во-1-х, следует отключить smtp-сервер (т.к. нам он не нужен, а в открытый 25 порт сразу же полезет куча хакеров icon_wink.gif). Для этого в /etc/postfix/master.cf закомментируем строчку, начинающуюся на smtp.
Теперь откроем /etc/postfix/main.cf и поменяем несколько строчек с учетом роли postfix на нашей машине.
mynetworks_style = host - на всякий случай запрещаем соединения на smtp-порт от всех машин кроме локальной (в принципе, мы все равно отключили smtp-демона, но если он необходим локально - этот параметр обязательно надо выставить именно так).
relayhost = my-smtp-server.ru - здесь надо указать smtp-сервер, который будет использован postfix для отправки писем. Лучше всего подойдет для этих целей smtp-сервер Вашего провайдера.
mailbox_command = /usr/bin/procmail -a $DOMAIN -d $LOGNAME - команда локальной доставки.
postfix необходимо настроить на запуск при старте системы (например, командой chkconfig postfix on).
И еще одна незаменимая для диалапщиков вещь. При каждом подключении к Интернету выполняются все файлы из /etc/ppp/ip-up.d. Поэтому положим туда файлик следующего содержания:
#!/bin/sh
SENDMAIL=/usr/sbin/sendmail
[ ! -x "$SENDMAIL" ] || exec "$SENDMAIL" -q >/dev/null 2>&1
Команда sendmail -q отправит всю отложенную почту (напоминаю, что postfix может эмулировать sendmail).
Данный файл взят из ALTLinux, в других дистрибутивах может иметься аналогичный по задачам (как минимум подобный есть в Mandrake, только там вызывается postfix flush).
Настройка fetchmail
Поскольку файл конфигурации fetchmail (.fetchmailrc) содержит пароли, доступ к нему должен иметь только его владелец (в противном случае fetchmail даже не запустится). Поэтому каждый пользователь, от которого планируется запускать fetchmail, должен иметь в домашнем каталоге свою копию настроек. Если на машине всего 1 такой пользователь, все равно придется скопировать его конфиг в /root или в /etc (для запуска fetchmail в режиме демона или через ip-up.d). Итак, обычный конфиг выглядит так:
# общие настройки для всех серверов
# все используемые сервера работают по протоколу pop3 с обычной парольной авторизацией
defaults: proto POP3, auth password,
# кому отдавать почту
mda "/usr/sbin/sendmail -i %T",
# принимать все сообщения с сервера, в т.ч. прочтенные
fetchall,
# через каждые 100 принятых писем соединяться заново, чтобы в случае разрыва связи не принимать их повторно
expunge 100
# настройки серверов
poll server1.ru
user 'user1' there with password 'pass1' is 'localuser' here
poll server2.ru
user 'user1' there with password 'pass2' is 'localuser' here,
user 'user2' there with password 'pass3' is 'localuser' here
Здесь пользователь с логином localuser имеет 3 ящика: [email protected], [email protected] и [email protected]. Запятые, двоеточия, отступы и слова there, here и with вставлены лишь для удобочитаемости и игнорируются.
Можно использовать fetchmail в режиме демона, для этого в начало файла /etc/fetchmailrc (который должен содержать все используемые сервера) добавим строки
set daemon 600
set syslog
Здесь 600 - интервал проверки (в секундах). 2-я строка указывает демону, что все сообщения надо отправлять в syslog. Ну и включаем демона командой chkconfig fetchmail on. Кстати, на основе вышеприведенного /etc/ppp/ip-up.d/sendmail можно сделать аналог для fetchmail:
#!/bin/sh
FETCHMAIL=/usr/bin/fetchmail
[ ! -x "$FETCHMAIL" ] || exec "$FETCHMAIL" > /dev/null 2>&1
Тогда при каждом подключении автоматически будет получена новая почта. Заметьте, почта сама принимается и отправляется при подключении, при том что пользователю не надо даже запускать почтового клиента. В этом одно из удобств создаваемой нами системы.
Настройка procmail
Здесь сложно дать готовый конфиг, т.к. большая его часть должна писаться индивидуально. Но всё же. Вот вводная часть:
# все указанные в дальнейшем папки располагаются в $MAILDIR
MAILDIR=$HOME/Mail
# сюда идет почта, не подходящая ни под один фильтр
DEFAULT=$MAILDIR/Mail
# сюда пишется тема каждого обработанного письма и папка, куда оно было помещено
LOGFILE=$MAILDIR/Log
А вот несколько типичных сортирующих правил:
:0:
* ^List-Id: .*community.alt
Lists/Community
:0:
* ^From: .*(@subscribe.ru)|([email protected])|([email protected])
Рассылки/Рассылки
:0:
* ^To: .*wrar@altlinux
ALT/inbox
Как видим, все такие правила начинаются строчкой :0:, затем идет 1 или больше строк, где после * идет регулярное выражение, с которым сравниваются все заголовки письма (вообще-то procmail умеет фильтровать по содержимому самого письма, и много другое, так что изучайте man procmailrc и man procmailex). При совпадении всех строк письмо отправляется в ящик, определяемый последней строкой. Если там стоит /dev/null - письмо удаляется.
Кроме фильтрации, можно выполнять и много других действий над письмами. Вот очень полезное правило, удаляющее повторяющиеся письма (например, если во время скачивания писем по pop3 оборвалась связь, и уже скачанные письма начали скачаиваться снова):
:0 Whc: msgid.lock
| formail -D 65536 msgid.cache
:0 a:
/dev/null
Здесь msgid последних писем кэшируются в файле msgid.cache, размером не больше 64K, и если msgid полученного письма содержится в этом файле - письмо удаляется.
Настройка mutt
Скажу еще пару слов про настройку mutt применительно к обсуждаемой почтовой системе. Я не буду рассматривать настройки mutt как программы чтения и написания писем, тем более что их очень много. Остановлюсь на относящихся к нашей теме:
set from= - необходимо указать свой обратный адрес
set envelope_from - необходимо для правильной отправки писем через интерфейс sendmail (будет вписан правильный адрес From:)
mailboxes - надо указать все локальные ящики (иными словами, почтовые папки - файлы в формате mailbox или папки в формате maildir), которые mutt будет проверять на наличие новых писем.
set spoolfile= - ящик, открываемый при запуске mutt.
И напоследок. В административных целях в файле /etc/aliases необходимо указать псевдоним root'а, т.е. имя пользователя, который будет получать письма, адресованные root'у:
# Person who should get root's mail.
root: someuser
Кстати, после установки и запуска postfix root'у иногда будут приходить письма от различных демонов и программ (как правило, с сообщениями об ошибках). Например при попытке выполнения sudo пользователем, не упомянутым в sudoers произойдет следующее:
[user2@localhost ~]$ sudo ls
Password:
user2 is not in the sudoers file. This incident will be reported.
И root'у (точнее, указанному в /etc/aliases пользователю) придет письмо:
From: [email protected]
Subject: *** SECURITY information for localhost.localdomain ***
localhost.localdomain : May 5 19:07:24 : user2 : user NOT in sudoers ; TTY=pts/1 ; PWD=/home/user2 ; +USER=root ; COMMAND=/bin/ls