В рамках программы по унификации установленных серверных систем встала задача по переделке почтового сервера. Вдумчивое изучение мануалов и руководств показало довольно любопытный факт – нигде не было найдено однозначно достоверного руководства или подобия Best Practice по развёртыванию почтовика.
Мануал пошаговый, основывается на внутренней документации компании и затрагивает совершенно очевидные вопросы. Гуру могут не тратить время, ноу-хау здесь нет – руководство является сборной солянкой и публикуется только потому, что все найденные руководства по развёртыванию почтовика напоминали картинку о том, как рисовать сову.
Для тех, кто не хочет собирать всё вручную, оптимальным вариантом, пожалуй, будет пакет iRedMail. Отличная сборка Postfix, Dovecot, Apache, MySQL/PostgreSQL, Policyd, Amavis, Fail2ban, Roundcube и даже Awstats. Ставится легко, работает стабильно, есть красивая админка (бесплатная) и очень красивая админка (платная) не идущая ни в какое сравнение с убогим PostfixAdmin. Поклонники же ручного труда могут продолжить чтение.
Старый сервер работал под Gentoo и нёс в себе термоядерный заряд из Postfix+VDA с Courier и глючно реализованного SASL, решавшим подключаться к mysql только при первой аутентификации. План переделки заключался в миграции на наш внутренний стандарт – CentOS. Роль MTA и MDA возлагается на связку Postfix и Dovecot, а в качестве вспомогательной артиллерии: Amavis + SpamAssassin + ClamAV + Postgrey + Fail2Ban. Письма хранятся в файлах, а учётные записи и домены — в MySQL. На сервере крутится несколько почтовых доменов и есть поддержка виртуальных квот.
[*] Подключаем дополнительные репозитории. Мне хватило epel, rpmforge, centalt и remi. Не все они нужны постоянно включёнными, и можно установить плагин yum-priorities; ну или если лень разбираться, то включать-отключать их руками. Далее я буду говорить, что из какого репозитория устанавливается.
[*] Работа с SELinux достойна отдельного материала, поэтому в рамках данной статьи примем, что selinux по-ламерски сделан permissive или disabled.
[*] Не забываем про ntp:
yum install ntp
ntpdate <ваш ntp сервер>
chkconfig ntpd on && /etc/init.d/ntpd start
Это позволит избежать возможной проблемы Dovecot’a «Time has moved backwards». Также можно в /etc/sysconfig/ntpd изменить ключ на -L, чтобы ntpd не слушал сеть.
[*] В завершение подготовительного этапа ставим утилиты, которые облегчат нам тестирование и дальнейшую работу:
yum install wget mlocate bind-utils telnet mailx sharutils
Для нашей базы данных используем MySQL 5.5 от Remi. Можно и mariadb, конечно, но пока MySQL ещё жив, вышеупомянутая сборка меня полностью устраивает. Версия важна, т.к. при обновлении Postfix до 2.10 он захочет новую версию и если поставить 5.1 из base, то обновление постфикса из CentALT потянет за собой MariaDB. Кому больше нравится PgSQL — пожалуйста, ставьте его. Развёртывание ничем отличаться не будет, даже конфигурационные файлы postfix можно будет брать неизменными. Отличаться будет только настройка самого postgresql и создание базы.
Для запуска подойдёт вариант «из коробки» (в репозитории ниже представлен слегка расширенный my.cnf). Создаём пользователя postfix с одноимённой базой и всеми правами на неё.
CREATE USER postfix@localhost IDENTIFIED BY 'mypassword';
CREATE DATABASE postfix;
GRANT ALL PRIVILEGES ON postfix.* TO postfix;
Антивирусом у меня работает ClamAV. Стоит отметить, что самая последняя версия есть на CentALT, однако она в упор не хочет оттуда скачиваться, умирая на попытке скачать 50 мегабайт clamav-db. Поэтому ставим из EPEL на пару минорных версий меньше, погоды это не сделает. Clam будет работать у нас через сокет, поэтому в /etc/clamd.conf комментируем строки:
#TCPSocket 3310
#TCPAddr 127.0.0.1
Обновление баз антивируса подключается автоматически, за него отвечает утилита freshclam. Проконтролируем, чтобы соответствующий файл находился в cron.daily и запускаем сервис антивируса
freshclam
chkconfig clamd on && /etc/init.d/clamd start
Развёртывать или не развёртывать веб-интерфейс — личное дело каждого. Мне он понадобился для контроля процесса миграции. Вам он может понадобиться для создания структуры базы и администрирования доменов, ящиков, алиасов и т.п. Для последних задач в большинстве руководств активно предлагается PostfixAdmin, но мне он категорически не нравится. Равно как я бы рекомендовал придерживаться принципа разделения, по которому почтовый сервер должен заниматься обработкой почты, веб-сервер держать веб-приложения, а DB-сервер работать с базами данных.
Для тех, кто не захочет развёртывать веб-подсистему, прилагаю SQL-дамп базы данных для почтового сервера на все случаи жизни. Даже с некоторыми неиспользуемыми возможностями: mysql_dump.sql на гитхабе.
Если же потребуется PostfixAdmin — ставьте nginx/apache + php и собственно сам PostfixAdmin. И обратите внимание, что развернуть его поверх приведённого дампа не удастся — из структуры удалены некоторые «лишние» таблицы. Нюансов настройки PostfixAdmin немного. Редактируем config.inc.php, обращая внимание на следующие параметры:
## должен содержать тот же метод хэширования пароля, что и dovecot
$CONF['encrypt'] = 'md5crypt';
$CONF['transport_default'] = 'virtual';
$CONF['emailcheck_resolve_domain']='NO';
## Поскольку будет использоваться dovecot, убираем префикс
$CONF['create_mailbox_subdirs_prefix']='';
## На случай, если захочется использовать хранение квот не в maildir, а в базе данных через dict
$CONF['new_quota_table'] = 'yes';
После этого можно идти на domain.tld/postfixadmin/setup.php, генерировать пароль и создавать учётную запись супер-администратора. Теперь сгенерированный хэш надо внести в файл config.inc.php и изменить его статус:
$CONF['configured'] = true;
$CONF['setup_password'] = 't8h9i9s2i7s7m2y4l9o8g9i4n:a0n9d5p2a5s2s9w5o4r7d';
[!] Postfixadmin сам создаёт структуру базы и в mysql, и в postgresql при запуске setup.php. Если намереваетесь использовать его, установку следует проводить на пустую базу.
Проконтролируем, что в базе postfix создана вся дефолтная структура и перейдём к установке MTA и MDA. Postfix уже идёт в комплекте с CentOS, но не самый новый. Обновим его из CentALT и оттуда же поставим Dovecot.
yum update postfix
yum install dovecot dovecot-mysql
Все основные системы корабля будут оперировать с файлами в /var/vmail под отдельным юзверем:
groupadd -g 1000 vmail
useradd -d /var/vmail/ -g 1000 -u 1000 vmail
chown vmail:vmail /var/vmail
Сделаем самоподписанные SSL'ки
mkdir /etc/postfix/certs
openssl req -new -x509 -days 3650 -nodes -out /etc/postfix/certs/cert.pem -keyout /etc/postfix/certs/key.pem
Самый противный этап сборки – убедить Postfix работать с базой данных:
mkdir /etc/postfix/mysql
В этой директории создаём файлы со следующим содержанием:
hosts = localhost
user = postfix
password = mypassword
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '1'
virtual_alias_domain_maps.cf
hosts = localhost
user = postfix
password = mypassword
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1
virtual_alias_maps.cf
hosts = localhost
user = postfix
password = mypassword
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
virtual_mailbox_domains.cf
hosts = localhost
user = postfix
password = mypassword
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'
virtual_mailbox_maps.cf
hosts = localhost
user = postfix
password = mypassword
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
Редактируем файл /etc/postfix/main.cf, обучая Postfix работать с базой по свежесозданным файлам:
# ============================================================
# MySQL mappings
# ============================================================
relay_domains = mysql:/etc/postfix/mysql/relay_domains.cf
virtual_alias_maps = mysql:/etc/postfix/mysql/virtual_alias_maps.cf,
mysql:/etc/postfix/mysql/virtual_alias_domain_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql/virtual_mailbox_domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql/virtual_mailbox_maps.cf
Хороший почтовый сервер пропускает своих и авторизует чужих. Чтобы аутентификация работала корректно, запустим Submission, подняв SMTP сервис дополнительно на 587 порту. Смартфоны при создании новых учётных записей при вписывании smtp сервера с аутентификацией по умолчанию предлагают 587 порт; вы же не хотите объяснять клиентам, что недостаточно вписать mail.domain.tld, а ещё надо и порты какие-то прописывать. В общем, в /etc/postfix/master.cf редактируем секцию, отвечающую за submission:
submission inet n - n - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_wrappermode=no
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
-o smtpd_relay_restrictions=permit_mynetworks,permit_sasl_authenticated,defer_unauth_destination
-o milter_macro_daemon_name=ORIGINATING
[!] Обязательно обращаем внимание на пробелы перед -o ключами — без них конфиг не будет валидным.
Пока отложим в сторону master.cf, к нему мы вернёмся позднее, и продолжим с /etc/postfix/main.cf
soft_bounce = no
myhostname = mail.domain.tld
mydomain = domain.tld
myorigin = $myhostname
# Убираем $myhostname и $mydomain из локального класа
# Чтобы не было do not list domain in BOTH mydestination and virtual_mailbox_domains
mydestination = localhost.$mydomain, localhost
## Вписываем свои сетки
mynetworks = 192.168.0.0/16, 127.0.0.0/8
## Убираем nis:/ чтобы избежать спама в лог
## dict_nis_init: NIS domain name not set - NIS lookups disabled
alias_maps = hash:/etc/aliases
smtpd_banner = $myhostname ESMTP $mail_name
debug_peer_level = 2
debug_peer_list = 127.0.0.1
Это были изменения строк по умолчанию. А теперь добавим несколько секций наших настроек. Проверьте на дубликаты, убирая их из родной конфигурации, если они там встречаются. Я предлагаю свои настройки вписывать структурированными блоками в нижней части файла /etc/postfix/main.cf:
# ============================================================
# RESTRICTIONS
#
# Uncomment reject_rbl_client if necessary
# More information at: http://help.ubuntu.ru/wiki/фильтрация_спама_на_уровне_smtp_протокола
# ============================================================
smtpd_discard_ehlo_keywords = etrn, silent-discard
smtpd_forbidden_commands = CONNECT GET POST
broken_sasl_auth_clients = yes
smtpd_delay_reject = yes
smtpd_helo_required = yes
disable_vrfy_command = yes
smtpd_helo_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_non_fqdn_helo_hostname,
reject_invalid_helo_hostname,
permit
smtpd_data_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_pipelining,
reject_multi_recipient_bounce,
permit
smtpd_sender_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_non_fqdn_sender,
reject_unknown_sender_domain,
permit
smtpd_recipient_restrictions = reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
reject_multi_recipient_bounce,
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:/var/spool/postfix/postgrey/socket,
reject_invalid_hostname,
#reject_rbl_client zen.spamhaus.org,
#reject_rbl_client bl.spamcop.net,
#reject_rbl_client dnsbl.sorbs.net,
permit
# ============================================================
# TLS
# ============================================================
smtp_tls_security_level = may
smtpd_tls_security_level = may
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
smtp_tls_session_cache_database = btree:$data_directory/smtp_tls_session_cache
smtpd_tls_key_file = /etc/postfix/certs/key.pem
smtpd_tls_cert_file = /etc/postfix/certs/cert.pem
tls_random_source = dev:/dev/urandom
# ============================================================
# LIMITS
# ============================================================
message_size_limit = 51200000
smtpd_soft_error_limit = 10
smtpd_hard_error_limit = 15
smtpd_error_sleep_time = 20
anvil_rate_time_unit = 60s
smtpd_client_connection_count_limit = 20
smtpd_client_connection_rate_limit = 30
smtpd_client_message_rate_limit = 30
smtpd_client_event_limit_exceptions = 127.0.0.1/8
smtpd_client_connection_limit_exceptions = 127.0.0.1/8
# ============================================================
# QUEUE
# ============================================================
maximal_queue_lifetime = 1d
bounce_queue_lifetime = 1d
[!] Использовать или не использовать чёрные списки — ваш выбор. Я закомментировал соответствующие директивы reject_rbl_client, чтобы не плодить холивары. Грейлистинга зачастую хватает, а Spamhaus и иже с ним исповедуют неоднозначную политику, но на практике оказалось, что «честных ребят», в чёрные списки просто так не заносит и ложных срабатываний у нас не было. Повезло, наверное. Поэтому — дело вкуса включать директивы RBL или нет. Считайте, что я их указал в информационных целях.
[!] Параметры разбиты по группам — внимательно пересмотрите их и подстройте под собственные нужды. Хуже нет варианта, чем вслепую влепить чужой конфиг без правок.
[!] К файлу main.cf мы снова вернёмся, добавляя в него postgrey, amavis и dovecot, а пока перейдем к MDA
Что это такое:
- Это наш Mail Delivery Agent, локальный транспорт
- Собственный SASL, через который будет работать Postfix
- Работа с квотами
- Предоставление пользователю imap и pop3
Пара изменений в /etc/dovecot/dovecot.conf:
protocols = imap pop3
login_greeting = Hello there.
Остальная часть конфигурационного файла удобно разбита на составляющие и прекрасно документирована:
disable_plaintext_auth = no
auth_realms = domain.tld domain2.tld
auth_default_realm = domain.tld
auth_mechanisms = plain login
## [!] Комментируем auth-system.conf.ext, чтобы не
## заставлять dovecot искать пользователя в pam
#!include auth-system.conf.ext
mail_uid = 1000
mail_gid = 1000
mail_plugins = quota
# Поднимаем imap и imaps
service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
}
# Поднимаем pop3 и pop3s
service pop3-login {
inet_listener pop3 {
port = 110
}
inet_listener pop3s {
port = 995
ssl = yes
}
}
# Поднимаем SASL, куда будет ходить postfix
service auth {
unix_listener auth-userdb {
mode = 0600
user = vmail
group = vmail
}
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user=postfix
group=postfix
}
}
ssl_cert = </etc/postfix/certs/cert.pem
ssl_key = </etc/postfix/certs/key.pem
lda_mailbox_autocreate = yes
lda_mailbox_autosubscribe = yes
protocol lda {
mail_plugins = $mail_plugins autocreate
}
mail_plugins = $mail_plugins autocreate quota imap_quota
}
# Данные для вас могут отличаться.
# Такие папки создавались для безболезненной миграции со старой системы
plugin {
autocreate = Trash
autocreate2 = sent-mail
autocreate3 = drafts
autosubscribe = Trash
autosubscribe2 = sent-mail
autosubscribe3 = drafts
}
# Отредактируйте значения в соответствии с собственными нуждами.
plugin {
quota_rule = *:storage=200M
quota_rule2 = Trash:storage=+10M
}
plugin {
quota_warning = storage=90%% quota-warning 90 %u
}
# Проверьте, чтобы у скрипта был нужный chmod
# Плюс чтобы в quota-warning.sh был указан корректный путь до dovecot-lda
service quota-warning {
executable = script /usr/local/bin/quota-warning.sh
user = vmail
unix_listener quota-warning {
user = vmail
}
}
# Формат хранения квоты - maildir
# При желании можно менять на dict, fs или dirsize
# Подробная документация в http://wiki2.dovecot.org/Quota
plugin {
quota = maildir:User quota
}
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
Создаём /etc/dovecot/dovecot-sql.conf.ext:
connect = host=localhost dbname=postfix user=postfix password=mypassword
default_pass_scheme = MD5-CRYPT
user_query = SELECT '/var/vmail/%d/%n' as home, 'maildir:/var/vmail/%d/%n'as mail, 1000 AS uid, 1000 AS gid, concat('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active = '1'
password_query = SELECT username as user, password, '/var/vmail/%d/%n' as userdb_home, 'maildir:/var/vmail/%d/%n' as userdb_mail, 1000 as userdb_uid, 1000 as userdb_gid, concat('*:bytes=', quota) AS userdb_quota_rule FROM mailbox WHER
E username = '%u' AND active = '1'
Теперь подружим Postfix с Dovecot. Добавим две секции в /etc/postfix/main.cf:
# ============================================================
# SASL
# ============================================================
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
# ============================================================
# VIRTUAL
# ============================================================
virtual_mailbox_base = /var/vmail
virtual_minimum_uid = 1000
virtual_uid_maps = static:1000
virtual_gid_maps = static:1000
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
И поставим Postfix перед фактом, что доставкой почты занимается dovecot. В /etc/postfix/master.cf:
# ====================================================================
# DOVECOT
# ====================================================================
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}
Далее необходимо проконтролировать, чтобы скрипт предупреждения о превышении квоты /usr/local/bin/quota-warning.sh отрабатывал корректно. В моём случае в CentOS путь в нём был указан неверно и пришлось править его вручную. Его в любом случае, кстати, поправить вручную, отредактировав адрес отправителя, который по умолчанию указан, как postmaster@domain.tld. Найдём искомый бинарник
updatedb
locate dovecot-lda
chmod 755 /usr/local/bin/quota-warning.sh
И поправим путь в самом /usr/local/bin/quota-warning.sh, при желании добавляя в скрипт более содержательные заголовки.
Поскольку у нас будет работать Amavis, который является прослойкой между почтовыми агентами и антивирусно-антиспамовыми системами, то запускать spamd отдельно не нужно – он работает как модуль, подгружающийся при необходимости. Чтобы SA держать обновлённым, используется родная утилита sa-update. Убедимся, что в etc/cron.d есть файлик sa-update с запланированным запуском апдейтера.
[!] Ставьте spamassassin 3.3.2 из rpmforge-extras, т.к. втыкающаяся из EPEL версия 3.3.1 имеет врождённый дефект в sa-update. Последняя версия 3.3.2 уже избавлена от этой проблемы и обновляется корректно
yum install spamassassin amavisd-new
Немного подкорректируем /etc/mail/spamassassin/local.cf
required_hits 6
report_safe 0
rewrite_header Subject ***SPAM***
#
# WEIRD STUFF
#
score FORGED_MUA_OUTLOOK 2.199 2.199 0.963 1.116
score FH_DATE_PAST_20XX 0.0
score DOS_OE_TO_MX_IMAGE 0.0
score DOS_OE_TO_MX 0.0
score DOS_OUTLOOK_TO_MX 0.0
score TO_NO_BRKTS_DIRECT 0.0
score HELO_LOCALHOST 0.0
score FSL_RU_URL 0.0
score FROM_MISSP_EH_MATCH 1.0
score TVD_RCVD_SINGLE 1.0
score TO_IN_SUBJ 1.0
#
# TUNING
#
score SUBJ_FULL_OF_8BITS 0.00
score HTML_COMMENT_8BITS 0.01
score HEADER_8BITS 0.00
score TO_NO_USER 0.01
score FORGED_MUA_OUTLOOK 0.5
score X_AUTH_WARNING 0.01
score SUBJ_HAS_UNIQ_ID 9.99
score HTTP_USERNAME_USED 9.99
score FORGED_YAHOO_RCVD 9.99
score FORGED_JUNO_RCVD 16
score UNWANTED_LANGUAGE_BODY 1.02
score MLM 5.55
score RCVD_NUMERIC_HELO 4.95
#
# WHITE/BLACK LISTS
#
whitelist_from root@localhost
whitelist_from *@example.com
blacklist_from *@outblaze.com
auto_whitelist_path /etc/mail/spamassassin/auto-whitelist
auto_whitelist_file_mode 0666
А вот конфигурационный файл Amavis'а — полная противоположность расхваливаемым мною конфигам Dovecot. Он представляет собой обычный perl скрипт, который к тому же ещё и плохо форматирован. Я вношу изменения просто — переименовываю файл в .pl и редактирую с подсветкой синтаксиса; это хоть немного облегчает жизнь.
# количество экземпляров amavisd
# должно совпадать с указанным в /etc/postfix/master.cf
$max_servers = 4;
# Домен по умолчанию
$mydomain = 'domain.tld';
# Правим доверенные подсетки
@mynetworks = qw( 127.0.0.0/8 [::1] [FE80::]/10 [FEC0::]/10
10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 );
# Твик для 2.6.4 и старше. Избавляемся от предупреждения в логе
# Open relay? Nonlocal recips but not originating
@client_ipaddr_policy = map { $_ => 'MYNETS' } @mynetworks;
# Переписываем пороговые значения для spamassassin
$sa_tag_level_deflt = 2.0;
$sa_tag2_level_deflt = 5.2;
$sa_kill_level_deflt = 6.5;
$sa_dsn_cutoff_level = 10;
# Куда будут отправляться уведомления о письмах с вирусами и спамом
$virus_admin = "virusalert@$mydomain";
$mailfrom_notify_admin = "virusalert@$mydomain";
$mailfrom_notify_recip = "virusalert@$mydomain";
$mailfrom_notify_spamadmin = "abuse@$mydomain";
# Обязательно указываем имя хоста сервера
$myhostname = 'mail.domain.tld';
# Что делать при срабатывании
$final_virus_destiny = D_DISCARD;
$final_banned_destiny = D_BOUNCE;
$final_spam_destiny = D_DISCARD;
$final_bad_header_destiny = D_PASS;
# Если будем использовать карантин, то указываем куда карантинить
# Разумеется, соответствующие почтовые ящики должны существовать
$virus_quarantine_to = "virus-quarantine@$mydomain";
$spam_quarantine_to = "spamtrap@$mydomain";
# Если надо какие-то адреса или домены внести в белый список
# создаём массив
@whitelist_sender_maps = ( new_RE(
qr'.*@example.com$'i,
qr'user@test.org$'i,
));
# Весь массив @av_scanners сокращаем до
@av_scanners = (
['ClamAV-clamd',
&ask_daemon, ["CONTSCAN {}n", "/var/run/clamav/clamd.sock"],
qr/bOK$/m, qr/bFOUND$/m,
qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],
);
);
# И второй тоже
@av_scanners_backup = (
['ClamAV-clamscan', 'clamscan',
"--stdout --no-summary -r --tempdir=$TEMPBASE {}",
[0], qr/:.*sFOUND$/m, qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],
);
Теперь сообщим Postfix'у, что отныне он использует Amavis для проверки почты. Вносим соответствующий блок в /etc/postfix/master.cf
# ====================================================================
# AMAVIS
# ====================================================================
amavisfeed unix - - n - 4 lmtp
-o lmtp_data_done_timeout=1200
-o lmtp_send_xforward_command=yes
-o disable_dns_lookups=yes
-o max_use=20
127.0.0.1:10025 inet n - n - - smtpd
-o content_filter=
-o smtpd_delay_reject=no
-o smtpd_client_restrictions=permit_mynetworks,reject
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o smtpd_data_restrictions=reject_unauth_pipelining
-o smtpd_end_of_data_restrictions=
-o smtpd_restriction_classes=
-o mynetworks=127.0.0.0/8,192.168.0.0/16
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000
-o smtpd_client_connection_count_limit=0
-o smtpd_client_connection_rate_limit=0
-o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters,no_address_mappings
-o local_header_rewrite_clients=
-o smtpd_milters=
-o local_recipient_maps=
-o relay_recipient_maps=
и в /etc/postfix/main.cf добавляем
# ============================================================
# AMAVIS
# ============================================================
content_filter=amavisfeed:[127.0.0.1]:10024
Отрабатываем сервисы:
chkconfig amavisd on && /etc/init.d/amavisd start
/etc/init.d/postfix restart
telnet 127.0.0.1 10024
# 220 [127.0.0.1] ESMTP amavisd-new service ready
Об эффективности грейлистинга писалось уже не раз, поэтому просто молча
yum install postgrey
Никакой дополнительной конфигурации не требуется — прописываем его в /etc/postfix/main.cf
smtpd_recipient_restrictions = ...
reject_unauth_destination,
check_policy_service unix:/var/spool/postfix/postgrey/socket,
...
[!] Директива check_policy_service должна обязательно идти после reject_unauth_destination.
Если есть необходимость исключить из проверки какие-либо сервера — редактируем /etc/postfix/postgrey_whitelist_clients.local, а для исключения из проверки конкретные почтовые адреса на локальном сервере — редактируем postgrey_whitelist_recipients. Исчерпывающая информация доступна в вики: wiki.centos.org/HowTos/postgrey
Про Fail2ban разговор отдельный. Чтобы продемонстрировать его эффективность, покажу картинку со статистикой почтового сервера до и после установки утилиты. Красная линия на графике – неавторизованная долбёжка в поисках открытого релея. Письма, конечно, отсекаются, да и нагрузку большую не создают, но зачем вообще слушать этот мусор. Поэтому установка fail2ban с двумя правилами: для smtp и для защиты от перебора pop3 значительно улучшают внешний вид графика:
yum install fail2ban
# Тут оставляем и редактируем общие
# правила, игнорируемые подсетки
# и политику партии
##
## Убедитесь, что путь к логам соответствует действительности
##
[ssh-iptables]
enabled = true
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
logpath = /var/log/secure
maxretry = 5
[postfix-banhammer]
enabled = true
filter = postfix
action = iptables-multiport-tcp[name=PFIX, port="smtp,smtps", protocol=tcp]
logpath = /var/log/maillog
maxretry = 3
bantime = 7200
[dovecot-banhammer]
enabled = true
filter = dovecot
action = iptables-multiport-tcp[name=DCOT, port="pop3,pop3s,imap,imaps", protocol=tcp]
logpath = /var/log/maillog
findtime = 300
maxretry = 10
bantime = 1800
Если SSH открыт только на внутреннюю сеть, то первое правило можно и убрать. И всё, никаких дополнительных телодвижений – правила работают «из коробки».
chkconfig fail2ban on && /etc/init.d/fail2ban start
Поскольку в Dovecot мы подключили плагин autocreate, то для создания доменов и почтовых ящиков достаточно завести их в базу через Postfixadmin или делая INSERT INTO в консоли. При первой же аутентификации или первом полученном письме структура директорий будет создана автоматически.
- Тестируем логин POP3
telnet 127.0.0.1 110 user test pass testpassword UIDL
- Тестируем логин IMAP
telnet 127.0.0.1 143 1 LOGIN test testpassword 1 SELECT INBOX
- Тестируем SMTP без авторизации
telnet 127.0.0.1 25 #220 mail.domain.tld ESMTP Postfix helo darling #250 mail.domain.tld MAIL FROM: root@localhost #250 2.1.0 Ok RCPT TO: test@example.com #250 2.1.5 Ok DATA #354 End data with <CR><LF>.<CR><LF> this is text message . #250 2.0.0 Ok: queued as E3BA1A15FA quit #221 2.0.0 Bye
- Тестируем SMTP c авторизацией без SSL
Предварительно закодируйте в base64 тестовые логин и пароль, которые посылаются последовательно после AUTH LOGIN. Входящие требования с кодом 334 тоже закодированы в base64.telnet 127.0.0.1 25 #220 mail.domain.tld ESMTP Postfix ehlo darling #250-mail2.dautkom.lv #250-PIPELINING #250-SIZE 51200000 #250-STARTTLS #250-AUTH PLAIN LOGIN #250-AUTH=PLAIN LOGIN #250-ENHANCEDSTATUSCODES #250-8BITMIME #250 DSN AUTH LOGIN #334 VXNlcm5hbWU6 dGVzdA== #334 UGFzc3dvcmQ6 dGVzdHBhc3N3b3Jk #235 2.7.0 Authentication successful
- Тестируем SMTP c SSL
# Зашифруем наши credentials perl -MMIME::Base64 -e 'print encode_base64("00test@example.com00testpassword")' # Получаем строку # AHRlc3RAZXhhbXBsZS5jb20AdGVzdHBhc3N3b3Jk openssl s_client -starttls smtp -connect 127.0.0.1:587 -crlf -ign_eof # Обмен приветствиям # На полтора экрана текста EHLO darling #250-mail.example.com #250-PIPELINING #250-SIZE 51200000 #250-ENHANCEDSTATUSCODES #250-8BITMIME #250 DSN AUTH PLAIN AHRlc3RAZXhhbXBsZS5jb20AdGVzdHBhc3N3b3Jk #235 2.7.0 Authentication successful
- В комплекте с amavis идут вирусы и спам. Тестовые, разумеется. И чтобы сканеры не паниковали, они лежат запакованные. Поэтому перед дальнейшими тестами распакуем эту радость:
cd /usr/share/doc/amavisd-new-2.8.0/test-messages perl -pe 's/./chr(ord($&)^255)/sge' <sample.tar.gz.compl | zcat | tar xvf -
- Теперь можно тестировать отправку вирусов и спама:
sendmail -i your-address@example.com < sample-virus-simple.txt sendmail -i your-address@example.com < sample-spam-GTUBE-junk.txt
Информацию по обработке можно читать в логах (по умолчанию /var/log/maillog). Чтобы увидеть больше информации, поднимите уровень verbose в /etc/dovecot/conf.d/10-logging.conf и log-level в /etc/amavisd/amavisd.conf.
Теперь питание компьютера можно отключить можно начинать работать с почтовым сервером, создавать домены, пользователей, алиасы и т.п. Напоследок несколько общих моментов и рекомендаций:
- Для работы с конфигурационными файлами я использую git, превратив директорию /etc в репозиторий. Такой подход позволяет удобно шарить конфиги между сотрудниками техотдела и пошагово контролировать процесс настройки. В работе с такой комплексной системой, как почтовый сервер, подобная практика может сильно облегчить жизнь.
- Одной из моих задач была миграция c courier на dovecot. И да, это реально. Официальная документация wiki2.dovecot.org/Migration/Courier даёт почти всю необходимую информацию. В дополнение к ней порекомендую вручную выполнить POP3 команду UIDL на старом и новом сервере под одним и тем же пользователем с непустым почтовым ящиком, сравнивая результаты. Они должны быть одинаковыми, иначе почтовый клиент пользователя скачает всю почту из ящика заново.
Также можно по окончании миграции на новом сервере удалить ненужные папки и файлыfind . -name "courier*" -delete
- Не забудьте про iptables — откройте только нужные порты и скройте от любопытных глаз служебные.
- Идущий в комплекте с CentOS логгер rsyslog мне никогда не нравился, и я его меняю на syslog-ng из EPEL. Кстати, при непосредственном участии syslog-ng рисуется график из шестой главы — сбор и запись статистики ведётся путём парсинга логов.
- Таблица vacation создаётся, но в dovecot не поставлен плагин Sieve и «автоответчика» нет. Поэтому таблица — просто задел «на будущее». Гайд и так гигантский получился.
Почти полную сборку конфигурационных файлов я выложил на гитхаб, чтобы при необходимости можно было получить доступ к конфигурационным файлам не по кусочкам, а целиком. В этой статье файлы редактировались постепенно, имитируя такую же постепенную настройку всех систем. В подавляющем большинстве руководств файлы давались сразу и у читателя не получалось составить представление что за чем идёт и как связывается. Я постарался от этого избавиться, показывая поэтапность настройки. Авось, кому-то да пригодится.
Ещё раз подчеркну, что это начальный этап установки. Даже если не считать подключение мониторинга, который крайне желателен на почтовом сервере, работы ещё непочатый край. Однозначно потребуется тщательная настройка антиспам политики; если планируется использовать дополнительные релеи, то потребуется доработка запросов; обязательно будет нужно выверять параметры ограничений и т.п.
Но в остальном на этом пробу пера в написании масштабного руководства можно считать завершённой. В планах есть публикация материала уже не для «начинающих» и не по почтовому серверу, но я решил потренироваться на кошках. Кто дочитал до этого места… гм… завидую вашему терпению, но разбивать публикацию на несколько частей представлялось нецелесообразным.
Автор: Hesed