четверг, 5 ноября 2009 г.

Настройка почтовой системы на основе Postfix, Dovecot, PostfixAdmin

Перед тем, как приступить к настройке почтового сервера, необходимо убедиться в том, что на сервере имеется прямой доступ в Интернет, то есть на одном из интерфейсов имеется так называемый «белый» IP. Также на сервере должна быть доступна служба DNS. Поскольку почтовый сервер очень часто обращается к службе DNS, может потребоваться настроить локальный кэширующий DNS-сервер для снижения нагрузки на сеть и повышения отзывчивости подсистемы DNS.

Настраиваемая почтовая система обладает возможностями по администрированию доменов и почтовых ящиков через веб-интерфейс PostfixAdmin, в качестве основного домена в статье фигурирует домен stupin.homelinux.org, все учётные записи при этом хранятся в базе данных MySQL. Имеется почтовый клиент с веб-интерфейсом SquirrelMail, фильтрация спама средствами PostGrey, фильтрация вирусов средствами ClamSMTPd, отметка подозрительных писем с помощью SpamPd и SpamAssassin.

Не смотря на то, что настройка почтовой системы рассмотрена довольно подробно, данная статья конечно же не претендует на полноту. За кадром остаётся настройка защищённого подключения к веб-серверу, тонкая настройка фильтрации почты с помощью SpamAssassin, Postfix и PostGrey, повышение безопасности почтовой системы посредством запуска отдельных подсистем от имени непривилегированных пользователей и т.п. Статью можно использовать в качестве опорной для построения более развитой почтовой системы.

Настройка Lighttpd

Первым делом устанавливаем веб-сервер lighttpd, php.
# aptitude install lighttpd php5-cgi php5-json
Включаем модуль fastcgi веб-сервера lighttpd:
# lighty-enable-mod fastcgi
Заменяем в конфигурации модуля /etc/lighttpd/conf-enabled/10-fastcgi.conf интерпретатор PHP4 на PHP5:
fastcgi.server = (
  ".php" =>
  (
    (
      "bin-path" => "/usr/bin/php5-cgi",
      "socket" => "/tmp/php.socket",
      "max-procs" => 2,
      "idle-timeout" => 20,
      "bin-environment" =>
      (
        "PHP_FCGI_CHILDREN" => "4",
        "PHP_FCGI_MAX_REQUESTS" => "10000"
      ),
      "bin-copy-environment" =>
      (
        "PATH", "SHELL", "USER"
      ),
      "broken-scriptfilename" => "enable",
      "check-local" => "disable"
    )
  )
)
Перезапускаем веб-сервер:
# /etc/init.d/lighttpd restart
Настройка PostfixAdmin

Качаем последнюю стабильную версию PostfixAdmin со страницы http://sourceforge.net/projects/postfixadmin/files/. Для Debian существует готовый пакет postfixadmin_2.2.1.1_all.deb, его и скачаем:
$ wget "http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-2.2.1.1/postfixadmin_2.2.1.1_all.deb?use_mirror=sunet"
Установим пакет в систему:
# dpkg -i postfixadmin_2.2.1.1_all.deb
Пакет устанавливает все файлы проекта в каталог /usr/share/postfixadmin, файлы документации - в каталог /usr/share/doc/postfixadmin. Также создаются файлы с настройками самого PostfixAdmin - /etc/postfixadmin/config.inc.php и настройками Apache 2 - /etc/apache2/conf.d/postfixadmin.

Поскольку я собираюсь пользоваться PostfixAdmin на web-сервере Lighttpd, заглянем в файл /etc/apache2/conf.d/postfixadmin:
Alias /postfixadmin /usr/share/postfixadmin
И создадим на его основе настройки для Lighttpd - в файл /etc/lighttpd/lighttpd.conf нужно будет добавить строчки:
alias.url += (
  "/postfixadmin" => "/usr/share/postfixadmin",
)
Дополнительно, защитим каталог на web-сервере от случайных зевак:
auth.backend = "htdigest"
auth.backend.htdigest.userfile = "/etc/lighttpd/htdigest"
auth.require = (
  "/posfixadmin" =>
  (
    "method" => "digest",
    "realm" => "PostfixAdmin",
    "require" => "user=morbo"
  )
)
И с помощью утилиты htdigest из пакета apache2-utils задаём пароль для пользователя morbo и рилма PostfixAdmin:
$ htdigest /etc/lighttpd/htdigest "PostfixAdmin" morbo
Настроим Postfix Admin в соответствии с вашей спецификой (например, зададим подходящий пароль к базе данных, настроим домен по умолчанию и т.п.)

Отредактируем файл /usr/share/postfixadmin/config.inc.php и укажем следующее:
# vi config.inc.php
[...]
$CONF['configured'] = true;
$CONF['postfix_admin_url'] = 'http://stupin.homelinux.org/postfixadmin';
$CONF['database_type'] = 'mysql';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfixadmin';
$CONF['database_password'] = 'SecretPassword!';
$CONF['database_name'] = 'postfix';
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
$CONF['encrypt'] = 'cleartext';
Просмотрите остаток файла, если вам захочется сделать более тонкие настройки.

Вы можете быстро заменить домен по умолчанию на ваш собственный:
$ replace "change-this-to-your.domain.tld" "stupin.homelinux.org" - /usr/share/postfixadmin/config.inc.php
Создайте базу данных и пользователя в mysql:
$ mysql -u root -p
mysql> create database postfix;
mysql> grant all privileges on postfix.* to 'postfixadmin'@'localhost' identified by 'SecretPassword!';
mysql> flush privileges;
mysql> q
Откройте браузер и перейдите по ссылке http://stupin.homelinux.org/postfix/setup.php или http://ваш-IP/postfixadmin/. Будет предложено запустить процесс настройки. Удостоверьтесь, что все проверки установщика сообщают 'OK'.

Рекомендуется удалить setup.php.

Теперь перейдите по ссылке http://stupin.homelinux.org/postfixadmin/admin. Вы должны получить приглашение. Войдите с использованием почтового ящика администратора, заведённого ранее на странице настройки. Отсюда вы можете добавлять домены, почтовые ящики и т.п. Но Postfix этого не увидит. Нам нужно установить Postfix и настроить его.

Настройка Postfix

Установим Postfix и SASL2 с поддержкой MySQL:
# aptitude install postfix-mysql postfix-tls libsasl2-modules-sql libsasl2-modules
Добавим в файл /etc/postfix/main.cf следующие строки:
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_gid_maps = static:106
virtual_mailbox_base = /var/spool/mail/virtual
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 106
virtual_transport = virtual
virtual_uid_maps = static:106
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated,
  reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient,
  reject_unauth_destination, reject_unauth_pipelining, reject_invalid_hostname
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous
ЗАМЕЧАНИЕ: UID и GID равные 106 на вашей системе могут быть другими. Посмотрите на UID и GID пользователя postfix (или vmail) в файле /etc/passwd и укажите их. Например, на моём сервере:
# grep postfix /etc/passwd
postfix:x:102:105::/var/spool/postfix:/bin/false
--> uid: 102; gid: 105
Создайте файл /etc/postfix/mysql_virtual_alias_maps.cf:
user = postfix
password = SecretPassword!
hosts = 127.0.0.1
dbname = postfix
table = alias
select_field = goto
where_field = address
Файл mysql_virtual_domains_maps.cf:
user = postfix
password = SecretPassword!
hosts = 127.0.0.1
dbname = postfix
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = '0' and active = '1'
Файл mysql_virtual_mailbox_maps.cf:
user = postfix
password = SecretPassword!
hosts = 127.0.0.1
dbname = postfix
table = mailbox
select_field = maildir
where_field = username
Если вы хотите разрешить ретрансляцию почты через ваш сервер после SMTP AUTH, пропишите в файле /etc/postfix/sasl/smtpd.conf следующие настройки:
pwcheck_method: auxprop
mech_list: PLAIN LOGIN
auxprop_plugin: sql
sql_verbose: yes
sql_engine: mysql
sql_hostnames: 127.0.0.1
sql_user: postfix
sql_passwd: SecretPassword!
sql_database: postfix
sql_select: select password from mailbox where username = '%u@%r'
Создайте структуру каталогов, включая каталог для первого домена. Вы так же можете войти в PostfixAdmin и создать учётную запись 'test' для домена stupin.homelinux.org.
# mkdir -p /var/spool/mail/virtual/stupin.homelinux.org/test
# chmod -R 770 /var/spool/mail/virtual
# chown -R postfix:postfix /var/spool/mail/virtual
Настройка Dovecot

Установим Dovecot с поддержкой MySQL:
# aptitude install dovecot-common dovecot-imapd dovecot-pop3d
Отредактируем файл /etc/dovecot/dovecot-mysql.conf с настройками Dovecot/MySQL, воспользовавшись следующими опциями:
driver = mysql
connect = dbname=postfix user=postfixadmin host=127.0.0.1 password=SecretPassword!
default_pass_scheme = PLAIN
password_query = SELECT password
                 FROM mailbox
                 WHERE username = '%u'
user_query = SELECT maildir,
                    106 AS uid,
                    106 AS gid
             FROM mailbox
             WHERE username = '%u'
Теперь настроим Dovecot на использование MySQL, задав следующие опции в файле /etc/dovecot/dovecot.conf:
protocols = imap imaps pop3 pop3s
disable_plaintext_auth = no
log_timestamp = "%Y-%m-%d %H:%M:%S "
mail_location = maildir:/var/spool/mail/virtual/%d/%n
mail_access_groups = mail
first_valid_uid = 106
first_valid_gid = 106
protocol imap {
}
protocol pop3 {
  pop3_uidl_format = %08Xu%08Xv
}
auth default {
  mechanisms = digest-md5 plain
  passdb sql {
    args = /etc/dovecot/dovecot-mysql.conf
  }
  userdb sql {
    args = /etc/dovecot/dovecot-mysql.conf
  }
  user = root
}
Перезапустим Dovecot и Postfix и проверим их.

По завершении вы должны получить возможность добавлять новые домены, почтовые ящики, псевдонимы с помощью PostfixAdmin и получить правильно работающую систему, включая SMTP-аутентификацию. Отметим, что для работы SMTP-аутентификации saslauthd не требуется.

Настройка SquirrelMail

Устанавливаем пакет squirrelmail:
# aptitude install squirrelmail
В файл /etc/lighttpd/lighttpd.conf нужно будет добавить строчки:
alias.url += (
  "/mail" => "/usr/share/squirrelmail"
)
Настройку SquirrelMail можно осуществить с помощью ncurses-утилиты squirrelmail-configure.

Настройка плагина SquirrelMail PosfixAdmin

Для того, чтобы пользователи имели возможность самостоятельно менять свои пароли, можно установить расширение postfixadmin для squirrelmail. Адрес проекта http://squirrelmail-postfixadmin.palepurple.co.uk/

Чтобы скачать исходники проекта, необходимо поставить утилиты subversion:
# aptitude install subversion
Создадим каталог для скачиваемых из svn исходников плагина, скачаем исходники, скопируем необходимое нам, а лишнее удалим:
$ mkdir ~/squirrelmail-postfixadmin
$ cd ~/squirrelmail-postfixadmin
$ svn co -r 35 http://squirrelmail-postfixadmin.palepurple.co.uk/svn
$ mkdir ~/squirrelmail
$ cp ~/squirrelmail-postfixadmin/svn/tags/squirrelmail-postfixadmin-0.4.3/* ~/postfixadmin/
$ rm -R ~/squirrelmail-postfixadmin
Почистим исходники плагина от служебных файлов subversion:
$ find ~/postfixadmin/ -name .svn -type d -exec rm -R \{\} \;
Установим плагин в каталог squirrelmail:
# cp ~/postfixadmin /usr/share/squirrelmail/plugins/
Тонкая настройка Postfix

Во-первых, я задаю имя, которое будет использовать Postfix при отправке почты на другие почтовые серверы (в команде HELO или EHLO) или при приёме почты на 25 порту в приглашении (например, «220 stupin.homelinux.org ESMTP Postfix»):
myhostname = stupin.homelinux.org
myorigin = $myhostname
Во-вторых, укажем сети, имеющие право отправки почты без прохождения авторизации:
mynetworks = 10.16.7.0/24, 127.0.0.1
Далее, мой провайдер поместил все клиентские сети в список динамических IP, так называемый DUL. Из-за этого подавляющее большинство почтовых серверов отказываются принимать от меня почту. Чтобы отправка почты всё-таки работала, мой провайдер позволяет отправлять почту через его почтовый сервер mail.ufanet.ru:
relayhost = [mail.ufanet.ru]
И, наконец, я хочу чтобы Postfix не пытался складывать локальную почту в локальные же файлы mailbox. Вместо этого, он должен обрабатывать такую почту, как и всю остальную, то есть передавать её dovecot'у. Для этого пропишем следующую опцию:
local_transport = virtual
Настройка PostGrey

Установим postgrey:
# aptitude install postgrey

Поменять настройки можно в файле /etc/default/postgrey. Я добавил одну дополнительную опцию, которая помещает отправителя в белый список после 5 удачно пройденных тестов:
POSTGREY_OPTS="--inet=127.0.0.1:60000 --auto-whitelist-clients=5"
Настраиваем postfix на использование сервера политик postgrey. В файле /etc/postfix/main.cf к опции smtpd_recipient_restrictions в конец списка добавляем «check_policy_service inet:127.0.0.1:60000». После этого опция smtpd_recipient_restrictions в моей системе приняла следующий вид:
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated,
  reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient,
  reject_unauth_destination, reject_unauth_pipelining, reject_invalid_hostname,
  check_policy_service inet:127.0.0.1:60000
Теперь, чтобы настройки вступили в силу, можно перезапустить postgrey и postfix:
# /etc/init.d/postgrey restart
# /etc/init.d/postfix reload
Настройка ClamSMTPD

Устанавливаем clamsmtpd (если на сервере установлен стабильный релиз Debian, то лучше подключить дополнительный репозиторий volatile, в который помещаются обновления антивирусных баз данных и систем фильтрации спама):
# aptitude install clamsmtpd
Обновляем антивирусные базы:
# freshclam -v
Настраиваем порты демона в файле /etc/clamsmtpd.conf (я изменил их следующим образом):
OutAddress: 10026
Listen: 127.0.0.1:10025
Настраиваем postfix на передачу файла в clamsmtp. Во-первых добавим в файле /etc/postfix/main.cf следующие опции:
content_filter = scan:127.0.0.1:10025
receive_override_options = no_address_mappings
Во-вторых, в файл /etc/postfix/master.cf добавляем следующее:
scan      unix  -       -       n       -       16      smtp
  -o smtp_send_xforward_command=yes

127.0.0.1:10026 inet  n -       n       -       16      smtpd
  -o content_filter=
  -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
  -o smtpd_helo_restrictions=
  -o smtpd_client_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=permit_mynetworks,reject
  -o mynetworks_style=host
  -o smtpd_authorized_xforward_hosts=127.0.0.0/8
Перезапускаем clamsmtpd и postfix:
# /etc/init.d/clamsmtp restart
# /etc/init.d/postfix restart
Настройка SpamPd

Устанавливаем spampd:
# aptitude install spampd
Настраиваем spampd, в файле /etc/default/spampd меняем следующие опции:
LISTENPORT=10026
DESTPORT=10027
Также необходимо поменять настройки входного порта postfix, на котором письмо принимается без дополнительных проверок. В файле /etc/postfix/master.cf меняем строку
127.0.0.1:10026 inet  n -       n       -       16      smtpd
на строку
127.0.0.1:10027 inet  n -       n       -       16      smtpd
Для вступления настроек в силу перезапускаем postfix и spampd:
# /etc/init.d/postfix restart
# /etc/init.d/spampd restart
Пояснение принципов фильтрации писем

Теперь clamsmtpd и spampd работают последовательно. Postfix получая новое письмо на порт 25, передаёт письмо на проверку на порт 10025, где его принимает clamsmtpd. Далее, проверив письмо, clamsmtpd передаёт письмо на порт 10026, где его принимает spampd. Далее, после проверки, spampd возвращает письмо Posfix'у на порт 10027. Postfix, получив письмо на порт 10027, принимает его без дополнительных проверок.

clamsmtpd работает в связке с clamav-daemon, последовательно передавая ему на проверку все секции и вложения письма.

spampd тоже работает в связке с демоном spamassassin, передавая ему на проверку письмо целиком. Важно, что в данном примере настройки, не происходит автоматическое удаление писем, похожих на спам. Вместо этого в начало темы подозрительного письма добавляется текст «*****SPAM***** », а в заголовок письма помещаются метки SpamAssassin, свидетельствующие о количестве набранных спам-баллов и описанием каждого признака спама. Для удаления подозрительных писем необходимо воспользоваться дополнительными компонентами почтовой системы.

Ссылки

  1. Настройка веб-интерфейса Clutch - взята часть про настройку Lighttpd и PHP. Не пропадать же однажды уже написанному добру?!
  2. Squirrelmail - PostfixAdmin plugin
  3. Перевод этой и следующих двух статей я сделал отчасти для того, чтобы потом по ней написать этот мануал:
  4. PostfixAdmin на Debian
  5. ClamAV + clamsmtpd + Postfix
  6. Postfix и Postgrey: Проактивный способ фильтрации спама