ДЕНИС МЫСЕНКО
Эффективная почтовая система на базе Exim
Статья рассматривает создание почтовой системы с использованием Exim MTA версии 4, Exiscan, SpamAssassin, Dr.Web; системы, защищенной от спама и вирусов, рассчитанную на большое количество пользователей (сотни пользователей), а также имеющую удобную конфигурацию в одном файле. В нашем примере в качестве ОС выбрана FreeBSD 4, но не будет никакой разницы в установке для любой другой ОС семейства UNIX.
Почему Exim?
Exim MTA (message transfer agent) является широкофункциональной и высоко-защищенной почтовой системой. Несмотря на монолитность программного кода (все блоки находятся в одном процессе), за всю ее историю не было обнаружено ни одной серьезной уязвимости, допускающей несанкционированный доступ к серверу, на котором она работает. Программа распространяется по лицензии GNU, автор – доктор Philip Hazel, The University of Cambridge. Официальный сайт Exim – http://www.exim.org. Последней версией на текущий момент является 4.20, но мы рассмотрим пример на 4.12, как проверенный автором статьи.
Exim умеет брать пользователей из любого источника – MySQL, OpenLDAP, UNIX и т. д. Вся конфигурация находится в одном файле и разбита на практически автономные секции, что дает особые удобства и возможности при работе с ней.
Среди разделов конфигурации:
- Основной (main), где находятся общие настройки типа имени сервера, баннера, списка обслуживаемых доменов.
- Раздел безопасности (ACL), где находятся правила, на которые проверяется проходящяя через сервер почта. К примеру, реальность домена отправителя, существование пользователя на другом конце (callout).
- Раздел маршрутизации (routers), где находятся правила выбора маршрута почты, подсказывающие серверу, как найти приемщика корреспонденции. К примеру, доменный принцип (смотреть в DNS), алиасы (смотреть в файле алиасов), форварды (смотреть у пользователя в домашней папке в файле .forward), статическое правило (доставлять на указанный сервер).
- Раздел доставки (transport), где находится описание правил доставки. К примеру, доставка по SMTP, доставка в файл.
- Раздел переписывания (rewrite), где находятся правила изменения заголовков писем. К примеру, вы можете перенаправить всю почту одного домена на свой ящик, переписав поле RCPT.
Плюс разделы задания правил попыток пересылки (retry) и аутентификации. Благодаря существованию Exiscan, Exim нам поможет проверять проходящую через него почту на наличие вирусов, спама и других «почтовых дефектов» еще на этапе SMTP-сессии – это будет происходить по завершению команды DATA, в момент, когда удаленный почтовый сервер ждет реакции от Exim. При обнаружении «дефекта» Exim сразу же откажет в получении письма и, таким образом, ненужное письмо даже не успеет попасть в почтовую очередь (что спасает место на жестких дисках и нервы администратору).
Компоненты
Помимо самого Exim 4.12 в предложенной схеме будут использоваться:
- Exiscan – http://duncanthrax.net/exiscan – осуществление проверки во время SMTP-сессии (патч для Exim). Наш пример касается версии exiscan 4.12-26 (freeware).
- SpamAssassin – http://spamassassin.org – анализ почты по заданным правилам на отношение к спаму. За каждое правило назначено число баллов. При достижении указанного количества баллов письмо считается спамом. Пример правила – большие красные буквы в тексте письма. Наш пример касается версии SpamAssassin 2.50 (freeware).
- Dr.Web – http://www.drweb.ru – популярный российский антивирус от фирмы «Диалог-Наука». Является коммерческим, цены доступны на сайте.
Собираем Exim
Скачиваем Exim 4.12 и exiscan 4.12-26 с официальных сайтов, указанных в предыдущем разделе. Распаковываем exiscan в папку с распакованным Exim.
bash-2.05a$ wget ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/exim-4.12.tar.gz
bash-2.05a$ tar xzf exim-4.12.tar.gz
bash-2.05a$ cd exim-4.12
bash-2.05a$ wget http://duncanthrax.net/exiscan/exiscan-4.12-26.tar.gz
bash-2.05a$ tar xzf exiscan-4.12-26.tar.gz
Применяем патч:
bash-2.05a$ patch -l -p1 < exiscan-4.12-26.patch
Копируем дефолтный файл сборки:
bash-2.05a$ cp src/EDITME Local/Makefile
Редактируем Local/Makefile под свои нужды. Обращаем внимание на поля:
- EXIM_UID – UID, под которым будет крутиться Exim;
- EXIM_GID – GID, под которым будет крутиться Exim, обычно GID группы mail;
- SPOOL_DIRECTORY – папка с почтой, обычно /var/mail.
Пути:
- BIN_DIRECTORY=/usr/exim/bin – путь к программам Exim;
- CONFIGURE_FILE=/usr/exim/configure – путь к файлу конфигурации.
Маршрутизаторы почты:
- ROUTER_ACCEPT=yes – доставка почты в локальный ящик;
- ROUTER_DNSLOOKUP=yes – доставка почты, используя DNS (по записям MX);
- ROUTER_IPLITERAL=yes – доставка почты на IP-адреса (к примеру, postmaster@[10.1.1.1]);
- ROUTER_MANUALROUTE=yes – доставка почты на явно заданный сервер;
- ROUTER_QUERYPROGRAM=yes – доставка почты по информации от внешней программы;
- ROUTER_REDIRECT=yes – перенаправление почты (файлы .forward, база aliases).
Лучше на все поставить «yes», чтобы потом не пересобирать, если что-то понадобится.
Транспорты:
- TRANSPORT_APPENDFILE=yes – запись в файл;
- TRANSPORT_AUTOREPLY=yes – автоответчик;
- TRANSPORT_PIPE=yes – доставка через PIPE;
- TRANSPORT_SMTP=yes – доставка на SMTP-сервер.
Также на все поставить «yes», чтобы опять же не пересобирать в будущем.
Поиск пользователей:
- LOOKUP_DBM=yes – поиск в Berkeley DB;
- LOOKUP_LSEARCH=yes – линейный поиск в файле (типа /etc/aliases);
- LOOKUP_LDAP=yes – поиск в OpenLDAP;
- LOOKUP_MYSQL=yes – поиск в базе MySQL;
- LOOKUP_NIS=yes – поиск в директории NIS;
- LOOKUP_NISPLUS=yes – поиск в директории NIS+;
- LOOKUP_ORACLE=yes – поиск в базе Oracle;
- LOOKUP_PASSWD=yes – поиск в passwd файлах;
- LOOKUP_PGSQL=yes – поиск в базе PostgreSQL.
SMTP-аутентификаторы:
- AUTH_CRAM_MD5=yes – аутентификация по CRAM-MD5 (RFC 2195);
- AUTH_PLAINTEXT=yes – открытым текстом – LOGIN-механизм (RFC 2595);
- AUTH_SPA=yes – Microsoft Secure Password Authentication.
Выбираем нужные.
Теперь в корне дистрибутива Exim набираем:
bash-2.05a$ make
bash-2.05a$ make install
Все, Exim установлен в /usr/exim/bin. Теперь делаем:
bash-2.05a$ rm -f /usr/sbin/sendmail
bash-2.05a$ ln -s /usr/exim/bin/exim /usr/sbin/sendmail
bash-2.05a$ sendmail -bd
Проверяем работу нашего MTA:
bash-2.05a$ telnet 0 25
Connected to 0.
Escape character is "^]".
|
220 ourmail.duster.ru ESMTP Exim 4.12 Thu, 17 Jul 2003 16:09:30 +0700
Отлично, наш быстрый и удобный почтовый сервер установлен.
Собираем и конфигурируем SpamAssassin
Убийца спама (такой дословный перевод SpamAssassin) собирается очень просто:
bash-2.05a$ wget http://www.mirror.ac.uk/sites/spamassassin.taint.org/spamassassin.org/released/Mail-SpamAssassin-2.50.tar.gz
bash-2.05a$ tar xzf Mail-SpamAssassin-2.50.tar.gz
bash-2.05a$ cd Mail-SpamAssassin-2.50
bash-2.05a$ ./configure
bash-2.05a$ make
bash-2.05a$ su
su-2.05a# make install
Обращаем внимание на то, что ему потребуются некоторые Perl-модули, которые вы всегда можете найти в архиве CPAN (http://www.cpan.org).
Рекомендую сразу перейти в папку /etc/mail/assassin и внести некоторые изменения в файлы конфигурации.
Создадим файл local.cf, куда внесем следующие строки:
whitelist_from *@duster.ru
whitelist_from *@demos.su
Это домены, с которых любая почта не будет считаться спамом. Обязательно пропишите здесь ваших партнеров, дружественные домены и так далее – иначе в будущем возможны проблемы... Теперь создадим файл user_prefs.template, куда внесем следующие строки:
score BODY_8BITS 0
score SUBJ_FULL_OF_8BITS 0
score HEADER_8BITS 0
score HTML_COMMENT_8BITS 0
Нам незачем за 8-битные символы считать письмо спамом – ведь как ни странно, многие в России до сих пор составляют электронную корреспонденцию на русском.
В целях безопасности следует завести дополнительного пользователя, допустим spamd. По умолчанию процессом SpamAssassin используется порт 783, но так как мы будем пускать его не под супер-пользователем, следует взять порт выше 1023, к примеру 1783.
Запускаем SpamAssasin в фоновом режиме:
su-2.05a# /usr/bin/spamd -d -p 1783 -u spamd
Полный набор ключей вы можете узнать, запустив:
su-2.05a# /usr/bin/spamd -h
Собираем Dr.Web
Скачиваем и распаковываем Dr.Web с официального ftp-сайта:
bash-2.05a$ wget ftp://ftp.drweb.ru/pub/unix/4.29.5/drweb-4.29.5-freebsd4.tar.gz
bash-2.05a$ tar xzf drweb-4.29.5-freebsd4.tar.gz
bash-2.05a$ cd drweb-4.29.5-freebsd4
bash-2.05a$ su
su-2.05a# ./install.sh
Enter destination directory (/opt/drweb is default):
/usr/local/drweb
После чего Dr.Web будет установлен в папку /usr/local/drweb. В работе нам помимо сервера Dr.Web (drwebd) потребуется клиент из папки /usr/local/drweb/clients/drwebdc.
Конфигурация Dr.Web находится в файле drweb32.ini.
Обратим внимание на следующие поля:
- Key = «/usr/local/drweb/drwebd.key» – файл с лицензионным ключом.
- Interfaces = «localhost» – в большинстве случаев нет смысла держать Dr.Web на других интерфейсах, если мы не обслуживаем удаленные сервера.
- User = drweb – нет никакого смысла работать под супер-пользователем, лучше создать пользователя (к примеру «drweb») и дать только ему и группе администраторов права на чтение и запуск из папки /usr/local/drweb.
- LogScanned = Yes – записывать ли в лог результаты обработки – конечно, да.
- EnginePath = «/usr/local/drweb/drweb32.dll»
- VirusBase = «/usr/local/drweb/*.vdb»
- MoveFilesTo = «/usr/local/drweb/infected.!!!»
Пути к файлу с движком Dr.Web, вирусным базам и папке с инфицированными файлами соответственно. Ме-нять на свой вкус. Не забывайте лишь дать права созданному пользователю на запись в папку с инфицированными файлами.
su-2.05a# chown drweb.wheel /usr/local/drweb
su-2.05a# chmod 550 /usr/local/drweb
su-2.05a# chmod 750 /usr/local/drweb/infected.!!!
Сам сервер запускается очень просто:
bash-2.05a$ /usr/local/drweb/drwebd
Это следует прописать в файл запуска (/etc/rc.local для FreeBSD). Обновленные антивирусные базы следует класть в эту же папку, с дистрибутивом Dr.Web идет скрипт для автоматического обновления – update.pl. Его следует прописать в cron, для этого:
su-2.05a# crontab -u root -e
Вставляем следующую строку:
0 2 * * * /usr/local/drweb/update/update.pl /usr/local/drweb/
Запуск в 02:00 каждый день, параметр, переданный скрипту – это путь к антивирусным базам.
Конфигурируем Exim
Теперь подробно рассмотрим файл конфигурации /usr/exim/configure. Каждая секция, кроме главной, в файле конфигурации начинается со строки «begin <имя секции>».
Main section
- primary_hostname = ourmail.duster.ru – это официальное имя нашего сервера, которое будет ставиться в заголовки.
- domainlist local_domains = ourmail.duster.ru : localmail.ru – локальные домены, подразумевается, что они адресованы нашему почтовому серверу, то есть нашему серверу явно задано, куда класть эту почту (к примеру, локальным пользователям). Обратите внимание, что для разделения используется двоеточие, а не запятая.
- domainlist relay_to_domains = duster.ru : demos.su – список доменов, для которых мы будем осуществлять релейинг, то есть принимать почту и пересылать на MX с меньшим приоритетом.
- hostlist relay_from_hosts = 127.0.0.1 : 192.168.0.0/16 – список сетей, с которых мы будем принимать любую почту (список сетей клиентов). Как видите, поддерживается формат CIDR.
- smtp_banner = «ESMTP Welcome.» – наш баннер, который виден людям при открытии нашего SMTP-порта. Лучше использовать подобный лаконичный баннер, нежели стандартный – зачем незнакомцам знать версию нашего MTA?
- qualify_domain = ourmail.duster.ru – домен, который мы будем дописывать к адресу, если он не указан. К примеру, если кто-то отсылает письмо на адрес «postmaster» вместо «postmaster@ourmail.duster.ru». Обычно это домен обслуживаемой компании.
- acl_smtp_rcpt = acl_check_rcpt – набор правил ACL, которые находятся в соответствующей секции конфигурационного файла.
- host_lookup = !192.168.0.0/16 – делать запрос в DNS на всех клиентов, кроме указанных.
- helo_allow_chars = _ – разрешить символ подчеркивания в команде HELO. Рекомендую, так как некоторые администраторы используют знак подчеркивания в именах своих почтовых серверов, и если не добавить эту опцию – ваш сервер не будет принимать их корреспонденцию.
- exiscan_condition = 1 – включаем работу Exiscan. Здесь и далее, 1 – значит включено, 0 – значит выключено (как в математической логике).
- exiscan_timeout = 5m – тайм-аут для работы Exiscan.
- exiscan_loglevel = 2 – уровень ведения логов. От 0 до 2; 0 – значит не вести лог вообще.
- exiscan_demime_condition = 0 – проверка на валидность MIME (к примеру, отсутствие двойных заголовков). Автор отключает, так как некоторые почтовые клиенты (типа Outlook Express) иногда создают письма с вложениями, которые не пройдут эту проверку.
- exiscan_demime_action = reject – что делать с непрошедшими? Можно отказать в приеме письма (reject), пропустить (pass) его, занести отправителя в черный список (blackhole) и заморозить письмо (freeze).
- exiscan_demime_pickyness = 2 – значение от 0 до 2 указывает, насколько сильно придираться к письму.
- exiscan_extension_condition = 1 – включаем проверку на расширение вложений.
- exiscan_extension_data = pif:vbs:scr:bat – список запрещенных расширений.
- exiscan_extension_action = reject – что делать? Варианты такие же, как в проверке MIME.
- exiscan_av_condition = 1 – включаем антивирусный контроль.
- exiscan_av_scanner = cmdline – Dr.Web не входит в список стандартных антивирусов exiscan, поэтому пишем, что наш будет просто запущен из командной строки. Список поддерживаемых антивирусов:
- exiscan_av_scanner_path = /usr/local/drweb/clients/drwebdc/drwebdc – путь к нашему нестандартному антивирусу.
- exiscan_av_scanner_options = -n127.0.0.1 -rv -q -f| – ключи для запуска Dr.Web-клиента. 127.0.0.1 – адрес сервера, на котором крутится сервер Dr.Web (drwebd), он может быть нелокальным.
- exiscan_av_scanner_regexp_trigger = infected with – строка в выводе клиента Dr.Web, означающая, что вирус найден.
- exiscan_av_action = reject – что делать с зараженными письмами? Варианты как в предыдущих проверках.
- exiscan_regex_condition = 1 – включаем поиск заданных строк в письмах.
- exiscan_regex_data = TEENPORN : Language Center – указываем запрещенные слова.
- exiscan_regex_action = reject – что делать? Конечно, запрещать!
- exiscan_spamd_condition = 1 – включаем анализ на принадлежность почты к спаму.
- exiscan_spamd_threshold = 7.6 – число от 0 до 999. Минимальный балл, при достижении которого письмо считается спамом. Чем меньше число, тем больше спама будет через вас проходить. Если балл достигнут – в заголовок письма вставится поле X-Spam-Score, указывающее сколько баллов было набрано. Все методы анализа писем дают дроби типа 0.5, 1.2, 2.6, поэтому имеет смысл указывать балл также в виде дроби.
- exiscan_spamd_header_style = full – количество информации, добавляемой в заголовок.
- none – в заголовок ничего не прописывается.
- single – добавится только поле X-Spam-Score.
- flag – если письмо считается спамом, то также добавляется флаг X-Spam-Flag.
- full – если письмо считается спамом, то также добавляется поле X-Spam-Report с подробным отчетом (по каким критериям письмо засчитано спамом).
- exiscan_spamd_action = reject – что делать? Конечно, запрещать!
- exiscan_spamd_subject_tag = *SPAM* – если вы все-таки пропускаете письма, то можно добавить в тему письма указанный тэг, к примеру *SPAM*.
- exiscan_spamd_address = 127.0.0.1 783 – адрес и порт, на котором крутится SpamAssassin, опять же может быть нелокальным.
ACL section
Оставляем как есть, если у кого-то есть желание – можно добавить функцию callout. Для этого в строках verify = sender и verify = recipient добавляем /callout, то есть получаем строку типа verify = recipient/callout.
Таким образом, наш сервер во время проверки адресов отправителя и получателя будет создавать SMTP-сессию с сервером, отвечающим за соответствующий домен отправителя или получателя, и проверять – существует ли там указанный пользователь.
В таком случае письма с несуществующих адресов не будут проходить, но это скажется на времени работы почтового сервера.
Routers section
Оставляем как есть, лишь добавляя по надобности дополнительные маршрутизаторы почты сверху секции.
Пример:
friends:
driver = manualroute
transport = remote_smtp
route_list = friends.ru mx.friends.ru
Это явное задание маршрутизации почты friends.ru на сервер mx.friends.ru, стоит на нем MX или нет – роли не играет.
Transports section
Оставляем как есть.
Retry section
Оставляем как есть.
Rewrite section
Перезапись адресов в заголовках осуществляется по примеру:
*@friends.ru postmaster@ourmail.duster.ru E
Сначала пишем, что менять, затем – на что. Флажок E означает, что изменится только адрес в рабочем заголовке, поля To: и From: останутся неизмененными.
Authenticators section
Здесь задаются правила аутентификации, чтобы наш SMTP-сервер могли использовать только по паролю. Необходимость обычно существует только для систем бесплатной почты и компаний, которые хотят, чтобы их сотрудники могли использовать корпоративный SMTP-сервер из любой точки планеты.
Пример для фиксированного (единственного для всех) пароля:
fixed_login_oe:
driver = plaintext
public_name = LOGIN
server_prompts = "Username:: : Password::"
server_condition = ${if and {{eq{$1}{user}}{eq{$2}{password}}}{yes}{no}}
server_set_id = $1
Данный пример (LOGIN-механизм) работает для клиентов Outlook Express. Для Netscape Messanger следует использовать следующую конфигурацию:
fixed_login_ns:
driver = plaintest
public_name = PLAIN
server_condition = ${if and {{eq{$1}{user}}{eq{$2}{password}}}{yes}{no}}
server_set_id = $1
Происходит примитивное сравнение указанных почтовым клиентом имени и пароля с нашими «user» и «password» (см. server_condition).
По умолчанию все клиенты должны пройти аутентификацию, если мы прописали хоть один метод в этом разделе. Но лучше бы убрать ее для локальных пользователей, для этого добавим в основной раздел (в Main section) следующую строку:
auth_advertise_hosts = !192.168.0.0/16
Финиш
Все, мы у финиша – получили быстрое и техничное почтовое решение с анализом на наличие вирусов, спама и прочих «дефектов» в нашей корреспонденции!
Автором статьи протестирована связка Exim с базами MySQL и OpenLDAP – работает превосходно. Скорость доставки – на грани фантастики!
Лог-файлы хранятся по умолчанию в папке /var/mail/log.
- mainlog – основной лог проходящих писем;
- rejectlog – лог отклоняемых писем;
- paniclog – серьезные ошибки в работе MTA.
Статистику можно смотреть утилиткой eximstats:
bash-2.05a$ /usr/exim/bin/eximstats -nr /var/mail/log/mainlog
Удачи всем постмастерам!