diff --git a/articles/2016/04/10/hardcore-mail-relay-1/index.markdown b/articles/2016/04/10/hardcore-mail-relay-1/index.markdown index d41e3ba..6daea22 100644 --- a/articles/2016/04/10/hardcore-mail-relay-1/index.markdown +++ b/articles/2016/04/10/hardcore-mail-relay-1/index.markdown @@ -13,7 +13,7 @@ tags: mail, spam, exim, zabbix, rspamd, репост * общие сведения о сети * литература и ссылки - [Статистика и мониторинг](/articles/2016/04/10/hardcore-mail-relay-2/) -- Настройки средств самого exim'а +- [Настройки средств самого exim'а](/articles/2016/04/11/hardcore-mail-relay-3/) - Усиливаем защиту внешними средствами * отстрел ботов * грейлистинг @@ -63,3 +63,5 @@ tags: mail, spam, exim, zabbix, rspamd, репост * [официальный талмуд по exim'у](http://www.exim.org/exim-html-current/doc/html/spec_html/index.html) * [rspamd, документация на оффсайте](http://rspamd.com/doc/index.html) * [rspamd, более читабельная версия доков](https://bitbucket.org/vstakhov/rspamd/wiki/Documentation_single) + +[Далее: Статистика и мониторинг](/articles/2016/04/11/hardcore-mail-relay-3/) diff --git a/articles/2016/04/10/hardcore-mail-relay-2/index.markdown b/articles/2016/04/10/hardcore-mail-relay-2/index.markdown index 638edef..c9cf22b 100644 --- a/articles/2016/04/10/hardcore-mail-relay-2/index.markdown +++ b/articles/2016/04/10/hardcore-mail-relay-2/index.markdown @@ -107,4 +107,4 @@ tags: mail, spam, exim, zabbix --- -[К оглавлению](/articles/2016/04/10/hardcore-mail-relay-1/) +[К оглавлению](/articles/2016/04/10/hardcore-mail-relay-1/), [Далее: Настройка самого exim'а](/articles/2016/04/11/hardcore-mail-relay-3/) diff --git a/articles/2016/04/11/hardcore-mail-relay-3/index.markdown b/articles/2016/04/11/hardcore-mail-relay-3/index.markdown new file mode 100644 index 0000000..d3fd011 --- /dev/null +++ b/articles/2016/04/11/hardcore-mail-relay-3/index.markdown @@ -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/)