...
...
...

почтовый сервер на основе sendmail и dbmail

вступление

Достался мне в наследство почтовик, проработавший 3 года практически без изменений.

И крутился на нем sendmail, каждый почтовый ящик – отдельный пользователь (а ящиков примерно 2000 :).

Произошло ЧП - сломался сервер, но жесткий диск остался цел и невредим.

В связи с этим было закуплено новое железо. Можно, конечно, банально воткнуть старый винт, и пусть все крутится дальше, как и было до поломки, но это решение показалось неправильным по нескольким причинам.

1. Винту четыре года, может и посыпаться ненароком.

2. В случае выхода из строя винта как быть с пользовательской почтой, с логинами-паролями?

3. Давно была мысль обновить ПО на сервере.

В результате усиленных поисков в интернете наткнулся на руководство по настройке связки Exim+dbmail+SpamAssasin+Антивирус). Именно это руководство и послужило отправной точной для дальнейших действий и поисков.

почему sendmail?

Из почтовых серверов - Qmail, Sendmail, Postfix и Exim - мне больше всего понравился Qmail - прост в настройке, по всем отзывам и по собственным впечатлениям - быстр, надежен, наименьшее количество обнаруженых уязвимостей (если не сказать - полное их отсутствие); но и давно не обновлялся, большинство функционала реализуется сторонними утилитами, то есть требует довольно существенного "обвеса" для достижения необходимого уровня функциональности.

Postfix - сам его не "щупал", но порасспрашивал знакомых (и не очень) людей. Оказалось, что Postfix практически никто не применяет на почтовых серверах, обслуживающих хотя бы 1000 ящиков и 10-15 доменов (просьба не возмущаться поклонников Postfix, верю, что это хороший МТА, но это – не мой выбор).

Exim - мне тут сложно что-либо сказать, имею только косвенные данные - по моим опросам примерно 3 из 10 используют Exim, причины – проще настроить, чем sendmail; меньшее количество уязвимостей, чем в sendmail.

Sendmail - несмотря на регулярные проблемы с безопасностью и сложностью настройки, почему все-таки Sendmail?

- Сложность конфига компенсируется относительной простотой xxxxx.mc файла, из которого с помощью m4 получаем конфиг, по-моему xxxxx.mc выглядит не сложнее, чем конфиг Exim’а.

- Как сказал один знакомый, "Sendmail может ВСЕ, на что только способна почта".

почему dbmail?

Очень заманчива идея хранить в базе данных не только логин-пароль, но и сами письма. Сразу есть поддержка обьема почтового ящика. Можно держать базу на отдельном сервере. Не проблема быстро восстановить работу сервера при сбое из дампа базы. Поиском иных вариантов не занимался, хотя, возможно, существуют альтернативы dbmail (даже наверняка существуют), но меня вполне устраивает именно dbmail.

DBMail - установка и настройка

С установкой все просто – устанавливаем привычным вам образом. Я предпочитаю собирать из исходников. Скачиваем нужный релиз с официального сайта www.dbmail.org, распаковываем, переходим в каталог с распакованными исходниками.

Можно (и желательно) внимательно прочитать файл INSTALL. Далее говорим, что наша база - PostgreSQL (ну или MySQL - кому как надо).

./configure --with-pgsql (или --with-mysql)

И далее хорошо знакомые нам всем make, make check, make install.
Желательно для dbmail специально создать пользователя, хотя и необязательно (я создал и обозвал dbmail)

Далее необходимо создать собственно базу данных. Для этого читаем файлик INSTALL.dbmail, в котором и описана эта процедура. Конкретно для PostgreSQL необходимо проделать следующее: создаем пользователя с именем dbmail (имя можно задать любое):

createuser -U postgres dbmail

Теперь надо присвоить пользователю пароль:

psql postgres postgres

Собственно присваиваем пароль:

ALTER USER dbmail WITH PASSWORD '<password>';
\q


Теперь создаем базу:

createdb -U dbmail dbmail

И создаем таблицы в базе:

psql -U dbmail dbmail < sql/postgresql/create_tables.pgsql

Теперь копируем конфигурационный файл в /etc

cp dbmail.conf /etc/

Затем правим конфиг. Параметры говорят сами за себя, и у человека, хоть немного знакомого с английским, вопросов вызывать недолжны. Какие возникли проблемы лично у меня. По умолчанию в конфиге указано довольно большое количество подключений к базе данных: при запуске dbmail- pop3d база перестала принимать подключения. Для начала стоит выбрать числа поменьше - MAXCHILDREN и MAXCONNECTS сразу уменьшил в 10 раз. Теперь база данных готова для использования.

Добавление пользователей можно организовать с помощью консольной утилиты dbmail-users.

dbmail-users -a username -w secret -g 0 -m 25M –s username@domain.org username1@domain.net

Где:

-a username - имя пользователя;

-s username@domain.org - алиас (можно несколько через пробел), почта для этих адресов будет складываться в ящик username;

-m 25M - обьем ящика (поумолчанию - в байтах, K - килобайты, M - мегабайты);

-w secret – пароль.

Прочие опции желающие могут изучить, прочтя вывод команды

dbmail-users --help

Еще документация рекомендует добавить в cron следующую строку:

0 3 * * * /usr/local/sbin/dbmail-util -cturpd -l 24h -qq

Это нужно для обслуживания базы данных.

DBmail предоставляет в наше распоряжение 2 транспорта для передачи писем в базу данных - dbmail-lmtp и dbmail-smtp.

Если MTA поддерживает lmtp, то рекомендуется использовать именно его.

Запуск:

dbmail-lmtpd

и

dbmail-pop3d

или

dbmail-imapd

(кому что больше нравится).

Осталось состыковать наш MTA с dbmail.

На официальном сайте DBmail имеется wiki с описанием стыковки dbmail с Qmail, Exim, Postfix и Sendmail.

подключение к Sendmail

Для того, чтобы sendmail понял, чего мы от него хотим, надо сначала создать 2 m4-макроса: /usr/share/sendmail/cf/mailer/dbmail.m4 и /usr/share/sendmail/cf/mailer/dbmail-lmtp.m4.

Вот что мы пишем в dbmail.m4:

PUSHDIVERT(-1)
ifdef(`DBMAIL_MAILER_PATH',,
`ifdef(`DBMAIL_PATH',
`define(`DBMAIL_MAILER_PATH', DBMAIL_PATH)',
`define(`DBMAIL_MAILER_PATH', /usr/sbin/dbmail-smtp)')')
_DEFIFNOT(`DBMAIL_MAILER_FLAGS', `SPhnu9')
ifdef(`DBMAIL_MAILER_ARGS',,
`define(`DBMAIL_MAILER_ARGS', `dbmail -d $u')')
POPDIVERT

Mdbmail, P=DBMAIL_MAILER_PATH, F=_MODMF_(CONCAT(`DFM', DBMAIL_MAILER_FLAGS), `DBMAIL'),
S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP/HdrFromSMTP,
ifdef(`DBMAIL_MAILER_MAX', `M=DBMAIL_MAILER_MAX, ')T=DNS/RFC822/X-Unix,
A=DBMAIL_MAILER_ARGS


А вот и второй макрос - dbmail-lmtp.m4:

PUSHDIVERT(-1)
ifdef(`DBMAIL_MAILER_PATH',,
`ifdef(`DBMAIL_PATH',
`define(`DBMAIL_MAILER_PATH', DBMAIL_PATH)',
`define(`DBMAIL_MAILER_PATH', [IPC])')')
_DEFIFNOT(`DBMAIL_MAILER_FLAGS', `AhmXz5@/:|')
ifdef(`DBMAIL_MAILER_ARGS',,
`define(`DBMAIL_MAILER_ARGS', `TCP $h 24')')

POPDIVERT
Mdbmail-lmtp, P=DBMAIL_MAILER_PATH, F=_MODMF_(CONCAT(`DFM', DBMAIL_MAILER_FLAGS), `DBMAIL'),
S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP/HdrFromSMTP,
ifdef(`DBMAIL_MAILER_MAX', `M=DBMAIL_MAILER_MAX, ')T=DNS/RFC822/X-Unix,
A=DBMAIL_MAILER_ARGS


На этом этапе возникла только одна проблемка: по умолчанию у меня dbmail-smtp стал в /usr/local/sbin, а макрос ищет его в /usr/sbin/. Ситуацию можно поправить, создав ссылку:

ln -s /usr/local/sbin/dbmail-smtp /usr/sbin/dbmail-smtp

или поправив исходник макроса.

Теперь в sendmail.mc (или его эквивалент) добавляем строчки:

FEATURE(`mailertable')dnl
MAILER(dbmail)dnl
MAILER(dbmail-lmtp)dnl


В /etc/mail/mailertable (именно его задает "FEATURE(`mailertable')" ) указываем домены, почта для которых будет передаваться в dbmail:

domain.org dbmail-lmtp:[127.0.0.1]
domain.net dbmail-lmtp:[127.0.0.1]


Не забыть убрать эти домены из /etc/mail/local-host-names (или его эквивалента), иначе письма для этих доменов в dbmail не попадут, а вместо этого будут доставлены локальным пользователям.

Теперь осталось пересобрать конфиг sendmail’а и перезапустить его.

Теоретически это все! Почта должна складываться в базу даных и отдаваться по протоколу POP3 или IMAP (в зависимости от того, какой демон - dbmail-pop3d или dbmail-imapd – запущен).

ВАЖНО! При рестарте очень желательно, чтобы dbmail-lmtpd запускался раньше sendmail’а.

боремся со спамом

Теперь осталось настрить sendmail для отбивания спама.

Начнем с проверки адреса отправителя. Воспользуемся фильтрами, работающими посредствам Milter API в sendmail.

Так как milter-sender теперь платный, воспользуемся фильтром smf-sav (http://smfs.sourceforge.net/smf-sav.html), выполняющим те же функции. Качаете, распаковываете, правите Makefile (сценария ./configure там не предусмотрено), затем собираете и устанавливаете.

Правим конфиг /etc/mail/smfs/smf-sav.conf и запускаем:

/usr/local/sbin/smf-sav

Теперь в sendmail.mc добавляем строчки для smf-sav:

dnl Проверка Адреса отправителя
define(`confMILTER_MACROS_HELO', confMILTER_MACROS_HELO`, {verify}')dnl
INPUT_MAIL_FILTER(`smf-sav', `S=unix:/var/run/smfs/smf-sav.sock, T=S:30s;R:4m')dnl


Далее в папке /etc/mail

make all install && ../rc.d/sendmail restart

Если все впорядке, то в логе /var/log/maillog можно увидеть строчки вида:

smf-sav[528]: sender check succeeded: <72stocknews@totallytitanium.com.>, 84.168.240.99, p54A8F063.dip.t-dialin.net, [00:00:03]

указывающие на то, что адрес существует.

Если адреса не существует, вы увидите что-то типа этого:

smf-sav[528]: recipient check failed: <duncan@kr.dataxp.net.>, 84.168.240.99, p54A8F063.dip.t-dialin.net, <72stocknews@totallytitanium.com.>, [00:00:01]

ВАЖНО! При рестарте необходимо, чтобы smf-sav запускался раньше sendmail’а, иначе проверка не будет выполняться.

Можно прикрутить еще проверку на зомбированые хосты. Реализовать это можно, например, при помощи smf-zombie. В механизмах его работы я не разбирался, могу только сказать, что его использование дает определенный эффект.

Качаете там же, где и smf-sav, распаковываете, правите Makefile (сценария ./configure опять не предусмотрено), затем собираете и ставите. Никаких конфигов для него не нужно.
Запускаем:

/usr/local/sbin/smf-zombie

Теперь в sendmail.mc добавляем строчки для smf-zombie:

dnl Убивание спама от зомбированых хостов
dnl Этот фильтр должен быть ПЕРВЫМ среди остальных фильтров
define(`confMILTER_MACROS_HELO', confMILTER_MACROS_HELO`, {verify}')dnl
define(`confMILTER_MACROS_ENVFROM', confMILTER_MACROS_ENVFROM`, {msg_size}')dnl
INPUT_MAIL_FILTER(`smf-zombie', `S=unix:/var/smfs/smf-zombie.sock, T=S:30s;R:1m')dnl

define(`confPRIVACY_FLAGS', `goaway,noetrn,nobodyreturn,noreceipts')dnl
define(`confTO_COMMAND', `1m')dnl
define(`confTO_IDENT', `0s')dnl
define(`confTO_RESOLVER_RETRANS', `7s')dnl
define(`confTO_RESOLVER_RETRY', `4')dnl
define(`confMAX_DAEMON_CHILDREN',`256')dnl
define(`confCONNECTION_RATE_THROTTLE',`8')dnl
define(`confBAD_RCPT_THROTTLE', `1')dnl Sendmail v8.12+


Далее в папке /etc/mail:

make all install && ../rc.d/sendmail restart

ВАЖНО! Этот фильтр должен быть ПЕРВЫМ среди остальных фильтров в конфиге sendmail’а. Также необходимо, чтобы smf-zombie запускался раньше sendmail’а.

послесловие

Все вышеописанное было проделано на FreeBSD 6.1 и успешно заработало практически с первой попытки.

Многие очевидные вещи в повествовании опущены, поскольку вряд-ли настройка ответственного сервера будет доверена человеку, не умеющему создать нового пользователя в системе или выполнить первоначальную настройку sendmail.




© Сетевые решения