На главную

Классический MTA средствами qmail.


Copyright © 2004-2008 М. Альхименко.
Оригинал (и самая последняя версия) этого документа находится на http://lithium.opennet.ru.
По всем вопросам обращайтесь на articles <at> lithium.opennet.ru


  • 22 января 2008 - правки в связи со сменой лицензии на public domain и обновлением версии netqmail.
  • 12 декабря 2006 - вместо оригинального qmail используется netqmail, сокращено количество патчей, мелкие исправления.
  • 27 января 2004 - первая версия.



Содержание:

Введение

      Здесь не ставилось целью дать полный перевод официальных руководств автора qmail — D. J. Bernstein'а (DJB) или написать "Книгу юных сурков" на все случаи жизни. Хотелось дать общее представление, как все устроено, а с частностями (например, с форматом запуска multilog) можно разобраться и самому. Imho основная цель этой статьи — помочь разобраться с классической доставкой почты в unix-системах (средствами qmail). Хотя, если строго следовать определению "классический", то изучать надо было бы sendmail, но imho не стоит привыкать к плохому с самого начала ;) .

      Все команды и пути даются из расчета на работу с RH-based Linux (RH9, ASP9) и FreeBSD 4.9, (ОС, опыт работы с которыми имелся на момент написания статьи). Если у вас другая система, и пути/команды не подходят, пишите — соответствующие поправки будут по возможности включены.

      На большинстве работающих серверов почта является едва ли не единственным средством обратной связи системы с администратором. По почте направляют отчеты о работе cron, системы вроде LIDS, различные средства мониторинга (smartd, logwatch) и пр. Многие распространенные дистрибутивы Linux (например RH9 и ASP9) ставят в качестве MTA или нечто дырявое (sendmail) или что-то, что тянет за собой несколько ненужных программ (postfix-xxx.i386.rpm требует MySQL + cyrus-sasl + ...), в данном случае совершенно ненужных. Поэтому было решено попробовать поставить MTA из исходников, и в был выбран qmail в его первоначальном варианте — без того множества дополнительных программ (и патчей вроде qmail-ldap), которые превращают его в нечто очень серьезное для обслуживания десятков доменов с тысячами пользователей. Только в роли классического unix'ового MTA.

      Для тех, кто не знаком с основами доставки почты в Unix вряд ли можно порекомендовать какой-то один источник, т.к. знания об этом вопросе приходилось собирать по частям из кучи руководств и подсказок знакомых. Самое приличное, что попадалось — "Руководство администратора Linux" Немет Э., Снайдер Г., Хейн Т. "Вильямс", 2003. Поэтому тут будет кратко изложено то, что удалось понять. Может это поможет Вам разобраться, как все работает.

      Мы отправляем письмо по адресу user@host.domain.ru, то есть письмо предназначено пользователю "user", для которого есть учетная запись на хосте host.domain.ru. На первом этапе доставки программа, отправляющая почту (или мы сами из оболочки пользователя), вызывает MUA — Mail User Agent, клиента электронной почты и передает ему адрес получателя и текст сообщения. (Обычно в качестве MUA в скриптах используется программа mail, в RH и ASP она входит в пакет mailx). Mail формирует сообщение и передает его MTA (Mail Transport Agent), который отвечает за доставку сообщений между системами или внутри системы между пользователями. Обычно все MUA при вызове MTA ищут бинарник sendmail (как интерфейс MUA —> MTA), а все MTA стараются его эмулировать, хотя некоторые MTA подменяют и саму программу mail, как это делает CGP. (Многие современные клиенты электронной почты частично реализуют функциональность MTA — передают сообщения по SMTP-протоколу настоящему MTA для дальнейшей пересылки). Далее MTA, если сообщение для локального пользователя, кладет его в соответствующие хранилище сообщений пользователя в системе (maildir или mailbox). Если сообщение отправлено для пользователя в другую систему, то MTA ищет в DNS MX-запись (Mail Exchanger), указывающую, какая машина принимает сообщения для пользователей нужного хоста или домена. Для каждого домена должна, а для хоста может сущеcтвовать в DNS соответствующая MX-запись, которая указывает на хост, принимающий почту для данной системы. Если для хоста нет записи MX, то MTA пытается передать сообщение напрямую на этот хост, основываясь только на записи типа A. Обычно для хоста запись MX используется в том случае, если он сам не принимает свою почту (в системе нет MTA или он не слушает 25 порт или он скрыт за firewall), а за него это делает другая система. Это очень упрощенная схема, но дает представления об основах работы MTA.

      Таким образом, в идеале на каждом хосте должен быть запущен MTA, который принимает почту для пользователей своей системы (в современном Internet слушая 25 порт TCP), осуществляет локальную доставку почты между пользователями и занимается доставкой сообщений пользователям других систем (отправленную изнутри системы), направляя почту MTA в этой системе, то есть занимается транспортом почты. MUA служит для просмотра пользователем своей почты в системе и передаче MTA сообщений для доставки. Просматривать сообщения в системе MUA может или напрямую, просматривая хранилище сообщений, или через демоны POP3 или IMAP, которые служат средством удаленного просмотра хранилища сообщений пользователем.

      Итак, в качестве MUA у нас есть mail, а как MTA мы будем использовать qmail. Он легкий, быстрый и безопасный. Ставить qmail можно и по указанным ниже руководствам, но здесь будет описан процесс установки MTA в его самом простом варианте (хотя, почитать эти руководства безусловно стоит) и в том виде, каким его планировал DJB (imho, конечно).

      Запускать qmail можно из обычных стартовых скриптов, но imho лучше использовать для этого пакет daemontools, так же написанный DJB. Он является аналогом Service Manager'а в Win2k — предназначен для управлением сервисами. В числе прочих достоинств, описанных самим DJB на странице программы он имеет бесспорное преимущество — перезапускает демон в случае его падения. Если Вам не хочется ставить этот пакет, можете позаимствовать один из скриптов в указанных ниже руководствах для запуска qmail и запускать его или из rc.local (если у вас BSD-style система запуска) или с использованием runlevels, как в RH (система SysV) или еще как-нибудь. Краткое описание daemontools дается в отдельной статье.

Установка

В качестве базового дистрибутива можно использовать оригинальный qmail, как это было описано в первой версии настоящей статьи, однако на данный момент лучше использовать дистрибутив netqmail, который является практически официальным развитием qmail в плане устранения проблем с современными компиляторами и ОС, т.к. оригинальный qmail не изменялся с 1998 года. До недавего времени qmail разрешено было распространять только в виде оригинальных исходных текстов, без модификаций (в настоящее время qmail является public domain), в качестве наследия этого — довольно большое кличество сторонних патчей, которые позволяют добавить в него тот или иной функционал. В данной статье будут упомянуты наиболее необходимые из них, на взгляд автора.
Идем на http://www.qmail.org/netqmail/, выбираем ближайшее зеркало, скачиваем и распаковываем исходники:

# cd /usr/src
# wget http://www.qmail.org/netqmail-1.06.tar.gz
# gunzip netqmail-1.06.tar.gz
# tar -xvf netqmail-1.06.tar

До изменения лицензии в процессе сборки netqmail необходимо было накладывать патч на оригинальные исходные тексты qmail, в данный момент в этом уже нет необходимости.
Т.о. сейчас у нас есть подкаталог netqmail-1.06, в котором содержится готовый netqmail. В таком состоянии его можно без проблем собирать, устанавливать и использовать, однако, при желании дополнительно можно наложить несколько полезных патчей. Создаем каталог для патчей, скачиваем их и накладываем на исходники:

# cd netqmail-1.06
# mkdir patch
# cd patch
# wget http://qmail.jms1.net/patches/qmail-date-localtime.patch (установка в заголовках локального времени, а не GMT)
# wget http://www.flounder.net/qmail/qmail-dns-patch (патч для обрабтки записей в DNS, не соотвествующих RFC, которые имеют завышенные размеры (больше 512 байт). Накладывать не обязательно, особенно если вы используете dnscache из состава djbdns - он всегда отдает корректные ответы)
# wget http://www.fehcom.de/qmail/qmail-smtpd.c.size.diff (патч для поддержки команды SIZE из RFC1870 для qmail-smtpd)
# wget http://www.qmail.org/accept-5xx.patch (патч для лучшей совместимости с RFC2821; некоторые сервера отвечают на приветствие 5xx-кодом, простое соответствие RFC821 для них не подходит.)
# wget http://www.thedjbway.org/qmail/patches/qmail-1.03.link-sync.patch патч для устранения проблем с синхронизацией файлов после вызова link() на файловых системах в Linux.
# cd ..
# patch -p1 < patch/qmail-date-localtime.patch
# patch -p1 < patch/qmail-dns-patch
# patch -p2 < patch/qmail-smtpd.c.size.diff
# patch -p0 < patch/accept-5xx.patch
# patch -p0 < patch/qmail-1.03.link-sync.patch

В netqmail содержимое файла INSTALL в каталоге исходников заменено на ссылку http://lifewithqmail.org/lwq.html (перевод на русский язык), поэтому или читаем содержимое файла из оригинального qmail, или текст по ссылке или верим на слово этой статье ;)
Создаем каталог для qmail:

# mkdir /var/qmail

Создаем пользователей для qmail:

# cp INSTALL.ids IDS

# vi IDS

Убираем из скрипта ненужные строки, оставляем только для своей системы, убираем с них комментарии и запускаем скрипт:

# . IDS (не забудьте про пробел!)

Проверяем, добавились ли новые пользователи и группы:

# cat /etc/passwd
# cat /etc/group

Переходим в /var/qmail и удаляем оттуда все dot-файлы, добавленные туда из /etc/skel для нового пользователя. То же делаем и для /var/qmail/alias. В итоге каталог /var/qmail/ должен содержать только каталог alias - больше ничего.

Собираем и устанавливаем qmail:

# cd /usr/src/netqmail-1.06
# make setup check

Если все прошло без ошибок, значит qmail собран и установлен в /var/qmail.
Свои man-страницы qmail устанавливает в /var/qmail/man, сделаем их доступными для команды man. Для этого нужно включить путь к man-страницам qmail в общесистемные пути к man'ам. Добавляем строку:

MANPATH /var/qmail/man

в файл /etc/man.config вручную или так:

# echo "MANPATH /var/qmail/man" >> /etc/man.config

К сожалению, мне так и не удалось во FreeBSD добавить пути к man-файлам qmail в общестистемные. Если кто знает как это сделать -- буду признателен за помощь.

Настройка

Теперь нужно сделать первичную конфигурацию qmail. Все основные настройки хранятся в файлах в каталоге /var/qmail/control. В первую очередь это файлы:
  • me — полное доменное имя хоста
  • defaultdomain — имя домена по умолчанию, если в адресе указанно только имя хоста
  • locals — список доменов для локальной доставки почты (что не надо отсылать наружу)
  • plusdomain — это я так и не понял ;)
  • rcpthosts — на какие хосты/домены принимать почту (в т.ч. и для пересылки)

Эти файлы автоматически создаются скриптом config, находящимся в каталоге исходников qmail. При запуске он пытается найти в DNS имя хоста, прописанное в /etc/sysconfig/network и, соответственно, в /proc/sys/kernel/hostname и переменной окружения HOSTNAME. Если ему это удается, он выполняет обратное преобразование и ищет FQDN для полученного ip-адреса. Это имя он кладет в me, имя домена в defaultdomain. Потом пытается найти PTR записи для всех локальных ip-адресов. Все найденные имена он также кладет в locals. Затем говорит нам, что если у нас еще есть доменные имена, ссылающиеся на наш хост, надо поместить их в locals. После этого копирует locals в rcpthosts (список хостов/доменов, для которых qmail будет принимать почту) и сообщает:

Now qmail will refuse to accept SMTP messages except to those hosts.
Make sure to change rcpthosts if you add hosts to locals or virtualdomains!


Теперь qmail будет отвергать любые сообщения по SMTP кроме предназначенных для этого хоста.
Убедитесь, что вы изменили rcpthosts, если вы добавили хост в locals или virtualdomains!


Если ip-адрес, соответствующий вашему hostname невозможно найти в DNS, то скрипт выдает ошибку:

Your hostname is gw.
hard error
Sorry, I couldn't find your host's canonical name in DNS.
You will have to set up control/me yourself.


Имя вашего хоста - gw
серьезная ошибка
Извините, не могу найти имя вашего хоста в DNS.
Вам придется самому настроить control/me.


и предлагает заполнить нужные файлы вручную. В таком случае выполняем:

# ./config-fast полное_имя_вашего_хоста

Этот скрипт не выполняет запросов в DNS, а просто заполняет файлы в control на основании переданного имени. Рекомендется посмотреть сами скрипты — там все достаточно ясно. Также, об этом написано в INSTALL.ctl.
Узнать о назначении всех файлов в /var/qmail/control можно на http://www.ru.qmail.org/docs/original/inform.html или в man qmail-control (в таблице нужно посмотреть имя приложения и потом посмотреть его man). Вообще, чтение man-страниц qmail крайне познавательно для понимания того, как что работает и это настраивать.

Теперь нужно создать псевдонимы для postmaster, MAILER-DAEMON и root (qmail не доставляет почту для root — для пущей безопасности), т.е. выбрать пользователя которому будут пересылаться сообщения, пришедшие на эти адреса. Пусть это будет пользователь max. (Помните, что это должен быть реальный пользователь системы!) Псевдонимы определяются файлами формата .qmail-user, лежащих в /var/qmail/alias. В каждом файле лежит имя пользователя, которому пересылается почта, пришедшая для user.

# cd ~alias
# touch .qmail-postmaster .qmail-mailer-daemon .qmail-root
# chmod 644 ~alias/.qmail*
# echo max > .qmail-postmaster
# echo max > .qmail-mailer-daemon
# echo max > .qmail-root

Теперь нам нужно создать замену бинарнику sendmail, чтобы MUA могли отдавать почту qmail:
Проверяем, нет ли у нас sendmail (если у вас не стоит пакет slocate воспользуйтесь find):

# locate sendmail

Если у вас что-то завалялось из состава других MTA, тщательно удалите их следы (бинарники, строки запуска в стартовых скриптах и inetd.conf и пр.), если, конечно, вы их не используете для каких-то целей. В таком случае, думайте сами, что делать.
Создаем симлинк на бинарник sendmail из состава qmail (/var/qmail/bin/sendmail):

# ln -s /var/qmail/bin/sendmail /usr/sbin/sendmail

Если у вы устанавливаете qmail на FreeBSD, то этого делать не надо — смотрите далее соответствующий раздел. На этом установка закончена.

Maildir

      Теперь нужно создать хранилища для пользовательских сообщений. Исторически, сообщения пользователей хранятся в формате Mailbox — один большой файл со всеми сообщениями пользователя в каталоге /var/spool/mail — по одному для каждого пользователя. DJB предложил новый формат: Maildir — каждое сообщение хранится в отдельном файле в специальной папке, которая обычно находится в домашнем каталоге пользователя. Это увеличивает сохранность сообщений и дает еще некоторое преимущества. Более развернуто почитать о достоинствах этого формата вы можете по указанным ниже ссылкам. О самом формате можно узнать набрав man maildir. Итак, мы выбираем Maildir.

      Для создания каталога Maildir служит программа maildirmake. О параметрах запуска вы можете почитать на её man-странице. Становимся пользователем, которого мы выбрали для псевдонимов root, postmaster и MAILER-DAEMON, чтобы сразу получить все файлы/каталоги с нужными разрешениями и создаем каталог maildir:

# su max
$ /var/qmail/bin/maildirmake /home/max/Maildir

В каждом каталоге пользователя может лежать файл .qmail, в котором содержатся директивы о том, что делать с письмами для этого пользователя. Почитать о его формате можно на man-странице dot-qmail.

Создадим этот файл:

$ cd
$ touch .qmail

Добавим туда директиву "./Maildir/", которая будет говорит qmail о том, что сообщение надо хранить в нужном нам формате:

$ echo "./Maildir/" > .qmail

Нам нужно, чтобы сообщения уходили за переделы системы и пересылались на наш внешний ящик (например, liar@my.domain.ru). Для этого добавим строку "&liar@my.domain.ru":

$ echo "&liar@my.domain.ru" >> .qmail

Становимся опять root:

$ exit

Теперь нам нужно сделать так, чтобы у каждого вновь созданного пользователя автоматически создавался ящик в его homedir. Для этого дополним каталог /etc/skel нужными нам шаблонами:

# /var/qmail/bin/maildirmake /etc/skel/Maildir
# touch /etc/skel/.qmail
# echo "./Maildir/" > /etc/skel/.qmail

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

Запуск qmail-start

      Примеры скриптов запуска лежат в /var/qmail/boot. Если посмотреть их содержимое, то становится ясно, что общий принцип таков:
Вначале с помощью env устанавливается переменные окружения (к обычно к содержимому PATH добавляется путь к бинарникам qmail) и запускается программа qmail-start. После своего старта qmail-start запускает qmail-send, qmail-lspawn, qmail-rspawn, и qmail-clean, устанавливает для них нужные uid и gid, передает им нужные для работы параметры, принимает от них stdout и stderr и перенаправляет их программе, указанной в качестве второго параметра при запуске. Более подробно об этом можно узнать из man qmail-start. Формат запуска qmail-start такой:

qmail-start цель-доставки logger

Цель-доставки — это куда передавать сообщения (этот параметр qmail-start передает qmail-lspawn). У нас это будет Maildir пользователя, хотя, можно передавать сообщения в mailbox или другую программу. Logger — это программа, которая будет принимать сообщения программы qmail-send — владельца всех процессов локальной доставки в qmail. Мы для этих целей будем использовать программу splogger из состава qmail. Она принимает входящий поток сообщений, обрабатывает его и передает в syslog. Splogger принимает два параметра — префикс и источник сообщения для syslog ("facility"). Префиксом у нас будет строка "qmail" (все сообщения для syslog будут начинаться с этой строки), источник по умолчанию (2 — mail). Чтобы узнать больше — как всегда man syslog и man splogger. В обычной linux-системе все сообщения с facility = 2 (mail) хранятся в /var/log/maillog . Также, вы можете использовать для ведения журнала multilog из состава daemontools — это более надежно, хотя и менее привычно.
В конечном итоге стартовый скрипт у нас будет выглядеть так (слегка переделанный вариант скрипта /var/qmail/boot/home):

#!/bin/sh
# Using splogger to send the log through syslog.
# Using qmail-local to deliver messages to ~/Maildir .
exec env - PATH="/var/qmail/bin:$PATH" \
qmail-start ./Maildir/ splogger qmail

Можно просто скопировать /var/qmail/boot/home в /var/qmail/run и изменить "./Mailbox" на "./Maildir/" (не забудьте про второй слэш!)

Поскольку supervise, как только обнаружит у себя в /services новый каталог, сам запускает скрипт run из него, и перезапускает программу при её смерти, мы создадим в каталоге /var/qmail файл down, чтобы supervice не запускал qmail автоматом, пока нам этого не будет надо (см. документацию по daemontools):

# touch /var/qmail/down

Создаем симлинк на /var/qmail в каталоге /services чтобы svscan мог узнать о существовании нового сервиса:

# ln -s /var/qmail /service

Если выполнить pstree, то можно увидеть новый процесс supervise в дереве процессов daemontools. Он обнаружил файл down и поэтому не запускает демон автоматически, а ждет команду на запуск.
Теперь все готово к запуску qmail. Управление сервисами в daemontools производится с помощью программы svc. Запускаем qmail:

# svc -u /service/qmail/

Смотрим, что получилось:

# pstree -u

Если все прошло нормально, то мы увидим:

...skip...
|-svscanboot-+-readproctitle
|            `-svscan---supervise---qmail-send(qmails)-+-qmail-clean(qmailq)
|                                                      |-qmail-lspawn(root)
|                                                      |-qmail-rspawn(qmailr)
|                                                      `-splogger(qmaill)
...skip...

В /var/log/maillog появится запись:
Dec 22 14:41:55 gw qmail: 1072093315.662894 status: local 0/10 remote 0/20
(Возможно появление еще нескольких записей об отправке — в отсутствии MTA демоны накапливают некоторое количество писем для root).
Обратите внимание на имена пользователей, под которыми работают программы. Они должны быть именно такими, иначе qmail откажется работать. Если у вас они не совпадают с приведенным выводом, проверьте, все ли вы сделали правильно.
Теперь пробуем отправить сообщение:

# mail -s "test 1" root
(набираем текст сообщения)<Enter>
.<Enter>
cc:<Enter>

Все, сообщение ушло.
Смотрим логи. Там должны быть записи о старте демона и доставке сообщения.

Dec 22 14:46:02 gw qmail: 1072093562.312652 new msg 131426
Dec 22 14:46:02 gw qmail: 1072093562.312773 info msg 131426: bytes 253 from <root@HOST.DOMAIN.RU> qp 10386 uid 0
Dec 22 14:46:02 gw qmail: 1072093562.318170 starting delivery 1: msg 131426 to local root@host.domain.ru
Dec 22 14:46:02 gw qmail: 1072093562.318241 status: local 1/10 remote 0/20
Dec 22 14:46:02 gw qmail: 1072093562.355299 new msg 131429
Dec 22 14:46:02 gw qmail: 1072093562.355382 info msg 131429: bytes 359 from <root@HOST.DOMAIN.RU > qp 10389 uid 502
Dec 22 14:46:02 gw qmail: 1072093562.360645 starting delivery 2: msg 131429 to local max@host.domain.ru
Dec 22 14:46:02 gw qmail: 1072093562.360716 status: local 2/10 remote 0/20
Dec 22 14:46:02 gw qmail: 1072093562.360741 delivery 1: success: did_0+1+0/qp_10389/
Dec 22 14:46:02 gw qmail: 1072093562.360760 status: local 1/10 remote 0/20
Dec 22 14:46:02 gw qmail: 1072093562.360776 end msg 131426
Dec 22 14:46:02 gw qmail: 1072093562.572414 new msg 131426
Dec 22 14:46:02 gw qmail: 1072093562.572490 info msg 131426: bytes 466 from <root@HOST.DOMAIN.RU > qp 10393 uid 500
Dec 22 14:46:02 gw qmail: 1072093562.577913 starting delivery 3: msg 131426 to remote liar@my.domain.ru
Dec 22 14:46:02 gw qmail: 1072093562.577985 status: local 1/10 remote 1/20
Dec 22 14:46:02 gw qmail: 1072093562.578008 delivery 2: success: did_1+1+0/qp_10393/
Dec 22 14:46:02 gw qmail: 1072093562.578028 status: local 0/10 remote 1/20
Dec 22 14:46:02 gw qmail: 1072093562.578045 end msg 131429
Dec 22 14:46:02 gw qmail: 1072093562.590113 delivery 3: success: 81.26.136.2_accepted_message./Remote_host_said:_250_300014_message_accepted_for_delivery/
Dec 22 14:46:02 gw qmail: 1072093562.612473 status: local 0/10 remote 0/20
Dec 22 14:46:02 gw qmail: 1072093562.612544 end msg 131426

(сообщения удаленного хоста у вас могут быть другими)
Через некоторое время проверяем почту в ящике, указанном в файле .qmail в каталоге пользователя, указанного в псеводонимах в каталоге ~alias.
В каталоге исходников есть более развернутое описание тестов доставки — TEST.deliver, если будет желание, можете провести их все.
Если все нормально, то удаляем файл down, чтобы daemontools перезапускал qmail в случае его падения:

# rm /var/qmail/down

Qmail-smtpd

Установка ucspi-tcp

      Чтобы ваш qmail отвечал высокому званию "MTA" он должен уметь не только доставлять почту локальным и удаленным клиентам изнутри системы, но и принимать её снаружи. Этим занимается qmail-smtpd. Соединения он принимает через программы, аналогичные inetd. Для замены tcpwrappers/inetd/xinetd DJB написал пакет ucspi-tcp, его мы и будем использовать.

      Процесс tcpserver при старте начинает слушать указанный порт (в нашем случае 25) и передает входящие данные программе qmail-smtpd, которую он запускает при установке соединения. Qmail-smtpd в свою очередь передает пришедшую почту qmail-queue для дальнейшей доставки.

Cкачиваем и распаковываем исходники:

# cd /usr/src
# wget http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz
# gunzip ucspi-tcp-0.88.tar
# tar -xf ucspi-tcp-0.88.tar
# cd ucspi-tcp-0.88

Cоздаем каталог для патчей, скачиваем и накладываем их на исходники:

# mkdir patch
# cd patch
# wget http://www.qmail.org/moni.csi.hu/pub/glibc-2.3.1/ucspi-tcp-0.88.nobase.patch
# wget http://www.qmail.org/moni.csi.hu/pub/glibc-2.3.1/ucspi-tcp-0.88.errno.patch
# wget http://www.qmail.org/moni.csi.hu/pub/glibc-2.3.1/ucspi-tcp-0.88.a_record.patch
# cd ..
# patch -p1 < patch/ucspi-tcp-0.88.a_record.patch
# patch -p1 < patch/ucspi-tcp-0.88.nobase.patch
# patch -p1 < patch/ucspi-tcp-0.88.errno.patch

компилируем и устанавливаем:

# make
# make setup check

Запуск qmail-smtpd

Создаем в /var/qmail каталог smtpd (другого, более осмысленного размещения придумать не удалось):

# mkdir /var/qmail/smtpd

Создаем в /var/qmail/smtpd скрипт run (для запуска qmail-smtpd с помощью daemontools) и файл down:

# cd /var/qmail/smtpd
# touch run down

открываем run в mc или vi и вставляем туда текст:

#!/bin/sh
exec envuidgid qmaild \
        softlimit -m 2000000 \
        tcpserver -UDHRQ 0 smtp \
        /var/qmail/bin/qmail-smtpd

# chmod 755 run

здесь сначала запускается envuidgid (из состава daemontools), в качестве параметра запуска передается имя учетной записи, с правами которой запустится tcpserver. Она устанавливет переменные окружения $GID и $UID. Затем запускается программа softlimit, она устанавливает пределы на использование памяти (у нас — ~2MB). Softlimit запускает tspserver, который переключается на работу с правами UID и GID, считанных из переменных окружения $GID и $UID (параметр запуска "-U"). Tcpserver при коннекте на слушаемый порт запускает qmail-smtpd. Подробнее — смотрите в документации на соотвествующие программы.

qmail-smtpd и tcpserver отправляют все свои сообщения на stdout и stderr. Чтобы перехватить их и занести в журнал мы воспользуемся функцией создания pipline между демонами, если в каталоге одного обнаруживается подкаталог log (см. описание daemontools), как это можно было бы сделать и для qmail-start. Можно использовать или родной multilog из daemontools, как это делается в djbdns или splogger из состава qmail, чтобы вести логи через syslog. Мы будем использовать splogger.
Создаем каталог для запуска программы логирования и связки её с qmail-smtpd через daemontools:

# mkdir /var/qmail/smtpd/log
# cd log
# touch run down

добавляем в run следующий текст:

#!/bin/sh
exec 2>&1
exec setuidgid qmaill /var/qmail/bin/splogger smtpd 2

# chmod 755 run

(Запускаем splogger под его пользователем с помощью setuidgid и передаем ему нужные параметры. Параметр "smtpd" выбран произвольно, можно использовать и "qmail").
затем создаем симлинк для запуска через daemontools:

# ln -s /var/qmail/smtpd /service

пробуем запустить:

# svc -u /service/qmail/smtpd/log/
# svc -u /service/qmail/smtpd/

проверяем:

# pstree -u

...skip...
|-svscanboot-+-readproctitle
|            `-svscan---supervise-+-qmail-send(qmails)-+-qmail-clean(qmailq)
|                                 |                    |-qmail-lspawn(root)
|                                 |                    |-qmail-rspawn(qmailr)
|                                 |                    `-splogger(qmaill)
|                                 |-supervise---tcpserver(qmaild)
|                                 `-supervise---splogger(qmaill)
...skip...
нас интересуют процессы tcpserver и splogger &mdash: мы видим, что они запущены и работают под нужными пользователями. Проверяем, слушает ли tcpserver 25 порт:

# lsof -i -P -n | grep 'LISTEN'

tcpserver 15591   qmaild    3u  IPv4 764976       TCP *:25 (LISTEN)
или

# netstat -l -n | grep 'LISTEN'
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN
Если все нормально, то можно удалить файлы down из /service/qmail/smtpd/log/ и /service/qmail/smtpd/. Если что-то не так, то ошибки можно увидеть или в /var/log/maillog (или куда там у вас syslog кидает сообщения от почтового сервера) или, если используется multilog вместо splogger, через ps -auxww как параметры readproctitle.

Теперь можно попробовать отправить сообщение самому себе в систему с другой машины. Результат можно посмотреть в логах + само сообщение в Maildir (syslog может кидать сообщения в журнал с большой задержкой, чтобы их увидеть приходится подождать или перезапустить syslog). Если вы настраивали пересылку на внешний ящик, то надо глянуть письмо там. Можно просто отослать письмо с ящика, указанного в .qmail, в систему с qmail и через минуту оно вернется обратно, если все нормально в обеих системах. По заголовкам письма можно проверить его путь.

Обратите внимание, что при сделаных нами настройках qmail принимает почту только для систем, перечисленных в файле rcpthosts. Если вы хотите, чтобы он служил релеем для некоторой сети, придется подправить его скрипт запуска. Подробнее читайте на http://www.ru.qmail.org/addons.html или в документации qmail о переменной окружения RELAYCLIENT.

Следует заметить, что запуск qmail-smtpd тут рассматривается с обучающими целями. Если вы решите использовать его для работы, то необходимо сделать как минимум две вещи: проверку на вирусы и проверку существования получателя письма. Существует большое число программ и патчей, позволяющих это сделать, большинство из них можно найти на www.qmail.org. Можно рекомендовать попробовать simscan для борьбы с вирусом и спамом и патч qmail-spp, позволяющий очень сильно расширить функциональность qmail-smtpd, в т.ч. и проверять получателя во время smtp-сессии. В дальнейшем, если в qmail понадобится что-то новое, это почти всегда можно найти в виде патча на qmail.org или в Google.

В отличие от огромного и монолитного sendmail qmail состоит из множества маленьких программ, осуществляющих только одну функцию. На первых порах легко запутаться, какая из них что делает. Рекомендуется посмотреть содержимое файлов PIC.* из каталога исходников qmail и схемы на http://www.ru.qmail.org/docs/original/inform.html.

Несомненно, многие вещи можно упростить, в частности, попробовать сразу указать нужный псевдоним в /var/qmail/alias/.qmail-root или нужный адрес в другой системе в конфигах программ, или не писать директиву ./Maildir/ в /qmail, чтобы не оставлялись копии пересланных сообщений, но ведь наша основная задача — понять, как все работает, а дальше мы и сами все настроим, так ;) ?

Замечания относительно FreeeBSD

      Поскольку этот текст был написан в те времена, когда я работал только с Linux, некоторые моменты неприменимы к FreeBSD. Недавно появилась возможность установить qmail и на FreeBSD, в связи с чем наметились несколько дополнений, которые было решено вынести в отдельный раздел для экономии времени.

      Во-первых, во FreeBSD мне не удалось найти возможность полностью удалить sendmail из системы, поэтому чтобы его корректно отключить сделайте следующее:

  • Добавьте в файл /etc/rc.conf строку:
    sendmail_enable="NONE"
    Это отключит запуск всех сервисов sendmail. После этого необходимо или убить все процессы Sendmail или перезагрузить систему.
  • Добавьте в файл /etc/make.conf строку:
    NO_SENDMAIL=true
    это исключит sendmail из пересобираемых и переустанавливаемых программ при make world и make installworld. Иначе sendmail, отключенный нами, будет переустановлен снова.

      Во-вторых, нам необходимо корректно заменить sendmail и системе. Далее идет перевод какого-то из man'ов (никак не могу вспомнить какого):
Программа sendmail настолько распространена в качестве стандартной программы для систем *NIX, что многие программы считают, что она уже установлена и настроена. По этой причине многие альтернативные MTA предоставляют собственные совместимые реализации интерфейса командной строки sendmail; это облегчает их использование в качестве "прозрачной" замены sendmail.
Поэтому если вы используете альтернативную почтовую программу, потребуется убедиться, что когда программное обеспечение пытается выполнить стандартные исполняемые файлы sendmail, такие как /usr/bin/sendmail, на самом деле выполняются программы вновь установленной почтовой системы. К счастью, FreeBSD (начиная с версии 4.0) предоставляет систему, называемую mailwrapper(8), которая выполняет эту работу за вас.
Когда установлен sendmail, файл /etc/mail/mailer.conf выглядит примерно так:

sendmail    /usr/libexec/sendmail/sendmail
send-mail   /usr/libexec/sendmail/sendmail
mailq       /usr/libexec/sendmail/sendmail
newaliases  /usr/libexec/sendmail/sendmail
hoststat    /usr/libexec/sendmail/sendmail
purgestat   /usr/libexec/sendmail/sendmail
Это означает, что, например, /usr/sbin/sendmail является на самом деле символической ссылкой на mailwrapper, которая и запускается вместо вызываемой программы. Mailwrapper обращается к mailer.conf за информацией и выполняет /usr/libexec/sendmail/sendmail. Такое положение вещей делает простой замену программ, выполняемых при вызыве стандартных функций sendmail.
Поэтому если вы хотите запускать файлы qmail вместо sendmail, отредактируйте /etc/mail/mailer.conf так:
sendmail        /var/qmail/bin/sendmail
send-mail       /var/qmail/bin/sendmail
mailq           /var/qmail/bin/qmail-qread
newaliases      /var/qmail/bin/newaliases
hoststat        /var/qmail/bin/qmail-tcpto
purgestat       /var/qmail/bin/qmail-tcpok
В дополнение к этому в целях повышения безопасности сделаем следующее:

# chmod 0 /usr/libexec/sendmail/sendmail
# mv /usr/libexec/sendmail/sendmail /usr/libexec/sendmail/sendmail.bak

Для более старых версияй можно найти руководство в файле "REMOVE.sendmail". На всякий случай можно переместить исходные тексты qmail из /usr/src в ~/src, например, т.к. неизвестно что с ними будет при обновлении системы через cvsup.

Cсылки




Рейтинг@Mail.ru