Alex 'AdUser' Z
9 years ago
3 changed files with 388 additions and 2 deletions
@ -0,0 +1,384 @@ |
|||||||
|
--- |
||||||
|
title: Почтовый шлюз: задание со звёздочкой (Настройка самого exim'а) |
||||||
|
tags: mail, spam, exim |
||||||
|
--- |
||||||
|
|
||||||
|
Прежде чем накручивать внешние сервисы, нужно посмотреть, что можно сделать встроенными средствами самого exim'а. |
||||||
|
|
||||||
|
Далее идут куски конфига exim'а с пояснениями по месту. |
||||||
|
В случаях, когда опыт и стандарт не совпадают - предпочтение отдавалось опыту. |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
Из конфига убрано всё лишнее, для удобства воспрятия. |
||||||
|
По большему счёту использовались только lookup'ы, особенности протокола, dnsbl и встроенный spf. |
||||||
|
|
||||||
|
Пару слов насчёт dnsbl: используйте. |
||||||
|
Как бы на них не ругались, нервные клетки, сэкономленные на отстреле всякой нечисти, |
||||||
|
стоят той небольшой их части, которую вы потратите на вытаскивание особо одарённых в исключения. |
||||||
|
|
||||||
|
Кроме того важен психологический момент: клиент **сам** попал в блэклист, |
||||||
|
и то что до нас не доходит его почта - соотвественно **его собственный** косяк. |
||||||
|
|
||||||
|
## --------------------------------------------------------- |
||||||
|
# общие настройки |
||||||
|
## --------------------------------------------------------- |
||||||
|
split_spool_directory |
||||||
|
rfc1413_query_timeout = 0s |
||||||
|
local_scan_timeout = 50s |
||||||
|
disable_ipv6 = true |
||||||
|
dns_ipv4_lookup = * |
||||||
|
untrusted_set_sender = * |
||||||
|
local_from_check = false |
||||||
|
message_size_limit = 15m |
||||||
|
ignore_bounce_errors_after = 45m |
||||||
|
|
||||||
|
# эти настройки специфичны для вашего дистрибутива |
||||||
|
exim_user = mailnull |
||||||
|
exim_group = mail |
||||||
|
trusted_users = mailnull : nobody |
||||||
|
|
||||||
|
# на этой опции основана одна из проверок для совсем тупых ботов. |
||||||
|
# при попытке использовать pipeline, когда мы его не анонсируем - |
||||||
|
# сбрасывать соединение |
||||||
|
# в postfix'е соответствует reject_unauth_pipeline |
||||||
|
pipelining_advertise_hosts = |
||||||
|
|
||||||
|
# не разрешать домены в виде @[ip-адрес] |
||||||
|
# в стандарте оно есть, но никто в здравом уме ими не пользуется |
||||||
|
allow_domain_literals = false |
||||||
|
|
||||||
|
# настройки smtp-соединений |
||||||
|
smtp_accept_queue_per_connection = 200 |
||||||
|
smtp_accept_max = 1000 |
||||||
|
smtp_accept_reserve = 200 |
||||||
|
smtp_accept_max_per_host = 10 |
||||||
|
smtp_reserve_hosts = +relay_from_hosts : +our_networks : +our_hosts |
||||||
|
|
||||||
|
# как представляться в EHLO общем случае |
||||||
|
primary_hostname = relay.example.com |
||||||
|
# на каких адресах принимать соединения |
||||||
|
local_interfaces = 4.3.2.1 : 192.168.15.2 |
||||||
|
# КРАЙНЕ ЖЕЛАТЕЛЬНО, чтобы в DNS PTR для первого адреса |
||||||
|
# было прописано relay.example.com |
||||||
|
# обратитесь к провайдеру |
||||||
|
|
||||||
|
host_lookup = * |
||||||
|
host_reject_connection = +include_unknown |
||||||
|
|
||||||
|
helo_allow_chars = _ |
||||||
|
helo_try_verify_hosts = * |
||||||
|
|
||||||
|
# уменьшает количество логов |
||||||
|
log_selector = \ |
||||||
|
-host_lookup_failed \ |
||||||
|
-lost_incoming_connection \ |
||||||
|
-queue_run |
||||||
|
|
||||||
|
# домены, почта для которых доставляется в пределах этой машины |
||||||
|
domainlist local_domains = relay.example.com |
||||||
|
|
||||||
|
# spam_domains - домены, от которых идёт только спам |
||||||
|
# known_domains - домены, с которыми работаем постоянно |
||||||
|
# не включайте сюда shared-мегапомойки типа @mail.ru! |
||||||
|
domainlist our_domains = /etc/exim/lists/our_domains |
||||||
|
domainlist spam_domains = /etc/exim/lists/spam_domains |
||||||
|
domainlist known_domains = /etc/exim/lists/known_domains |
||||||
|
|
||||||
|
# trusted_hosts - пропустить большнство проверок для этих хостов |
||||||
|
# relay_from_hosts - разрешить пересылку почты на внешние домены с этих адресов |
||||||
|
hostlist our_hostnames = relay.example.com |
||||||
|
hostlist relay_from_hosts = 127.0.0.1 : 192.168.15.4 |
||||||
|
hostlist our_hosts = /etc/exim/lists/our_hosts |
||||||
|
hostlist our_networks = /etc/exim/lists/our_networks |
||||||
|
hostlist trusted_hosts = /etc/exim/lists/trusted_hosts |
||||||
|
hostlist spam_hosts = /etc/exim/lists/spam_hosts |
||||||
|
hostlist helo_whitelist = /etc/exim/lists/helo_whitelist |
||||||
|
hostlist helo_spam_regexps = /etc/exim/lists/helo_spam_regexps |
||||||
|
|
||||||
|
## --------------------------------------------------------- |
||||||
|
acl_smtp_helo = check_helo |
||||||
|
acl_smtp_rcpt = check_rcpt |
||||||
|
acl_smtp_data = check_data |
||||||
|
|
||||||
|
begin acl |
||||||
|
## --------------------------------------------------------- |
||||||
|
# различные проверки хостов по helo/ehlo |
||||||
|
## --------------------------------------------------------- |
||||||
|
check_helo: |
||||||
|
drop message = HELO/EHLO require by SMTP RFC |
||||||
|
hosts = !+trusted_hosts |
||||||
|
condition = ${if eq{$sender_helo_name}{} {yes}{no}} |
||||||
|
|
||||||
|
drop message = IP address in HELO |
||||||
|
hosts = !+trusted_hosts |
||||||
|
condition = ${if match{$sender_helo_name}{\N^\[[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\]?$\N} {yes}{no}} |
||||||
|
delay = 5s |
||||||
|
|
||||||
|
drop message = localhost in HELO/EHLO |
||||||
|
hosts = !+trusted_hosts |
||||||
|
condition = ${if match {$sender_helo_name} {\N^(127\.0\.0\.1|localhost(\.localdomain)?)$\N} {yes}{no}} |
||||||
|
delay = 5s |
||||||
|
|
||||||
|
drop message = HELO should be FQDN |
||||||
|
hosts = !+trusted_hosts |
||||||
|
condition = ${if !match{$sender_helo_name} {\N.*[A-Za-z0-9-]{2,}\.[A-Za-z]{2,6}$\N} {yes}{no}} |
||||||
|
delay = 5s |
||||||
|
|
||||||
|
accept message = Ignoring HELO/EHLO check, host was added to whitelist |
||||||
|
hosts = +trusted_hosts |
||||||
|
condition = ${lookup{$sender_helo_name}wildlsearch*{/etc/exim/lists/helo_whitelist} {yes}{no}} |
||||||
|
|
||||||
|
drop message = Dont like your hostname |
||||||
|
hosts = !+trusted_hosts |
||||||
|
condition = ${lookup{$sender_helo_name}wildlsearch*{/etc/exim/lists/helo_spam_regexps} {yes}{no}} |
||||||
|
delay = 5s |
||||||
|
|
||||||
|
drop message = Using my HELO is a bad idea |
||||||
|
!hosts = +trusted_hosts : +our_networks |
||||||
|
condition = ${if match{$sender_helo_name}{+our_hostnames} {yes}{no}} |
||||||
|
delay = 5s |
||||||
|
|
||||||
|
# если helo/ehlo прошло проверки, но не идеально - включаем грейлист |
||||||
|
warn !verify = helo |
||||||
|
set acl_m_greylist = 1 |
||||||
|
|
||||||
|
accept |
||||||
|
|
||||||
|
## --------------------------------------------------------- |
||||||
|
# различные проверки получателей |
||||||
|
## --------------------------------------------------------- |
||||||
|
check_rcpt: |
||||||
|
# эти получатели могут получать всю почту, несмотря ни на какие проверки |
||||||
|
accept local_parts = postmaster : admin |
||||||
|
domains = +our_domains |
||||||
|
|
||||||
|
# эти хосты могут слать почту куда угодно, |
||||||
|
# но только от нашего имени |
||||||
|
accept hosts = +relay_from_hosts |
||||||
|
sender_domains = +our_domains |
||||||
|
|
||||||
|
# "наши" хосты могут слать почту внутри "наших" доменов |
||||||
|
# без авторизации |
||||||
|
accept hosts = +our_networks : +our_hosts |
||||||
|
domains = +our_domains |
||||||
|
|
||||||
|
# различные виды блокировок особо настырных |
||||||
|
# сообщения намерено оставлены неинформативными |
||||||
|
deny message = You are blocked |
||||||
|
sender_domains = +spam_domains |
||||||
|
|
||||||
|
deny message = You are blocked |
||||||
|
hosts = +spam_hosts |
||||||
|
|
||||||
|
deny message = You are blocked |
||||||
|
senders = wildlsearch*@;/etc/exim/lists/spam_domain_regexps |
||||||
|
|
||||||
|
deny message = You are blocked |
||||||
|
senders = wildlsearch*@;/etc/exim/lists/spam_emails |
||||||
|
|
||||||
|
reject message = You are not allowed to use submission port |
||||||
|
condition = ${if eq {$interface_port}{587} {yes}{no}} |
||||||
|
!hosts = +relay_from_hosts |
||||||
|
|
||||||
|
# проверки обратного dns-имени |
||||||
|
# впринципе, их можно вынести в отдельный list и свернуть в одно правило, |
||||||
|
# но так отправляется вменяемое сообщение в отлупе |
||||||
|
warn message = Bad rev hostname (missing) |
||||||
|
hosts = !+trusted_hosts |
||||||
|
condition = ${if eq{$sender_host_name}{} {yes}{no}} |
||||||
|
set acl_m_greylist = 1 |
||||||
|
delay = 5s |
||||||
|
|
||||||
|
deny message = Bad rev hostname (ip address, dashes) |
||||||
|
hosts = !+trusted_hosts |
||||||
|
condition = ${if match{$sender_host_name} {[0-9]+-[0-9]+-[0-9]+-[0-9]+} {yes}{no}} |
||||||
|
delay = 5s |
||||||
|
|
||||||
|
deny message = Bad rev hostname (ip address, dots) |
||||||
|
hosts = !+trusted_hosts |
||||||
|
condition = ${if match{$sender_host_name} {\N[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\N} {yes}{no}} |
||||||
|
delay = 5s |
||||||
|
|
||||||
|
deny message = Bad rev hostname (adsl, pool, ppp & etc) |
||||||
|
hosts = !+trusted_hosts |
||||||
|
condition = ${if match{$sender_host_name} {[ax]dsl|pool|dialup|peer|dhcp|gprs|broadband|dslam|dynamicip|ppp|pptp|pppoe} {yes}{no}} |
||||||
|
delay = 5s |
||||||
|
|
||||||
|
deny message = Bad rev hostname (vps) |
||||||
|
hosts = !+trusted_hosts |
||||||
|
condition = ${if match{$sender_host_name} {vps[-\\.]?[0-9]+|\\.vps} {yes}{no}} |
||||||
|
delay = 5s |
||||||
|
|
||||||
|
# проверки SPF - встроенная в exim, включается ключом при компиляции |
||||||
|
drop message = SPF for sender domain not allows mail from your host |
||||||
|
hosts = !+trusted_hosts |
||||||
|
spf = fail |
||||||
|
|
||||||
|
warn message = SPF softfail, greylisted |
||||||
|
hosts = !+trusted_hosts |
||||||
|
spf = softfail |
||||||
|
set acl_m_greylist = 1 |
||||||
|
|
||||||
|
# дубовая проверка на подделку отправителя |
||||||
|
deny message = Sender is in our domains, but host is not |
||||||
|
sender_domains = +our_domains |
||||||
|
!hosts = +our_networks : +our_hosts |
||||||
|
|
||||||
|
accept hosts = : +trusted_hosts |
||||||
|
domains = +our_domains |
||||||
|
|
||||||
|
deny message = Host is listed in $dnslist_domain |
||||||
|
dnslists = zen.spamhaus.org:bl.spamcop.net |
||||||
|
delay = 30s |
||||||
|
|
||||||
|
# если число несуществующих получателей больше семи - отлуп, |
||||||
|
# это явно какая-то автоспамилка |
||||||
|
deny message = Max $rcpt_fail_count failed recipients allowed |
||||||
|
condition = ${if > {${eval:$rcpt_fail_count}}{7}{yes}{no}} |
||||||
|
delay = ${eval: ($rcpt_fail_count) * 30}s |
||||||
|
log_message = $rcpt_fail_count failed recipient attempts |
||||||
|
|
||||||
|
# кто-то пытается злоупотребить доверием |
||||||
|
# потом эти строчки в логе светятся в eximstats'е как новогодняя ёлка |
||||||
|
warn log_message = External mail relaying from 'trusted' hosts |
||||||
|
hosts = +trusted_hosts |
||||||
|
domains = !+our_domains |
||||||
|
|
||||||
|
# проверять получателей сразу, методом коннекта к нашему внутреннему почтовику |
||||||
|
# не принимать письма, если у нас нет таких юзеров |
||||||
|
deny message = No such user |
||||||
|
domains = +our_domains |
||||||
|
!verify = recipient/callout=10s,defer_ok/no_details |
||||||
|
|
||||||
|
# пометить письма от доменов, с которыми мы работаем постоянно |
||||||
|
# учитывается антиспамом, смотри далее |
||||||
|
warn remove_header = x-known-domain |
||||||
|
sender_domains = +known_domains |
||||||
|
add_header = X-Known-Domain: $sender_address_domain |
||||||
|
|
||||||
|
# место для проверки грейлистингом |
||||||
|
|
||||||
|
accept domains = +local_domains |
||||||
|
accept domains = +our_domains |
||||||
|
|
||||||
|
deny message = relay not permitted |
||||||
|
delay = 10s |
||||||
|
|
||||||
|
## --------------------------------------------------------- |
||||||
|
# проверки тела письма |
||||||
|
## --------------------------------------------------------- |
||||||
|
check_data: |
||||||
|
# тут пока ничего нет, см дальше |
||||||
|
|
||||||
|
## --------------------------------------------------------- |
||||||
|
# маршрутизация |
||||||
|
## --------------------------------------------------------- |
||||||
|
begin routers |
||||||
|
|
||||||
|
local_mail: |
||||||
|
driver = accept |
||||||
|
check_local_user |
||||||
|
domains = +local_domains |
||||||
|
transport = local_delivery |
||||||
|
|
||||||
|
our_mail_server: |
||||||
|
driver = manualroute |
||||||
|
domains = +our_domains |
||||||
|
route_list = * mail.example.com byname |
||||||
|
transport = local_smtp |
||||||
|
|
||||||
|
lookuphost: |
||||||
|
driver = dnslookup |
||||||
|
domains = ! +local_domains |
||||||
|
ignore_target_hosts = 127.0.0.0/8 |
||||||
|
transport = remote_smtp |
||||||
|
no_more |
||||||
|
|
||||||
|
system_aliases: |
||||||
|
driver = redirect |
||||||
|
allow_defer |
||||||
|
allow_fail |
||||||
|
data = ${lookup{$local_part}lsearch{/etc/aliases}} |
||||||
|
file_transport = address_file |
||||||
|
group = mail |
||||||
|
pipe_transport = address_pipe |
||||||
|
retry_use_local_part |
||||||
|
user = mailnull |
||||||
|
|
||||||
|
userforward: |
||||||
|
driver = redirect |
||||||
|
check_ancestor |
||||||
|
check_local_user |
||||||
|
no_expn |
||||||
|
file = $home/.forward |
||||||
|
file_transport = address_file |
||||||
|
pipe_transport = address_pipe |
||||||
|
reply_transport = address_reply |
||||||
|
no_verify |
||||||
|
|
||||||
|
localuser: |
||||||
|
driver = accept |
||||||
|
check_local_user |
||||||
|
transport = local_delivery |
||||||
|
|
||||||
|
## --------------------------------------------------------- |
||||||
|
# способы доставки |
||||||
|
## --------------------------------------------------------- |
||||||
|
begin transports |
||||||
|
|
||||||
|
# в interface указан наш адрес в локальной сети |
||||||
|
local_smtp: |
||||||
|
driver = smtp |
||||||
|
no_delay_after_cutoff |
||||||
|
interface = 192.168.15.2 |
||||||
|
|
||||||
|
# в interface указан наш внешний internet-адрес |
||||||
|
remote_smtp: |
||||||
|
driver = smtp |
||||||
|
interface = 4.3.2.1 |
||||||
|
no_delay_after_cutoff |
||||||
|
|
||||||
|
local_delivery: |
||||||
|
driver = appendfile |
||||||
|
delivery_date_add |
||||||
|
envelope_to_add |
||||||
|
file = /var/mail/$local_part |
||||||
|
group = mail |
||||||
|
mode = 0660 |
||||||
|
return_path_add |
||||||
|
|
||||||
|
# не используется, оставлен для примера |
||||||
|
address_pipe: |
||||||
|
driver = pipe |
||||||
|
return_output |
||||||
|
|
||||||
|
# не используется, оставлен для примера |
||||||
|
address_file: |
||||||
|
driver = appendfile |
||||||
|
delivery_date_add |
||||||
|
envelope_to_add |
||||||
|
return_path_add |
||||||
|
|
||||||
|
# не используется, оставлен для примера |
||||||
|
address_reply: |
||||||
|
driver = autoreply |
||||||
|
|
||||||
|
# не используется, оставлен для примера |
||||||
|
filter_pipe: |
||||||
|
driver = pipe |
||||||
|
return_fail_output |
||||||
|
user = nobody |
||||||
|
|
||||||
|
## --------------------------------------------------------- |
||||||
|
# настройка повторов |
||||||
|
## --------------------------------------------------------- |
||||||
|
begin retry |
||||||
|
|
||||||
|
* * F,2h,15m; G,16h,1h,1.5; F,2d,8h |
||||||
|
|
||||||
|
После того у нас всё минимально работает, нужно усилить защиту сервера, чтоб ни одна сволочь не пролезла. |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
[К оглавлению](/articles/2016/04/10/hardcore-mail-relay-1/) |
Loading…
Reference in new issue