2008/05/02

Mailhub-сервер на базе Exim

Второй раз столкнулся с задачей конфигурирования основного mx-сервера и так уж получилось, что это вновь оказался Exim (дистрибутив Debian Etch 4.0r3). Решил уже всё дотошно описать, чтобы впоследствии можно было с легкостью восстановить требуемую конфигурацию. Данное описание содержит комментарии только к внесенным мною изменениям, стандартные конфигурационные параметры я не описываю и не указываю.

В моей конфигурации основной mx-сервер выступает в роли "привратника", который принимает из Internet всю почту и рассылает далее по внутренним smtp-серверам, поэтому упор делается на отброс нежелательной корреспонденции (spam'a).
Комментарии приветствуются :)

Основной конфигурационный файл Exim для "пересборки" выглядит примерно так:
# cat /etc/exim4/update-exim4.conf
dc_eximconfig_configtype='internet'
dc_other_hostnames='mail.mycompany.com'
dc_local_interfaces=''
dc_readhost=''
dc_relay_domains='mycompany.com:mycompany.eu:mycompany.net'
dc_minimaldns='false'
dc_relay_nets=''
dc_smarthost=''
CFILEMODE='644'
dc_use_split_config='true'
dc_hide_mailname=''
dc_mailname_in_oh='true'
dc_localdelivery='mail_spool'
Для удобства внесения изменений в конфигурацию я использую мини-скрипт rebuild
cat > /etc/exim4/rebuild
#!/bin/bash
update-exim4.conf
/etc/init.d/exim4 restart
[Ctrl+d]
chmod +x /etc/exim4/rebuild
В базовой комплектации Debian Exim идёт в "лёгкой" сборке, но для того, чтобы использовать возможность фильтровать вирусы с помощью ClamAv необходим heavy-пакет.
# apt-get install exim4-daemon-heavy
Антивирус прикручивается к Exim'у просто, но для его установки следут использовать volatile-репозитарий. Перед установкой пакета clamav-daemon, следует добавить в /etc/apt/sources.list соответствующую строку и обновить apt-get.
# cat >> /etc/apt/sources.list
deb http://volatile.debian.org/debian-volatile etch/volatile main contrib non-free
[Ctrl+d]
# apt-get update
# apt-get install clamav-daemon
Чтобы clamav-пользователь имел возможность читать и писать в каталог /var/spool/exim4/scan, его необходимо добавить в группу Debian-exim
# usermod -G Debian-exim clamav
Чтобы научить Exim отдавать на проверку stmp-траффик, необходимо добавить строку
av_scanner = clamd:/var/run/clamav/clamd.ctl
в main-отдел конфигурации Exim'а (каталог /etc/exim4/conf.d/main/).
Затем добавить в acl-отдел конфигурации строки
deny message = This message contains a virus: ($malware_name) please scan your system.
malware = */defer_ok
Далее начинается самое ответственное - конфигурация Exim'а для первичной фильтрации спама:
/etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs
  • CHECK_RCPT_IP_DNSBLS = bl.spamcop.net
/etc/exim4/conf.d/main/02_exim4-config_options
  • smtp_banner = Welcome to the Moon $tod_full - изменяем banner
  • rfc1413_query_timeout = 0s - отключаем Ident-запросы, чтобы избавиться от задержки при подключению к smtp-сервису
  • helo_allow_chars = _ - чтобы разрешить в HELO/EHLO символ _
/etc/exim4/conf.d/acl/30_exim4-config_check_mail
acl_check_mail:
deny
message = no HELO given before MAIL command
condition = ${if def:sender_helo_name {no}{yes}}

accept
/etc/exim4/conf.d/acl/30_exim4-config_check_rcptd
acl_check_rcpt:
accept
hosts = :
# описание этого условия можно найти тут
drop message = Forged IP in HELO.
log_message = HELO is our IP
condition = ${if eq {${lookup {$sender_helo_name} \
lsearch{/etc/exim4/reject_helo} \
{yes}{no}}}{${if !eq {$sender_host_address}{127.0.0.1}{yes}{no}}}{yes}{no}}

accept
.ifndef CHECK_RCPT_POSTMASTER
local_parts = postmaster
.else
local_parts = CHECK_RCPT_POSTMASTER
.endif
domains = +local_domains : +relay_to_domains

accept
hosts = +relay_from_hosts
control = submission/sender_retain

accept
authenticated = *
control = submission/sender_retain

accept
domains = +local_domains
endpass
message = unknown user
verify = recipient

# Иногда бывает удобно воспользоваться данным условием, чтобы заблокировать отправителей,
# указав их в файле /etc/exim4/local_sender_blacklist
deny
message = sender envelope address $sender_address is locally blacklisted here. If you think this is wrong, get in touch with postmaster
!acl = acl_whitelist_local_deny
senders = ${if exists{CONFDIR/local_sender_blacklist}\
{CONFDIR/local_sender_blacklist}\
{}}

# То же самое, только касательно хостов-отправителей
deny
message = sender IP address $sender_host_address is locally blacklisted here. If you think this is wrong, get in touch with postmaster
!acl = acl_whitelist_local_deny
hosts = ${if exists{CONFDIR/local_host_blacklist}\
{CONFDIR/local_host_blacklist}\
{}}

# Полезное правило, но с ним нужно быть осторожным. На основном mx-сервере я оставляю его
# в warn-режиме, чтобы вдруг не заблокировать неродиво настроенных серверов, а вот на вторичных всегда выставляю в deny.
warn
message = X-Host-Lookup-Failed: Reverse DNS lookup failed for $sender_host_address (${if eq{$host_lookup_failed}{1}{failed}{deferred}})
condition = ${if and{{def:sender_host_address}{!def:sender_host_name}}\
{yes}{no}}

# Проверка по DNSBLS. Почта отбрасывается, если хост находится сразу в трёх DNS Black листах:
# bl.spamcop.net, xbl.spamhaus.org, ctl.abuseat.org.
.ifdef CHECK_RCPT_IP_DNSBLS
drop
message = X-Warning: $sender_host_address is listed at DNSLists (bl.spamcop.net,xbl.spamhaus.org,cbl.abuseat.org) and out system thinks your message is spam.
log_message = $sender_host_address is listed at DNSLists
dnslists = CHECK_RCPT_IP_DNSBLS
dnslists = xbl.spamhaus.org
dnslists = cbl.abuseat.org
.endif

# Проверка отправителя. Callout означает, что данных почтовый сервер, для того чтобы проверить
# существование указанного отправителя, инициирует попытку отправить письмо указанному отправителю.
# Опция defer_ok предостерегает от отбрасывания серверов с greylisting'ом, либо с серверов,
# на которые временно невозможно присоединиться
deny
message = Sender verification failed
!acl = acl_whitelist_local_deny
domains = +relay_to_domains
!verify = sender/callout=30s,defer_ok

# Обязательная проверка получателя для внутренних доменов (relay_to_domains) callout'ом.
accept
domains = +relay_to_domains
endpass
message = unknown user
verify = recipient/callout

# Если все предыдущие условия не подходят, отбрасываем письмо.
deny
message = relay not permitted
А для того, чтобы данный основной mx-сервер рассылал почту конкретным внутренним серверам, достаточно добавить файл /etc/exim4/hubbed_hosts примерно такого содержания:
mycompany.com: 192.168.1.2
mycompany.eu: 192.168.1.2
mycompany.net: 192.168.1.3
Ссылки:
  1. Specification of the Exim Mail Transfer Agent

3 comments:

Трам-пам-пам said...

Немного не по теме, но все же.
Вы случаем не знаете, как можно отправить attachment через telnet по smtp ?

Roman Sozinov said...

to Трам-пам-пам:
Отчего ж не знаю? Знаю :)
Но это не так просто, так как Вам придётся перевести attachment в base64-кодировку и только потом вставлять в открытую smtp телнет-сессию. Естественно прежде необходимо всё сделать по правилам smtp-протокола :)
http://www.cs.cf.ac.uk/Dave/PERL/node175.html

Anonymous said...

Можно ли чуть подробнее вот куда это и как вставить. Не могу врубится.

CHECK_RCPT_IP_DNSBLS = bl.spamcop.net