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