dnl dnl поддержка Reverse-Path Rewriting (aka Sender Rewriting Scheme) dnl dnl http://spf.pobox.com/srs.html dnl http://www.infradead.org/rpr.html dnl dnl пароль dnl define(`confSRS_SECRET', `somesecret')dnl dnl dnl длина hash'а dnl define(`confSRS_HASH_LENGTH', `20')dnl dnl dnl время жизни SRS подписи, дн. dnl define(`confSRS_DSN_TIMEOUT', `7')dnl dnl dnl SRS домен dnl пример: dnl define(`confSRS_DOMAIN', `srs.local.domain')dnl dnl при этом надо прописать wildcard для MX записей в настройках DNS сервера dnl пример: dnl *.srs.local.domain IN MX 10 this.host. dnl dnl режим отладки dnl NO - выключить режим отладки dnl YES - включить режим отладки dnl define(`confSRS_DEBUG', `NO')dnl dnl dnl список отправителей, адреса которых подписываются SRS указывается dnl в файле CONFDIR/senders-always-srs в виде: dnl domain0 : maibox00 : mailbox01 : mailbox02 dnl domain1 : maibox10 : mailbox11 dnl список адресов по умолчанию можно указать, используя "*" в качестве домена dnl пример: dnl domain.tld : * dnl our.domain.com : !postmaster : * dnl dnl так, если нужно подписывать все адреса, кроме локальных, dnl в CONFDIR/senders-always-srs необходимо указать: dnl local.domain : !* dnl another.local.domain : !* dnl * : * dnl dnl ислючения для перезаписи адресов: dnl LOCAL - не будут перезаписываться адреса отправителей из domain-local dnl RELAY_DOMAINS - не будут перезаписываться адреса отправителей из domain-relayto dnl define(`confSRS_DOMAINS_SKIP', `LOCAL RELAY_DOMAINS')dnl dnl при использовании confSRS_DOMAINS_SKIP нет необходимости перечислять локальные и рилеемые dnl домены в CONFDIR/senders-always-srs dnl dnl список получателей, для которых не надо подписывать обратный адрес отправителя dnl с помощью SRS указывается в файле CONFDIR/skip_srs_recipients dnl рекомендуется внести в этот файл адреса списков рассылок и других получателей, dnl которые идентифицируют отправителей по envelope from, а не по header from dnl адреса в списке указывается построчно dnl пример: dnl exim-users@exim.org.ua dnl freebsd@freebsddiary.org.ua dnl *@yahoogroups.com dnl ifelse(SECTION, `MAIN', `dnl # NOTE: The Caller-ID lookup needs to check for a TXT record with an # underscore in it. Make sure your dns_check_names_pattern # http://www.exim.org/exim-html-4.30/doc/html/spec_14.html#IX1060 # option is set accordingly. Mine looks like this: dns_check_names_pattern = (?i)^(?>(?(1)\.|())[_a-z0-9\xc0-\xff](?>[-_a-z0-9\x80-\xff]*[_a-z0-9\x80-\xbf])?)+$ # Define this to handle SRS-bounces SRS_SECRET=confSRS_SECRET ifdef(`confSRS_SECRET', `', ` errprint(`*** ERROR: confSRS_SECRET variable required ')') # And this if you want to (probably temporarily) accept two keys. #SRS_OLD_SECRET= ifdef(`confSRS_DOMAIN', `', ` errprint(`*** ERROR: confSRS_DOMAIN variable required ')') domainlist rpr_domains = *.confSRS_DOMAIN SRS_HASH_LENGTH=confSRS_HASH_LENGTH SRS_DSN_TIMEOUT=confSRS_DSN_TIMEOUT SRS_URL=http://www.infradead.org/rpr.html # Define this to enable SRS on forwarding. SRS_DOMAIN=confSRS_DOMAIN ifelse(confSRS_DEBUG, `YES', ` SRS_DEBUG=YES ') ') ifelse(SECTION, `ACL_CHECK_RCPT', `dnl # отвергание DSN, не подписанных SRS deny senders = : recipients = @@lsearch;CONFDIR/senders-always-srs message = Bounce address not SRS signed log_message = Bounce address not SRS signed # отвергание писем с непустым envelope from или не от postmaster@ для доменов +rpr_domains deny domains = +rpr_domains condition = ${if and{\ {!eq {$sender_address}{}} \ {!eq {$sender_address_local_part}{postmaster}}\ }{yes}{no}} message = Invalid SRS bounce (Not DSN: $sender_address instead) log_message = Invalid SRS bounce (Not DSN: $sender_address instead) ') ifelse(SECTION, `ROUTERS', `dnl # Urgh. Isn''`t there a better way to detect that we''`re in sender verification? # -- This will apparently be fixed in Exim 4.31 rpr_mark_sender_verify: caseful_local_part verify_only verify_recipient = false driver = redirect data = ${quote_local_part:$local_part}@$domain address_data = verifying sender redirect_router = rpr_bounce # Verify, and extract return address from, an SRS-address. # Don''`t allow non-bounces, except from postmaster@* since some people use # that for sender-verification callbacks. # прием bounce messages для SRS подписанных адресов rpr_bounce: caseful_local_part driver = redirect domains = +rpr_domains allow_fail data = ${if !match {$local_part}{\N^[sS][rR][sS]0\+([^+]+)\+([0-9]+)\+([^+]+)\+(.*)\N} \ {:fail: Invalid SRS bounce \ .ifdef SRS_DEBUG (malformed)\ .endif } \ {${if and {{!eq {$1}{${length_SRS_HASH_LENGTH:${hmac{md5}{SRS_SECRET}{${lc:$2+$3+$4@$domain}}}}}} \ .ifdef SRS_OLD_SECRET {!eq {$1}{${length_SRS_HASH_LENGTH:${hmac{md5}{SRS_OLD_SECRET}{${lc:$2+$3+$4@$domain}}}}}} \ .endif } \ {:fail: Invalid SRS bounce \ .ifdef SRS_DEBUG (HMAC should be ${length_SRS_HASH_LENGTH:${hmac{md5}{SRS_SECRET}{${lc:$2+$3+$4@$domain}}}} not $1)\ .endif } \ {${if <{$2}{${eval:$tod_epoch/86400-12288-SRS_DSN_TIMEOUT}} \ {:fail: Invalid SRS bounce \ .ifdef SRS_DEBUG (expired ${eval:$tod_epoch/86400-12288-SRS_DSN_TIMEOUT-$2} days ago)\ .endif } \ {${if >{$2}{${eval:$tod_epoch/86400-12288}} \ {:fail: Invalid SRS bounce \ .ifdef SRS_DEBUG (timestamp in future)\ .endif } \ {${if and { {!eq {$sender_address}{}} \ {!eqi {$sender_address_local_part}{postmaster}}\ {!eq {$address_data}{verifying sender}}\ } \ {:fail: Invalid SRS bounce \ .ifdef SRS_DEBUG (Not DSN: $sender_address instead)\ .endif }\ # Wheee. At last the actual rewrite part... {${quote_local_part:$4}@$3}\ }}}}}}}}} headers_add = X-SRS-Return: DSN routed via $primary_hostname. See SRS_URL # исключения из перезаписи адресов отправителей, # если отправитель пустой rpr_skip_DSN: driver = redirect senders = ! data = ${quote_local_part:$local_part}@$domain redirect_router = dnslookup # skip SRS for some recipients # исключения из перезаписи адресов отправителей, # если получатель указан в CONFDIR/skip_srs_recipients rpr_skip_rcpt: driver = redirect condition = ${lookup{$local_part@$domain}wildlsearch{CONFDIR/skip_srs_recipients}{yes}{no}} data = ${quote_local_part:$local_part}@$domain redirect_router = dnslookup # Some addresses are joe-job protected by _always_ using SRS, and never actually # sending mail from that address. That way, we can always reject bounces to these # addresses, and prevent joe-jobs from being received by anyone who actuallybothers # to do sender verification callouts. # исключения из перезаписи адресов отправителей, # если отправитель не указан в CONFDIR/senders-always-srs rpr_skip_mail: driver = redirect senders = !@@lsearch;CONFDIR/senders-always-srs data = ${quote_local_part:$local_part}@$domain redirect_router = dnslookup # Rewrite reverse-path so that forwarding to known SPF-afflicted # servers doesn''`t break. We generate a limited-lifetime hash cookie, # from which we can later recreate the original sender address. We # include the hostname and more precise timestamp in the domain of the # generated address, so that we can track down the offending message # in the log if it _does_ offend us. # перезапись адресов отправителей # если получатель в из домена, указанного в CONFDIR/domains-spf-afflicted rpr_outgoing_goto: caseful_local_part driver = redirect # Don''`t rewrite unless the recipient is in a domain we _know_ to be broken # but for local reasons have decided we need to work around. # The text file listing broken recipient domains should look something like: # gmx.net: all # gmx.de: all # aol.com: spf # This lookup will leave the result of the lookup in $domain_data. domains = lsearch;CONFDIR/domains-spf-afflicted # We expect any or all of "all", "spf", "cid" or "self" in $domain_data from the textfile lookup # If the reason for the breakage is listed as "spf", then don''`t rewrite # unless the sender''`s domain actually advertises SPF records. # Likewise for "cid" and Caller-ID records. # If it''`s listed as "self" then rewrite only if we''`re sending it # mail claiming to be from itself or one of its subdomains. # If it''`s "all" then just rewrite everything. condition = ${if or { \ {eq{$domain_data}{all}} \ {and { {match{$domain_data}{spf}} \ {match {${lookup dnsdb{txt=$sender_address_domain}{$value}{}}}{v=spf1}} \ }} \ {and { {match{$domain_data}{cid}} \ {match {${lookup dnsdb{txt=_ep.$sender_address_domain}{$value}{}}}{^