Postfix — агент передачи почты (MTA — mail transfer agent).

Postfix создавался как альтернатива для патриарха MTA — Sendmail. Считается, что Postfix быстрее работает, легче в администрировании, более защищен и, что важно, совместим с Sendmail.

Postfix отличается продуманой модульной архитектурой, которая позволяет создать очень надежную и быструю почтовую систему. Так, например, привилегии root требуются только для открытия порта (TCP 25 порт), а демоны, которые выполняют основную работу могут работать непривелегированным пользователем в изолированном (chroot) окружении, что очень положительно сказывается на безопасности.

В данной статье рассказывается как настроить Postfix. Так же как добавить поддержку POP3 и IMAP, авторизацию, как хранить пользователей в базе данных MySQL. А самое главное — как фильтровать почту от спама и проверять ее на наличие вирусов.

1. Предварительная настройка системы
Для начала отключаем sendmail. Для этого прописываем в /etc/rc.conf следующие строчки:

sendmail_enable="NONE"
mta_start_script=""
sendmail_outbound_enable="NO"
sendmail_submit_enable="NO"
sendmail_msp_queue_enable="NO"

Далее создаем файл /etc/periodic.conf (если он еще не существует) со следующим содержанием:

daily_clean_hoststat_enable="NO"
daily_status_mail_reject_enable="NO"
daily_status_include_submit_mailq="NO"
daily_submit_queuerun="NO"

2. Установка нужных пакетов
Ставим все в следующем порядке:

2.1 MySQL Server 5.0.33
В ней мы храним учетные записи пользователей, транспортные таблицы и алиасы.

# cd /usr/ports/databases/mysql50-server
# make install clean

2.2 Cyrus-Sasl 2.1.22
В ней мы храним учетные записи пользователей, транспортные таблицы и алиасы.

# cd /usr/ports/security/cyrus-sasl2
# make WITHOUT_OTP=yes WITH_MYSQL=/usr/local/lib install clean

2.3 Демон авторизации saslauthd 2.1.22

# cd /usr/ports/security/cyrus-sasl2-saslauthd
# make install clean

Его ставить не обязательно, но у себя я его поставил. Если его ставить, то так же необходимо поставить pam_mysql из портов. Я поставил версию 0.6.2.

2.4 Courier-Imap 4.1.2.1
Исполняет роли POP3 и IMAP сервера.

# cd /usr/ports/mail/courier-imap
# make install clean

В опциях установки выбираем OPENSSL и AUTH_MYSQL.

2.5 Postfix 2.3.7
Это наш МТА.

# cd /usr/ports/mail/postfix
# make install clean

В опциях установки выбираем SASL2, TLS и MYSQL. Где-то в конце установки будет задан ряд вопросов. Везде отвечаем ответами по умолчанию.

# You need user "postfix" added to group "mail".
# Would you like me to add it 
[y]? y # Would you like to activate Postfix in /etc/mail/mailer.conf [n]? n

2.6 ClamAV 0.90
Бесплатный и надежный антивирус.

# cd /usr/ports/sercurity/clamav
# make install clean

В опциях установки я ничего не выбирал.

2.7 ClamSMTP 1.8
С помощью этого порта мы заставим работать в одной упряжке ClamAV и Postfix.

# cd /usr/ports/sercurity/clamsmtp
# make install clean

3 Конфигурирование программ

3.1 Настройка MySQL
Для начала надо настроить MySQL. Как и что делать можно почитать в соответствующей статье. А тут я расскажу уже как создать пользователей и нужные таблицы.
Для начала создаем базу данных mail, а потом уже создаем все необходимые таблицы. Ну и, конечно же, создаем пользователя postfix с ограниченными привилегиями (с возможность только делать запросы SELECT).

mysql> CREATE DATABASE mail;
mysql> CREATE TABLE `alias` (
   `address` varchar(128) NOT NULL default '',
   `goto` varchar(128) NOT NULL default '',
   PRIMARY KEY (`address`)
);

mysql> CREATE TABLE `transport` (
   `domain` varchar(128) NOT NULL default '',
   `transport` varchar(128) NOT NULL default '',
   PRIMARY KEY (`domain`)
);

mysql> CREATE TABLE `users` (
   `username` varchar(128) NOT NULL default '',
   `passwd` varchar(128) NOT NULL default '',
   `domain` varchar(128) NOT NULL default '',
   `email` varchar(128) NOT NULL default '',
   `uid` int(11) unsigned NOT NULL default '1000',
   `gid` int(11) unsigned NOT NULL default '12',
   `maildir` varchar(255) NOT NULL default '/var/mail/virtual/',
   `active` tinyint(4) NOT NULL default '1',
   `quota` int(11) unsigned NOT NULL default '4096000',
   PRIMARY KEY (`username`)
);

mysql> GRANT SELECT ON mail.* TO 'postfix'@'localhost'
   IDENTIFIED BY 'some_pass' WITH GRANT OPTION;

Теперь заполняем все таблицы. Сначала добавляем алиасы для root, postmaster и abuse

mysql> INSERT INTO `alias` (`address`, `goto`) VALUES ('root', '[email protected]');
mysql> INSERT INTO `alias` (`address`, `goto`) VALUES ('postmaster', '[email protected]');
mysql> INSERT INTO `alias` (`address`, `goto`) VALUES ('abuse', '[email protected]');
mysql> INSERT INTO `transport` (`domain`, `transport`) VALUES ('domain.ru', 'virtual');
mysql> INSERT INTO `users` (`username`, `passwd`, `domain`, `email`, `uid`, `gid`, `maildir`, `enabled`, `quota`) VALUES
('admin', 'password', 'domain.ru','[email protected]', 1001, 12, '/var/mail/virtual/admin/', 1, 4096000);

Поле maildir — это местоположение каталога почтового ящика пользователя. В нашем случае, папке /var/mail/virtual надо присвоить права на доступ пользователя postfix и группы maildrop.

# chown postfix:maildrop /var/mail/virtual

Все, на этом настройка mysql закончена. Чтобы облегчить задачу создания, удаления и редактирования таблиц можно, например, использовать phpMyAdmin.

3.2 Настройка Postfix
Будем править файл /usr/local/etc/postfix/main.cf.

queue_directory = /var/spool/postfix
command_directory = /usr/local/sbin
daemon_directory = /usr/local/libexec/postfix
mail_owner = postfix
default_privs = nobody
myhostname = domain.ru
mydomain = domain.ru
myorigin = $mydomain
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
local_recipient_maps = mysql:/usr/local/etc/postfix/maps/local_recipient_maps.cf $alias_maps $virtual_alias_maps
unknown_local_recipient_reject_code = 550
mynetworks_style = host
mynetworks =  192.168.0.0/24, 127.0.0.0/8
transport_maps = mysql:/usr/local/etc/postfix/maps/transport.cf
virtual_mailbox_base = /
virtual_mailbox_maps = mysql:/usr/local/etc/postfix/maps/mailbox.cf
virtual_alias_maps = mysql:/usr/local/etc/postfix/maps/alias.cf
# цифры 125 и 126 - это идентификаторы пользователя postfix и группы maildrop в
# файлах /etc/passwd и /etc/group
virtual_uid_maps = static:125
virtual_gid_maps = static:126
alias_maps = hash:/etc/mail/aliases
alias_database = hash:/etc/mail/aliases
home_mailbox = Maildir/
smtpd_banner = $myhostname mail server
debug_peer_level = 2
debugger_command =
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
xxgdb $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/local/sbin/sendmail
newaliases_path = /usr/local/bin/newaliases
mailq_path = /usr/local/bin/mailq
setgid_group = maildrop
html_directory = no
manpage_directory = /usr/local/man
sample_directory = /usr/local/etc/postfix
readme_directory = no
disable_vrfy_command = yes
smtpd_helo_required = yes
smtpd_sasl_path = smtpd
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_tls_ask_ccert = yes
relay_clientcerts = hash:/usr/local/etc/postfix/maps/fingerprints
smtpd_tls_loglevel = 1
smtpd_tls_recieved_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
smtpd_tls_key_file = /usr/local/etc/mail_ssl/ca/ca.key
smtpd_tls_cert_file = /usr/local/etc/mail_ssl/ca/ca.crt
smtpd_tls_CAfile = /usr/local/etc/mail_ssl/ca/ca.crt
smtpd_sender_login_maps = mysql:/usr/local/etc/postfix/maps/local_recipient_maps.cf
smtpd_helo_restrictions = check_recipient_access hash:/usr/local/etc/postfix/maps/postmaster_access,
                          check_helo_access hash:/usr/local/etc/postfix/maps/helo_access,
                          permit_sasl_authenticated, reject_invalid_hostname, reject_unknown_hostname,
                          reject_non_fqdn_hostname
# эти две строчки мы дописывам, чтобы работал ClamAV
content_filter = scan:127.0.0.1:10025
recieve_override_options = no_address_mappings
# эта строка отвечает за пересылку почты amavisd
# сейчас это ставить необязательно. для этого прочитайте статью выше, где
# рассказывается как настроить антиспам фильтр
content_filter=amavisfeed:[127.0.0.1]:10024
smtpd_sender_restrictions = permit_sasl_authenticated, reject_authenticated_sender_login_mismatch,
                            reject_unknown_sender_domain, reject_unlisted_sender, reject_unverified_sender
smtpd_recipient_restrictions = permit_sasl_authenticated, reject_non_fqdn_hostname, reject_non_fqdn_sender,
                               reject_non_fqdn_recipient, reject_unauth_destination, reject_unauth_pipelining,
                               reject_invalid_hostname, reject_rbl_client opm.blitzed.org, reject_rbl_client
                               list.dsbl.org, reject_rbl_client bl.spamcop.net, reject_rbl_client sbl-xbl.spamhaus.org

После всего этого. Выполняем команды:

# newaliases
# postfix check

Если нет ошибок, то едем дальше — создаем необходимые вспомогательные файлы. Надо обратить внимание на значение host. У меня стоит localhost. Но для этого надо в mysql создать пользователя postfix со значеним host=localhost, а не 127.0.0.1.
/usr/local/etc/postfix/maps/transport.cf:

host = localhost
user = postfix
password = password
dbname = mail
table = transport
select_field = transport
where_field = domain

/usr/local/etc/postfix/maps/mailbox.cf:

host = localhost
user = postfix
password = password
dbname = mail
table = users
select_field = maildir
where_field = email

/usr/local/etc/postfix/maps/alias.cf:

host = localhost
user = postfix
password = password
dbname = mail
table = alias
select_field = goto
where_field = address

/usr/local/etc/postfix/maps/local_recipient_maps.cf:

host = localhost
user = postfix
password = password
dbname = mail
table = users
select_field = email
where_field = username

Не забываем создать файл helo_access и postmaster_access.

/usr/local/etc/postfix/maps/helo_access:

name.domain.ru OK

/usr/local/etc/postfix/maps/postmaster_access:

[email protected]
[email protected]

И:

# postmap helo_access
# postman postmaster_access

Теперь, на всякий случай, делаем еще одну проверку файлов конфигурации postfix и запускаем его.

# postfix check
# postfix start

Далее необходимо законнектиться на 25 порт localhost-а и попробовать послать письмо созданному пользователю. Если все пройдет без ошибок, то в каталоге /var/mail/virtual должен создаться каталог av3nger с папками cur, new и tmp. Если все это появилось, значит postfix настроен правильно и работает. Напоследок, пропишем его в /etc/rc.conf:

postfix_enable="YES"

3.3 Настройка SASL с использованием saslauthd и pam_mysql
Можно почитать /usr/local/share/doc/pam-mysql.
Создаем файл /usr/local/lib/sasl2/smtpd.conf следующего содержания:

pwcheck_method: saslauthd
mech_list: PLAIN LOGIN
minimum_layer: 0

Затем правим файл /etc/pam.d/smtp:

auth required pam_nologin.so
auth required pam_mysql.so user=postfix passwd=password host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=passwd
account required pam_mysql.so user=postfix passwd=password host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=passwd
password required pam_mysql.so user=postfix passwd=password host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=passwd

И в заключении пропишем автоматический запуск демона в /etc/rc.conf. Флаг -a pam необходим при любой авторизации посредством pam. Флаг -r нужен для того, чтобы при авторизации не обрубался конец логина (@domain.ru — вот эта часть).

saslauthd_enable="YES"
saslauthd_flags="-a pam -r"

Говорят, что можно настроить систему без всякой это хрени. Я пробовал, действительно можно. Но а нужно? На всякий случай, вот как должен выглядеть файл /usr/local/lib/sasl2/smtpd.conf, если надо настроить SASL без ипользования демона saslauthd:

pwcheck_method: auxprop
mech_list: PLAIN LOGIN
auxprop_plugin: sql
sql_engine: mysql
sql_user: postfix
sql_hostnames: localhost
sql_passwd: password
sql_database: mail
sql_select: SELECT passwd FROM users WHERE username='%u' AND domain='%r' AND active='1';

3.4 Настройка Courier-Imap
Для настройки Courier-Imap надо сначала отредактировать файл /usr/local/etc/authlib/authdaemonrc. Правим в нем следующий параметр:

authmodulelist="authmysql"

После этого открываем файл /usr/local/etc/authlib/authmysqlrc. Содержание файлы должно быть примерно таким:

MYSQL_SERVER localhost
MYSQL_USERNAME           postfix
MYSQL_PASSWORD          password
MYSQL_PORT                  3306
MYSQL_OPT                   0
MYSQL_DATABASE           mail
MYSQL_USER_TABLE        users
MYSQL_CLEAR_PWFIELD   passwd
DEFAULT_DOMAIN           domain.ru
MYSQL_UID_FIELD          125
MYSQL_GID_FIELD          126
MYSQL_LOGIN_FIELD       email
MYSQL_HOME_FIELD       maildir
MYSQL_MAILDIR_FIELD    maildir
MYSQL_WHERE_CLAUSE   active=1

Можно запускать Courier. Но, как обычно, пропишем его в /etc/rc.conf:

courier_authdaemond_enable="YES"
courier_pop3d_enable="YES"
courier_imapd_enable="YES"

3.5 Настройка ClamAV
Пришло время для антивируса. Сначала пропишем все в /etc/rc.conf:

clamav_clamd_enable="YES"
clamav_freshclam_enable="YES"
clamsmtpd_enable="YES"

Все это отвечает за запуск демона антивируса, скрипт автоматического обновление баз данных и демона, с помощью которого антивирус будет вызываться postifx-ом при получении каждого письма.
Далее открываем файл /usr/local/etc/clamd.conf и приводим его к такому виду:

LogFile /var/log/clamav/clamd.log
LogTime yes
LogSyslog yes
LogVerbose yes
PidFile /var/run/clamav/clamd.pid
TemporaryDirectory /tmp
DatabaseDirectory /var/db/clamav
LocalSocket /var/run/clamav/clamd
FixStaleSocket yes
User clamav
AllowSupplementaryGroups yes
ScanArchive yes

Затем правим файл /usr/local/etc/freshclam.conf:

DatabaseDirectory /var/db/clamav
UpdateLogFile /var/log/clamav/freshclam.log
LogVerbose yes
LogSyslog yes
PidFile /var/run/clamav/freshclam.pid
DatabaseOwner clamav
AllowSupplementaryGroups yes
DNSDatabaseInfo current.cvd.clamav.net
DatabaseMirror database.clamav.net
NotifyClamd /usr/local/etc/clamd.conf

И файл /usr/local/etc/clamsmtpd.conf:

OutAddress: 10026
ClamAddress: /var/run/clamav/clamd
Header: X-Virus-Scanned: ClamAV using ClamSMTP
TempDirectory: /tmp
User: clamav

Чтобы postfix мог использовать данный антивирус, необходимо дописать в файл /usr/local/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

Перезапускаем Postfix, ClamAV, FreshClam и ClamSMTP. Антивирус настроен и работает.