Почтовая система провайдера

Дата публикации: 2007-01-06
В этой статье я опишу как можно создать почтовую систему уровня провайдера. Система будет включать в себя полноценную поддержку множества доменов, пользователи виртуальные - хранятся в базе MySQL, поддержка антивирусной проверки почты и система антиспама.
  В этой статье я опишу как можно создать почтовую систему уровня провайдера.
  Система будет включать в себя полноценную поддержку множества доменов, 
  пользователи виртуальные - хранятся в базе MySQL,
  поддержка антивирусной проверки почты и система антиспама.
  Используемые компоненты/программное обеспечение:
  1. сервер БД - MySQL
  2. POP3 сервер - QPopper с патчем для работы с MySQL
  3. SMTP сервер - Exim
  4. Антивирус - DrWeb
  5. Антиспам - SpamAssassin

  Как всегда ( ;) ) при написании статьи я буду сразу устанавливать систему на сервер и писать статью.
  Ссылки на весь используемый софт будут указаны в конце статьи
  Имеем сервер с установленной Slackware 11.0. МySQL специально не устанавливал из дистрибутива, 
  ибо хотел на момент написания статьи версию 5.1 (свои причины - связанны с тем что сервер этот должен будет заниматся репликацией данных с другим сервером).

  Итак скачали MySQL, распаковываем, компилируем:
  ./configure --prefix=/usr/local/mysql-5.1.14 --sysconfdir=/etc --enable-assembler --with-charset=cp1251 --with-extra-charsets=all --with-plugins=all
  make
  make install
  Теперь надо инсталлировать служебные базы и запустить собственно сам MySQL.
  В Slackware есть уже готовые файлы для конфигов мускула и для запуска при старте системы - воспользуемся этим для быстрого старта.
  root@www:/usr/local/src/mysql-5.1.14-beta# cp /etc/my-large.cnf /etc/my.cnf
  root@www:/usr/local/src/mysql-5.1.14-beta# chown +x /etc/rc.d/rc.mysqld
  Поскольку я хочу чтобы у меня мускул держал базы в /var/lib/mysql в /etc/my.cnf добавляю строчку datadir=/var/lib/mysql и даю права
  root@www:/usr/local/src/mysql-5.1.14-beta# chown mysql.mysql /var/lib/mysql
  root@www:/usr/local/src/mysql-5.1.14-beta# su - mysql
  mysql@www:~$ /usr/local/mysql-5.1.14/bin/mysql_install_db
  изменяем /etc/rc.d/rc.mysqld на предмет правильного пути к mysqld_safe (я просто изменил /usr/bin/mysqld_safe на /usr/local/mysql-5.1.14/bin/mysqld_safe) и запускаем
  Пока с мускулом все.

  Переходим к QPopper'у.
  Скачиваем, распакавываем все в /usr/local/src/qpopper4.0.9.
  Затем скачиваем и туда же кидаем патч qpopper-mysql-0.15-test.patch.
  Применяем его
  root@www:/etc/rc.d# root@www:/usr/local/src/qpopper4.0.9# patch -p1 < qpopper-mysql-0.15-test.patch
  Внимательно читаем появившийся файлик README.MYSQL
  Из этой документации вырезаем кусок SQL-команд сохраняем его в файл (например mail.sql) и немного "дорабатывем", получаем в результате:

CREATE DATABASE mail;

GRANT SELECT,UPDATE on mail.* to 'mail_db_user'@'localhost' identified by 'mail_db_password';

flush privileges;

use mail;

CREATE TABLE relay_ip (
  ip char(15) NOT NULL default '',
  ts int(11) NOT NULL default '0',
  KEY ip(ip)
);

CREATE TABLE email (
  username varchar(128) NOT NULL,
  domain varchar(64),
  password varchar(64) NOT NULL,
  is_alias char(1) default 'N',
  alias varchar(250) default '',
  quota int(11) default 5000000,
  status int(2) DEFAULT '0',
  key is_alias(is_alias),
  key username(username),
  key domain(domain)
);

  и "загоняем" все эти команды в мускул.
  Теперь приступаем к компиляции QPopper'а

./configure --enable-log-login-mysql --enable-mysql --with-mysqlconfig=/etc/mail/mysql-popper.conf \
  --enable-servermode --enable-shy --enable-spool-dir=/var/spool/mail --enable-log-facility=LOG_MAIL \
  --enable-old-spool-loc --enable-standalone --enable-fast-update --enable-chunky-writes=1  --prefix=/usr \
  --disable-status --enable-cache-dir=/var/spool/mail/cache --enable-temp-drop-dir=/var/spool/mail/pop \
  --disable-check-pw-max --disable-hash-dir-check --without-pam --enable-nonauth-file=/etc/mail/deny.users \
  --with-openssl

  Вот так страшно выглядить configure :)
  Затем стандартно:
  make
  make install

  Конфигурационный файл надо скопировать вручную
  cp /usr/local/src/qpopper4.0.9/mysql-popper.conf /etc/mail

  После редактирования получаем

MysqlAuthHost                   localhost
MysqlAuthPort                   3306
MysqlAuthDb                     mail
MysqlUsername                   mail_db_user
MysqlPassword                   mail_db_password
MysqlAuthTable                  email
MysqlAuthPasswordMethod         any
MysqlAuthUsernameField          username
MysqlAuthDomainField            domain
MysqlAuthDefaultDomain          rus21.ru
MysqlAuthPasswordField          password
MysqlAuthUidName                mail
MysqlAuthGidName                mail
MysqlAuthAcctStatusField        status

  Рисуем такой скрипт /etc/rc.d/rc.popper для запуска QPopper'а
#!/bin/sh

start() {
  if [ -x /usr/sbin/popper ]; then
    echo "Starting Qpopper: /usr/sbin/popper"
    /usr/sbin/popper
  fi
}

stop() {
  killall popper
}

restart() {
  stop
  sleep 1
  start
}

case "$1" in
'start')
  start
  ;;
'stop')
  stop
  ;;
'restart')
  restart
  ;;
*)
  echo "usage $0 start|stop|restart"
esac

  в /etc/rc.d/rc.M добавляем строки

# Start the Qpopper name server daemon:
if [ -x /etc/rc.d/rc.popper ]; then
  . /etc/rc.d/rc.popper start
fi

  дабы не было проблем надо вручную создать каталог для временных файлов и назначить правильные права
  mkdir /var/spool/mail/pop
  chown mail.mail /var/spool/mail/pop

  Делаем небольшой тест

mysql> \u mail
Database changed
mysql> insert into email values('ibz','rus21.ru','123','N','',5000000,1);
Query OK, 1 row affected (0.00 sec)

  root@www:/etc/mail# telnet localhost 110
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
+OK ready
user ibz
+OK Password required for ibz.
pass 123
+OK ibz has 0 visible messages (0 hidden) in 0 octets.
quit
+OK Pop server at www.rus21.ru signing off.
Connection closed by foreign host.
root@www:/etc/mail#

  Все ок, теперь начинаем настраивать связку exim+drweb+spamassassin

  Распаковываем в /usr/local/src/exim-4.66
  Стандартным привычным движением копируем файлик /usr/local/src/exim-4.66/src/EDITME в нужное место (кто не понял - надо
  нудно и долго читать README* - тяжело в учении легко в бою)
  root@www:/usr/local/src/exim-4.66# cp src/EDITME Local/Makefile
  Далее редактируем Local/Makefile
  Я сделал следующие изменения
  CONFIGURE_FILE=/etc/mail/exim-4.66.conf
  EXIM_USER=mail
  расскоментировал и исправил 
  LOOKUP_MYSQL=yes
  LOOKUP_INCLUDE=-I /usr/include/mysql
  LOOKUP_LIBS=-L/usr/lib -lmysqlclient
  закоментировал #EXIM_MONITOR=eximon.bin
  WITH_CONTENT_SCAN=yes
  AUTH_CRAM_MD5=yes
  AUTH_PLAINTEXT=yes
LOG_FILE_PATH=/var/log/exim/%slog
SYSTEM_ALIASES_FILE=/etc/mail/aliases

  ну а дальше 
  cd /usr/local/src/exim-4.66; make; make install
  mv /usr/sbin/sendmail /usr/sbin/sendmail.original
  ln -s /usr/exim/bin/exim /usr/sbin/sendmail
  mkdir /var/log/exim
  chown mail.mail /var/log/exim

  теперь надо установить DrWeb. Тут я особенно не мудрствовал - просто распаковал все архивы как было. Нужны три компонента
  - Демон DrWeb для линукса (подходящий к вашему libc)
  - Клиент-фильтр для Exim'а
  - Ключ для DrWeba (У меня была лицензия на 50 почтовых ящиков, раз в год обновляемая)
  
  Что я еще сделал - так это создал пользователя и группу drweb, в группу drweb дополнительно добавил юзера mail, и сделал
  chown -R drweb.drweb /var/drweb 

  Далее с сайта http://spamassassin.apache.org/ утягиваем последнюю версию СпамАсасина
  Распаковываем, с разгону пробуем запустить

root@www:/usr/local/src/Mail-SpamAssassin-3.1.7# perl Makefile.PL

  Получаем предупреждение что мол нет нужных библиотек, примерно так:

  ...
  ***************************************************************************
NOTE: the optional Archive::Tar (version 1.23) module is not installed.

  The "sa-update" script requires this module to access tar update
  archive files.


***************************************************************************
NOTE: the optional IO::Zlib (version 1.04) module is not installed.

  The "sa-update" script requires this module to access compressed
  update archive files.

REQUIRED module missing: Digest::SHA1
REQUIRED module missing: HTML::Parser
optional module missing: Net::DNS
optional module missing: Mail::SPF::Query
optional module missing: IP::Country
optional module missing: Razor2
optional module missing: Net::Ident
optional module missing: IO::Socket::INET6
optional module missing: IO::Socket::SSL
optional module missing: LWP::UserAgent
optional module missing: HTTP::Date
optional module missing: Archive::Tar
optional module missing: IO::Zlib

warning: some functionality may not be available,
please read the above report before continuing!

  Нас это не устраивает. Быстро ваяем такой шелл скрипт

perl -MCPAN -e 'install SNMP'
perl -MCPAN -e 'install Digest::SHA1'
perl -MCPAN -e 'install HTML::Parser'
perl -MCPAN -e 'install Net::DNS'
perl -MCPAN -e 'install Mail::SPF::Query'
perl -MCPAN -e 'install IP::Country'
perl -MCPAN -e 'install Razor2'
perl -MCPAN -e 'install Net::Ident'
perl -MCPAN -e 'install IO::Socket::INET6'
perl -MCPAN -e 'install IO::Socket::SSL'
perl -MCPAN -e 'install LWP::UserAgent'
perl -MCPAN -e 'install HTTP::Date'
perl -MCPAN -e 'install Archive::Tar'
perl -MCPAN -e 'install IO::Zlib'

  отвечаем на вопросы, долго и нудно, выбираю все в основном по умолчанию.
  После того как закончится снова делаю
root@www:/usr/local/src/Mail-SpamAssassin-3.1.7# perl Makefile.PL
  на этот раз удачно, дальше стандартно
  make; make install

  Конфиги SpamAssassin'а в /etc/mail/spamassassin пока не трогаем
  Одна особенность для Slackware - в /etc/passwd домашний каталог для юзера mail изменяем с "/" на "/var/spool/mail"
  создаем rc.файл для запуска, нечто вроде такого:

#!/bin/sh

start() {
  if [ -x /usr/bin/spamd ]; then
    echo "Starting Spamd:  /usr/bin/spamd -d -s /var/log/exim/spamd.log -u mail"
    /usr/bin/spamd -d -s /var/log/exim/spamd.log -u mail
  fi
}

stop() {
  killall spamd
}

restart() {
  stop
  sleep 1
  start
}

case "$1" in
'start')
  start
  ;;
'stop')
  stop
  ;;
'restart')
  restart
  ;;
*)
  echo "usage $0 start|stop|restart"
esac

  запускаем его, вроде в логах ничего криминального нет. Приступаем к запуску Exim.
  Для начала нарисуем rc.файл:

#!/bin/sh
start() {
  if [ -x /usr/sbin/exim ]; then
    echo "Starting Exim:  /usr/sbin/exim -bd -q2h"
    /usr/sbin/exim  -bd -q2h

  fi
}

stop() {
  killall exim
}

restart() {
  stop
  sleep 1
  start
}

case "$1" in
'start')
  start
  ;;
'stop')
  stop
  ;;
'restart')
  restart
  ;;
*)
  echo "usage $0 start|stop|restart"
esac

  теперь надо править конфиг-файл для exim
  



  Ссылки
  http://www.mysql.org/downloads/ - MySQL
  http://www.eudora.com/products/unsupported/qpopper/index.html - QPopper
  http://asteroid-b612.org/software/qpopper-mysql/qpopper-mysql-0.15-test.patch - Патч для QPopper'а для работы с MySQL