MTA EXIM - свободно распространяемый Mail Transfer Agent (MTA, лицензия GPL), обладающий возможностью очень гибкой и тонкой настройки, включая поиск конфигурационной информации в базах данных - mySQL, PostgresQL, Oracle, SQLite, а также LDAP. В Exim встроена поддержка Maildir (quota), SMTP-аутентификация, TLS/SSL, SpamAssassin, сканирование на лету антивирусом(ами), ACL, системные фильтры.
В этой статье я не буду останавливаться на настройке MTA в целом, а лишь рассмотрю некоторые методы борьбы с нежелательной корреспонденцией не прибегая к сторонним средствам, а силами самого EXIM – с помощью ACL (Access Control List).
Итак, секция ACL в конфиге EXIM:
*******
# начало блока ACL
begin acl
# блок ACL, проверяющий входящую почту (отправителя, получателя и тд)
acl_check_rcpt:
# предварительно принимаем почту со всех хостов (тут можно ввести IP-адреса, с которых мы хотим получать почту через двоеточие или список в файле. Однако нас это не устраивает)
accept hosts = :
# отбрасываем письма, если в локальной части адреса находятся символы ^[.] : ^.*[@%!/|] Проверяются локальные домены.
deny message = "Restricted characters in address. Rejected"
domains = +relay_to_domains
local_parts = ^[.] : ^.*[@%!/|]
# отбрасываем письма, если в локальной части адреса находятся символы ^[./|] : ^.*[@%!] : ^.*/\\.\\./ Проверяются нелокальные домены
deny message = "Restricted characters in address. Rejected"
domains = !+relay_to_domains
local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
# принимаем письма для постмастеров локальных доменов
accept local_parts = postmaster
domains = +relay_to_domains
# требуем проверки отправителя – в противном случае письмо отбрасывается
require verify = sender
# отбрасываем письмо, если у отправителя отсутствует HELO/EHLO. HELO – параметр протокола SMTP, несущий в себе имя хоста, или, другими словами,- это приветствие сервера. Обычно это имя домена, например, HELO gateway.af.mil или IP-адрес, взятый в квадратные скобки, например, HELO [10.43.0.25]. В нежелательной почте встречаются такие ситуации касательно HELO: его отсутствие, подсовывание IP-адреса принимающего сервера. Введем эти проверки в ACL. Если в результате проверок режется нужная почта, то просто добавляем в секцию hosts IP-адрес этого отправителя (hosts =!$IP_ADDRESS$), однако у меня проблем не возникало. На этом спам немного, но режется.
deny message = "HELO/EHLO required by RFC. Rejected"
condition = ${if eq{$sender_helo_name}{}{yes}{no}}
# отбрасываем письма в HELO отправителя стоит IP-адрес получателя. Не проверяем локалхост. Кстати, лучше указывать и 127.0.0.1 и localhost – так будет меньше проблем
deny message = "My IP in your HELO? Rejected"
condition = ${if eq{$sender_helo_name}{$interface_address}{yes}{no}}
hosts = !127.0.0.1 : !localhost : *
# отбрасываем письмо, если в HELO отправителя стоит его же IP-адрес. Согласно RFC в HELO должно указываться имя хоста или IP-адрес в квадратных скобках.
deny message = "Your IP in HELO? Rejected"
condition = ${if eq{$sender_helo_name}{$sender_host_address}{true}{false}}
# отбрасываем письмо, если в HELO отправителя находятся только цифры. Не проверяем локалхост
deny message = "HELO can not contain only digits. Rejected"
hosts = !127.0.0.1 : !localhost : *
condition = ${if match{$sender_helo_name}{\N^\d+$\N}{yes}{no}}
# отбрасываем письма поле адреса отправителя пустое. Я эту проверку убрал, поскольку на этом резалось некоторое количество нужной корреспонденции
# deny condition = ${if eq{$sender_address}{}{yes}{no}}
# hosts = !127.0.0.1 : !localhost : *
# message = "Sender address can not be blanc. Rejected"
# отбрасываем письма, если поле адреса отправителя стоят только пробелы. Не проверяем локалхост. Спама на этой проверке режется мало
deny message = "Sender address can not contain only spaces. Rejected"
hosts = !127.0.0.1 : !localhost : *
condition = ${if match{$sender_address}{\N^\s+$\N}{yes}{no}}
# отбрасываем письма если имя хоста отправителя содержит такие конструкции как adsl, dialup,pool,peer,dhcp – нормальный человек с таких писать не будет
deny condition = ${if match{$sender_host_name}{adsl|dialup|pool|peer|dhcp}{yes}{no}}
message = "Your hostname is bad (adsl,dhcp,dialup,etc...). Rejected"
# отбрасываем письма если адрес отправителя находится в файле senders_deny. Файл сформирован из черного списка Outlook c установленным Spamassasin. Формат файла – один адрес на каждой строке. В файле можно указывать полностью домены, с которых получение почты нежелательно. Не проверяем локалхост. Спама режется мало, так как спаммерские адреса все время меняются, но если резать полностью домены – должно быть более эффективно.
deny senders = /usr/local/etc/exim/senders_deny
hosts = !127.0.0.1 : !localhost
message = "Sender greylisted. Sender not allowed."
# проверяем наличие IP-адреса отправителя в блэк-листах. Использовать их нужно аккуратно так как во многих, например, dsbl.org находится половина адресов Интернета. Я выбрал 2 – cbl.abuseat.org и bl.spamcop.net как наиболее адекватные. Спама режется прилично. Если какой-либо хост проверять не нужно, вносим его IP- адрес в раздел hosts.
deny message = "Rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text"
hosts = !$IP_ADDRESS$
dnslists = cbl.abuseat.org
deny message = "Rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text"
hosts = !$IP_ADDRESS$
dnslists = bl.spamcop.net
# ставим задержку 30 секунд при получении писем от отправителя. Спама режется много, так как спаммерским серверам некогда ждать, а обычные mail-сервера способны ждать и минуту и больше. Метод взят с сайта www.lissyara.su
# присваиваем переменной acl_m0 значение 30 сек
warn set acl_m0 = 30s
# для дружественных хостов или тех, с кем из-за этого метода возникают проблемы переменной присваиваем значение 0 сек
warn hosts = +relay_from_hosts : $IP_ADDRESS$
set acl_m0 = 0s
# пишем значение задержки в лог
warn logwrite = Delay $acl_m0 for $sender_host_name [$sender_host_address] with HELO=$sender_helo_name.Mail from $sender_address to $local_part@$domain.
# ставим собственно задержку на 30 или 0 сек в зависимости от значения переменной acl_m0
delay = $acl_m0
# принимаем почту для получателей, перечисленных в файле recipients_allow. Это существенно только если у вас есть почтовый релей и собственно почтовый сервер с ящиками пользователей. Без этого условия проходит очень много спама на несуществующие адреса, а сообщение об отсутствии такого ящика отправитель получает не от релея, а от почтового сервера – а это уже письмо и если в письме отправителя в поле копия есть еще адреса, то мы автоматически становимся спаммерами и попадаем в блэк-листы, что огорчает. На количество спама это не влияет, однако снижает вероятность попадания в блэк-листы при условии использования почтового релея
accept recipients = /usr/local/etc/exim/recipients_accept
hosts = !127.0.0.1 : !localhost
deny recipients = *
hosts = !127.0.0.1 : !localhost
message = "You are not allowed to send email to this address. If I mistaken - please contact through postmaster@"
# далее стандартно – принимаем почту для своего домена, проверяем получателя. Если ни одно правило не подошло – значит отправитель ищет open-relay, на что получит ответ Relay not permitted
accept domains = +relay_to_domains
endpass
verify = recipient
message = "I have no such user. Rejected"
accept hosts = +relay_from_hosts
deny message = "Relay not permitted"