dnl dnl использовать механизм MTA-STS: dnl NO не использовать MTA-STS dnl YES не использовать MTA-STS dnl define(`confMTA_STS', `NO')dnl dnl только для exim 4.95 и выше, т. к. нужен патч для поддержки SNI dnl dnl включение тестового режима. в этом случае mode=enforce будет работать как mode=testing dnl NO - выключить тестовый режим dnl YES - включить тестовый режим dnl define(`confMTA_STS_TEST_MODE', `NO')dnl dnl dnl кеширование результатов запросов политик MTA-STS: dnl NO - не кешировать результаты dnl REDIS - кешировать результаты в redis dnl MEMCACHED - кешировать результаты в memcached dnl SQLITE - кешировать результаты в sqlite (ещё не реализовано) dnl MYSQL - кешировать результаты в mysql (ещё не реализовано) dnl define(`confMTA_STS_CACHE', `NO')dnl dnl dnl время жизни вычисленного значения MTA-STS политике в переменной $acl_m_mta_sts_policy dnl define(`confMTA_STS_TTL_LOCAL', `240')dnl dnl dnl при MEMCACHED или REDIS в confMTA_STS_CACHE dnl dnl префикс записей: dnl define(`confMTA_STS_CACHE_RECORD_PREFIX', `mta-sts:')dnl dnl dnl при SQLITE в confMTA_STS_CACHE dnl dnl define(`confMTA_STS_CACHE_SQLITE_FILE', `confSPOOLDIR/db/cache.db')dnl dnl dnl dnl dnl define(`confMTA_STS_CACHE_SQLITE_GET', `SELECT * FROM mta_sts_policy WHERE domain="$acl_arg1" AND expires > UNIXEPOCH();')dnl dnl dnl dnl define(`confMTA_STS_CACHE_SQLITE_SET', `REPLACE INTO mta_sts_policy (domain, id, version, mode, mx, max_age, expires, rua) VALUES ("$acl_arg1", "${extract{id}{$acl_arg2}}", "${extract{version}{$acl_arg2}}", "${extract{mode}{$acl_arg2}}", "${extract{mx}{$acl_arg2}}", "${extract{max_age}{$acl_arg2}}", UNIXEPOCH() + $acl_arg3, "${extract{rua}{$acl_arg2}}");')dnl dnl dnl dnl define(`confMTA_STS_CACHE_SQLITE_DELETE', `DELETE FROM mta_sts_policy WHERE expires < UNIXEPOCH();')dnl dnl dnl dnl define(`confMTA_STS_CACHE_SQLITE_GET', `SELECT * FROM mta_sts_policy WHERE domain="$acl_arg1" AND expires > datetime(UNIXEPOCH(), 'unixepoch', 'localtime');')dnl dnl dnl define(`confMTA_STS_CACHE_SQLITE_SET', `REPLACE INTO mta_sts_policy (domain, id, version, mode, mx, max_age, expires, rua) VALUES ("$acl_arg1", "${extract{id}{$acl_arg2}}", "${extract{version}{$acl_arg2}}", "${extract{mode}{$acl_arg2}}", "${extract{mx}{$acl_arg2}}", "${extract{max_age}{$acl_arg2}}", UNIXEPOCH() + $acl_arg3, "${extract{rua}{$acl_arg2}}");')dnl dnl dnl define(`confMTA_STS_CACHE_SQLITE_DELETE', `DELETE FROM mta_sts_policy WHERE expires < datetime(UNIXEPOCH(), 'unixepoch', 'localtime');')dnl dnl dnl changequote(<<, >>) dnl dnl dnl define(<>, < datetime(UNIXEPOCH(), 'unixepoch', 'localtime');>>)dnl dnl define(<>, <>)dnl dnl define(<>, <>)dnl dnl dnl changequote dnl dnl при MYSQL в confMTA_STS_CACHE dnl dnl define(`confMTA_STS_CACHE_MYSQL_GET', `SELECT domain, id, version, mode, mx, max_age, expires AS expires_datetime, UNIX_TIMESTAMP(expires) AS expires FROM mta_sts_policy WHERE domain="$acl_arg1" AND expires > NOW();')dnl dnl define(`confMTA_STS_CACHE_MYSQL_SET', `REPLACE INTO mta_sts_policy (domain, id, version, mode, mx, max_age, expires, rua) VALUES ("$acl_arg1", "${extract{id}{$acl_arg2}}", "${extract{version}{$acl_arg2}}", "${extract{mode}{$acl_arg2}}", "${extract{mx}{$acl_arg2}}", "${extract{max_age}{$acl_arg2}}", DATE_ADD(NOW(), interval $acl_arg3 second), "${extract{rua}{$acl_arg2}}");')dnl dnl define(`confMTA_STS_CACHE_MYSQL_DELETE', `DELETE FROM mta_sts_policy WHERE expires < NOW();')dnl dnl ifelse(SECTION, `ACLS_ADDITIONAL', `dnl ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl_mta_sts_get_policy_http_cache_set: # acl_arg1 - cache key # acl_arg2 - cache value # acl_arg3 - TTL ifelse(confMTA_STS_CACHE, `MEMCACHED', `dnl define(`confMEMCACHED_ENABLED', `YES')dnl warn set acl_m0 = ${acl{acl_memcached_set}{confMTA_STS_CACHE_RECORD_PREFIX`'$acl_arg1}{$acl_arg2}{$acl_arg3}} ')dnl ifelse(confMTA_STS_CACHE, `REDIS', `dnl warn set acl_m0 = ${acl{acl_redis_set}{confMTA_STS_CACHE_RECORD_PREFIX`'$acl_arg1}{$acl_arg2}{$acl_arg3}} ')dnl ifelse(confMTA_STS_CACHE, `SQLITE', `dnl warn set acl_m0 = ${lookup sqlite,file=confMTA_STS_CACHE_SQLITE_FILE{confMTA_STS_CACHE_SQLITE_SET}} ')dnl ifelse(confMTA_STS_CACHE, `MYSQL', `dnl warn set acl_m0 = ${lookup mysql{confMTA_STS_CACHE_MYSQL_SET}} ')dnl accept ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') acl_mta_sts_get_policy_http: # acl_arg1 - recipient domain # acl_arg2 - MTA-STS id accept condition = ${if match{$acl_arg1}{\N^([a-z\d\-]+\.)+[a-z]{2,}$\N}{no}{yes}} message = domain=$acl_arg1 id=$acl_arg2 mode=none message="Domain $acl_arg1 is suspicious. MTA-STS checks skipped" warn set acl_m_mta_sts_domain = ${acl{detaint}{$acl_arg1}} set acl_m_mta_sts_response = ${readsocket{inet:mta-sts.$acl_m_mta_sts_domain:443}{GET /.well-known/mta-sts.txt HTTP/1.0\r\nHost: mta-sts.$acl_m_mta_sts_domain\r\nConnection: close\r\n\r\n}{20s:tls=yes:sni=mta-sts.$acl_m_mta_sts_domain}{\n}{socket failure}} accept condition = ${if eq{$acl_m_mta_sts_response}{}{yes}{no}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=none message="Response to HTTP request mta-sts.$acl_arg1 is empty" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 60 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy accept condition = ${if eq{$acl_m_mta_sts_response}{socket failure}{yes}{no}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=none message="Unable to get response to HTTP request mta-sts.$acl_arg1: socket failure" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 60 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy accept condition = ${if match{$acl_m_mta_sts_response}{\N^HTTP\/1\.[01] 200\b\N}{no}{yes}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=none \ message="Unsuccessfull status of response to HTTP request mta-sts.$acl_arg1: ${sg{$acl_m_mta_sts_response}{\N(\r?\n.*)*$\N}{}}" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 60 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy # warn set acl_m_mta_sts_response_body = ${sg{$acl_m_mta_sts_response}{\N^((.+)\r?\n)+\r?\n\N}{}} warn set acl_m_mta_sts_response_body = ${acl{acl_http_response_get_body}{$acl_m_mta_sts_response}} accept condition = ${if eq{$acl_m_mta_sts_response_body}{}{yes}{no}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=none message="Response to HTTP request mta-sts.$acl_arg1 has empty body" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 60 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy accept condition = ${if match{$acl_m_mta_sts_response_body}{\N\bmx\s*:\s*\N}{no}{yes}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=fail message="badly formatted policy: mx not found" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 300 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy warn set acl_m_mta_sts_mx = ${reduce {<\n $acl_m_mta_sts_response_body}{}{$value${if match{$item}{\N\s*mx\s*:\s*(\S+)\s*\r?$\N}{${if eq{$value}{}{}{:}}$1}{}}}} accept condition = ${if eq{$acl_m_mta_sts_mx}{}{yes}{no}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=fail message="badly formatted policy: mx list is empty" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 300 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy accept condition = ${if match{$acl_m_mta_sts_response_body}{\N\bversion\s*:\s*\N}{no}{yes}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=fail message="badly formatted policy: version not found" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 300 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy warn set acl_m_mta_sts_response_body = ${sg{$acl_m_mta_sts_response_body}{\Nversion\s*:\s*\N}{version=}} set acl_m_mta_sts_version = ${extract{version}{$acl_m_mta_sts_response_body}} accept condition = ${if eq{$acl_m_mta_sts_version}{}{yes}{no}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=fail message="badly formatted policy: version is empty" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 300 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy accept condition = ${if match{$acl_m_mta_sts_version}{\N^\s*STSv\d+\s*$\N}{no}{yes}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=fail message="badly formatted policy: unexpected value of version $acl_m_mta_sts_version" message = $acl_m_mta_sts_policy accept condition = ${if match{$acl_m_mta_sts_response_body}{\N\bmode\s*:\s*\N}{no}{yes}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=fail message="badly formatted policy: mode not found" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 300 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy warn set acl_m_mta_sts_response_body = ${sg{$acl_m_mta_sts_response_body}{\Nmode\s*:\s*\N}{mode=}} set acl_m_mta_sts_mode = ${extract{mode}{$acl_m_mta_sts_response_body}} accept condition = ${if eq{$acl_m_mta_sts_mode}{}{yes}{no}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=fail message="badly formatted policy: mode is empty" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 300 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy accept condition = ${if match{$acl_m_mta_sts_response_body}{\N\bmax_age\s*:\s*\N}{no}{yes}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=fail message="badly formatted policy: max_age not found" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 300 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy warn set acl_m_mta_sts_response_body = ${sg{$acl_m_mta_sts_response_body}{\Nmax_age\s*:\s*\N}{max_age=}} set acl_m_mta_sts_max_age = ${extract{max_age}{$acl_m_mta_sts_response_body}} accept condition = ${if eq{$acl_m_mta_sts_max_age}{}{yes}{no}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=fail message="badly formatted policy: max_age is empty" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 300 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy accept condition = ${if match{$acl_m_mta_sts_max_age}{\N^\s*(\d+)\s*$\N}{no}{yes}} set acl_m_mta_sts_policy = domain=$acl_arg1 id=$acl_arg2 mode=fail message="badly formatted policy: unexpected value of max_age $acl_m_mta_sts_max_age" ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy 300 ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy warn set acl_m_mta_sts_max_age = ${sg{$acl_m_mta_sts_max_age}{\N^\s*(\d+)\s*$\N}{\$1}} warn set acl_m_mta_sts_response_body = ${sg{$acl_m_mta_sts_response_body}{\N\r?\n\N}{ }} warn set acl_m_mta_sts_rua = set acl_m_mta_sts_rua_record = ${lookup dnsdb{>\n; defer_never,txt=_smtp._tls.$acl_arg1}} set acl_m_mta_sts_rua_record = ${sg{$acl_m_mta_sts_rua_record}{;}{; }} condition = ${if match{${extract{v}{$acl_m_mta_sts_rua_record}}}{\N^TLSRPTv1;?\N}{yes}{no}} set acl_m_mta_sts_rua = ${sg{${extract{rua}{$acl_m_mta_sts_rua_record}}}{\N;$\N}{}} warn set acl_m_mta_sts_policy = \ domain=$acl_arg1 \ id=$acl_arg2 \ version=$acl_m_mta_sts_version \ mode=$acl_m_mta_sts_mode \ max_age=$acl_m_mta_sts_max_age \ expires=${eval:$tod_epoch + $acl_m_mta_sts_max_age} \ mx=$acl_m_mta_sts_mx \ rua=$acl_m_mta_sts_rua accept \ ifelse(confMTA_STS_CACHE, `NO', `', `dnl acl = acl_mta_sts_get_policy_http_cache_set $acl_arg1 $acl_m_mta_sts_policy $acl_m_mta_sts_max_age ')dnl ifelse(confMTA_STS_CACHE, `NO', `', `') message = $acl_m_mta_sts_policy acl_mta_sts_get_policy: # acl_arg1 - recipient domain accept condition = ${if eq{$acl_arg1}{}{yes}{no}} warn set acl_m_mta_sts_id_record = ${lookup dnsdb{>\n; defer_never,txt=_mta-sts.$acl_arg1}} accept condition = ${if match{${extract{v}{$acl_m_mta_sts_id_record}}}{\N^STSv1\s*;?\s*\N}{no}{yes}} message = domain=$acl_arg1 mode=none message="Unable to get _mta-sts.$acl_arg1 TXT record or record is empty" accept condition = ${if match{${extract{v}{${sg{$acl_m_mta_sts_id_record}{;}{; }}}}}{\N^STSv1\s*;?\s*\N}{no}{yes}} message = domain=$acl_arg1 mode=none message="STSv1 record not found" warn set acl_m_mta_sts_id = ${sg{${extract{id}{${sg{$acl_m_mta_sts_id_record}{;}{; }}}}}{\N\s*;?\s*$\N}{}} accept condition = ${if eq{$acl_m_mta_sts_id}{}{yes}{no}} message = domain=$acl_arg1 mode=fail message=id not found in _mta-sts.$acl_arg1 TXT record:$acl_m_mta_sts_id_record ifelse(confMTA_STS_CACHE, `MEMCACHED', `dnl define(`confMEMCACHED_ENABLED', `YES')dnl warn set acl_m_mta_sts_policy = ${acl{acl_memcached_get}{confMTA_STS_CACHE_RECORD_PREFIX`'$acl_arg1}} ')dnl ifelse(confMTA_STS_CACHE, `REDIS', `dnl warn set acl_m_mta_sts_policy = ${acl{acl_redis_get}{confMTA_STS_CACHE_RECORD_PREFIX`'$acl_arg1}} ')dnl ifelse(confMTA_STS_CACHE, `SQLITE', `dnl warn set acl_m_mta_sts_policy = ${lookup sqlite,file=confMTA_STS_CACHE_SQLITE_FILE{confMTA_STS_CACHE_SQLITE_GET}} ')dnl ifelse(confMTA_STS_CACHE, `MYSQL', `dnl warn set acl_m_mta_sts_policy = ${lookup mysql{confMTA_STS_CACHE_MYSQL_GET}} ')dnl warn condition = ${if eq{$acl_m_mta_sts_policy}{}{no}{yes}} condition = ${if eq{$acl_m_mta_sts_id}{${extract{id}{$acl_m_mta_sts_policy}}}{no}{yes}} set acl_m_mta_sts_policy = warn condition = ${if eq{$acl_m_mta_sts_policy}{}{no}{yes}} condition = ${if eq{$acl_arg1}{${extract{domain}{$acl_m_mta_sts_policy}}}{no}{yes}} set acl_m_mta_sts_policy = warn condition = ${if eq{$acl_m_mta_sts_policy}{}{no}{yes}} condition = ${if eq{${extract{expires}{$acl_m_mta_sts_policy}}}{}{yes}{no}} set acl_m_mta_sts_policy = warn condition = ${if eq{$acl_m_mta_sts_policy}{}{no}{yes}} condition = ${if match{${extract{expires}{$acl_m_mta_sts_policy}}}{\N^\d+$\N}{yes}{no}} condition = ${if <{${extract{expires}{$acl_m_mta_sts_policy}}}{$tod_epoch}{yes}{no}} set acl_m_mta_sts_policy = warn condition = ${if eq{$acl_m_mta_sts_policy}{}{yes}{no}} set acl_m_mta_sts_policy = ${acl{acl_mta_sts_get_policy_http}{$acl_arg1}{$acl_m_mta_sts_id}} warn log_message = MTA-STS policy for domain $acl_arg1: $acl_m_mta_sts_policy accept message = $acl_m_mta_sts_policy local_expires=${eval:$tod_epoch+confMTA_STS_TTL_LOCAL} acl_mta_sts_get_mode: # acl_arg1 - recipient domain warn condition = ${if eq{$acl_m_mta_sts_policy}{}{yes}{no}} set acl_m_mta_sts_policy = ${acl{acl_mta_sts_get_policy}{$acl_arg1}} warn condition = ${if match{${extract{local_expires}{$acl_m_mta_sts_policy}}}{\N^\d+$\N}{no}{yes}} set acl_m_mta_sts_policy = ${acl{acl_mta_sts_get_policy}{$acl_arg1}} warn condition = ${if <{${extract{local_expires}{$acl_m_mta_sts_policy}}}{$tod_epoch}{yes}{no}} set acl_m_mta_sts_policy = ${acl{acl_mta_sts_get_policy}{$acl_arg1}} warn condition = ${if eq{${extract{domain}{$acl_m_mta_sts_policy}}}{$acl_arg1}{no}{yes}} set acl_m_mta_sts_policy = ${acl{acl_mta_sts_get_policy}{$acl_arg1}} accept message = ${extract{mode}{$acl_m_mta_sts_policy}} acl_mta_sts_get_mx: # acl_arg1 - recipient domain warn condition = ${if eq{$acl_m_mta_sts_policy}{}{yes}{no}} set acl_m_mta_sts_policy = ${acl{acl_mta_sts_get_policy}{$acl_arg1}} warn condition = ${if match{${extract{local_expires}{$acl_m_mta_sts_policy}}}{\N^\d+$\N}{no}{yes}} set acl_m_mta_sts_policy = ${acl{acl_mta_sts_get_policy}{$acl_arg1}} warn condition = ${if <{${extract{local_expires}{$acl_m_mta_sts_policy}}}{$tod_epoch}{yes}{no}} set acl_m_mta_sts_policy = ${acl{acl_mta_sts_get_policy}{$acl_arg1}} warn condition = ${if eq{${extract{domain}{$acl_m_mta_sts_policy}}}{$acl_arg1}{no}{yes}} set acl_m_mta_sts_policy = ${acl{acl_mta_sts_get_policy}{$acl_arg1}} accept message = ${extract{mx}{$acl_m_mta_sts_policy}} acl_mta_sts_check_mx: # acl_arg1 - recipient domain # acl_arg2 - recipient host warn condition = ${if eq{$acl_m_mta_sts_policy}{}{yes}{no}} set acl_m_mta_sts_policy = ${acl{acl_mta_sts_get_policy}{$acl_arg1}} warn condition = ${if eq{${extract{domain}{$acl_m_mta_sts_policy}}}{$acl_arg1}{no}{yes}} set acl_m_mta_sts_policy = ${acl{acl_mta_sts_get_policy}{$acl_arg1}} warn set acl_m_mta_sts_mx = ${extract{mx}{$acl_m_mta_sts_policy}} accept message = ${if forany{$acl_m_mta_sts_mx}{match{$acl_arg2}{\ ${sg{${sg{$item}{\\.}{\\\\.}}}{\\*}{.*}}\ }}{}{0}} ') dnl ifelse(SECTION, `ACLS_ADDITIONAL', `') ifelse(SECTION, `ROUTERS', `dnl dnslookup_mta_sts_enforce: debug_print = "R: dnslookup_mtasts_enforce for $local_part@$domain" driver = dnslookup condition = ${if eq{${acl{acl_mta_sts_get_mode}{$domain}}}{enforce}} transport = remote_smtp_mtasts_enforce domains = ! +local_domains same_domain_copy_routing = yes ignore_target_hosts = confDNSLOOKUP_IGNORE_TARGET_HOSTS ipv4_prefer = yes # dnssec_request_domains = * no_more # no_verify dnslookup_mtasts_testing: debug_print = "R: dnslookup_mtasts_testing for $local_part@$domain" driver = dnslookup condition = ${if eq{${acl{acl_mta_sts_get_mode}{$domain}}}{testing}} transport = remote_smtp_mtasts_testing domains = ! +local_domains same_domain_copy_routing = yes ignore_target_hosts = confDNSLOOKUP_IGNORE_TARGET_HOSTS ipv4_prefer = yes # dnssec_request_domains = * no_more # no_verify ifelse(confMTA_STS_TEST_MODE, `NO', `dnl redirect_mtasts_fail: debug_print = "R: dnslookup_mtasts_fail for $local_part@$domain" driver = redirect condition = ${if eq{${acl{acl_mta_sts_get_mode}{$domain}}}{fail}} domains = ! +local_domains allow_defer data = :defer: MTA-STS Failure $address_data no_more ')dnl ifelse(confMTA_STS_TEST_MODE, `NO', `') ') dnl ifelse(SECTION, `ROUTERS', `') ifelse(SECTION, `TRANSPORTS', `dnl define(`TRANSPORT', `remote_smtp_mtasts_enforce')dnl remote_smtp_mtasts_enforce: debug_print = "T: remote_smtp_mtasts_enforce for $local_part@$domain" driver = smtp hosts_require_tls = * ifelse(confMTA_STS_TEST_MODE, `NO', `dnl tls_tempfail_tryclear = false tls_verify_hosts = * ',`dnl # local testing mode (process "enforce" as "testing" # tls_tempfail_tryclear = false # tls_verify_hosts = * # /local testing mode (process "enforce" as "testing" ')dnl ifelse(confMTA_STS_TEST_MODE, `NO', `') tls_verify_certificates = system # tls_try_verify_hosts = * tls_try_verify_hosts = ${acl{acl_mta_sts_get_mx}{$domain}} # tls_verify_cert_hostnames = ${acl{acl_mta_sts_get_mx}{$domain}} tls_verify_cert_hostnames = * event_action = ${if eq{$event_name}{tcp:connect}{${acl{acl_mta_sts_check_mx}{$domain}{$host}}}{}} ifdef(`confSMTP_AUTH_CLIENT', `ifelse(confSMTP_AUTH_CLIENT, `NO', `', `dnl hosts_try_auth = +hosts_try_auth ')') dnl ifdef(`confFALL_BACK_MX', `ifelse(confFALL_BACK_MX, `NO', `', `dnl define(`_I_',`eval(index(confFALL_BACK_MX,` ') >= 0)')`'ifelse(_I_,`1', ` fallback_hosts = ${sg{confFALL_BACK_MX}{ }{}}', ` fallback_hosts = confFALL_BACK_MX') ')') dnl ifdef(`confFALL_BACK_MX_LOCALHOST_ENABLE', `ifelse(confFALL_BACK_MX_LOCALHOST_ENABLE, `NO', `', `dnl allow_localhost ')') dnl ifdef(`confSMTP_SERIALIZE_HOSTS', `ifelse(confSMTP_SERIALIZE_HOSTS, `NO', `', `dnl serialize_hosts = +serialize_hosts ')') dnl dnl ifdef(`confSTARTTLS_SKIP_USING', `ifelse(confSTARTTLS_SKIP_USING, `NO', `', `dnl dnl hosts_avoid_tls = +skip_tls_using dnl ')') dnl hosts_avoid_tls = ${if match{$address_data}{\N\/avoid_tls\N}{*}{ifdef(`confSTARTTLS_SKIP_USING', `ifelse(confSTARTTLS_SKIP_USING, `NO', `', `+skip_tls_using')')}} dnl sinclude(confSITE_DIR`/configure.smtp_transport_options')dnl sinclude(confSITE_DIR`/configure.remote_smtp_transport_options')dnl dnl ifdef(`confMAIL_BACKUP', `ifelse_strstr(confMAIL_BACKUP, `ROUTER_REDIRECT', `dnl headers_remove = ${if eq{$local_part@$domain}{confMAIL_BACKUP_ADDR}{}{X-Recipients}} ')') dnl dnl ifelse_strstr(confAUTH_RESULTS_ADD, `CUSTOM', `dnl headers_remove = _confAUTH_RESULTS_ADD_CUSTOM_HEADER_ ') dnl ifelse_strstr(confAUTH_RESULTS_ADD, `CUSTOM', `') dnl define(`AUTHENTICATION_RESULTS_REMOVED', `NO')dnl ifelse_strstr(confAUTH_RESULTS_ADD, `DEFAULT', `dnl ifelse_strstr(confARC, `SIGN', `', `dnl headers_remove = Authentication-Results define(`AUTHENTICATION_RESULTS_REMOVED', `YES')dnl ') dnl ifelse_strstr(confARC, `SIGN', `', `') ') dnl ifelse_strstr(confAUTH_RESULTS_ADD, `DEFAULT', `') dnl ifelse(confAUTH_RESULTS_HIDE_ROOT_FORWARD, `REMOTE', `dnl ifelse(AUTHENTICATION_RESULTS_REMOVED, `YES', `', ` # блокировка добавления кастомного и штатного заголовков Authentication-Results при пересылке писем из командной строки от имени пользователя root в исходящих письмах headers_remove = ${if eq{$acl_m_auth_results_hide}{yes}{Authentication-Results}{X-Authentication-Results-Fake}} ')dnl ifelse(AUTHENTICATION_RESULTS_REMOVED, `YES', `', `') ')dnl ifelse(confAUTH_RESULTS_HIDE_ROOT_FORWARD, `REMOTE', `') dnl ifelse(confSMTP_AUTH_RELAY, `NO', `', `dnl headers_remove = X-Warn-Auth-Relay ') dnl define(`TRANSPORT', `')dnl define(`TRANSPORT', `remote_smtp_mtasts_testing')dnl remote_smtp_mtasts_testing: debug_print = "T: remote_smtp_mtasts_testing for $local_part@$domain" driver = smtp hosts_require_tls = * tls_verify_certificates = system # tls_try_verify_hosts = * tls_try_verify_hosts = ${acl{acl_mta_sts_get_mx}{$domain}} # tls_verify_cert_hostnames = ${acl{acl_mta_sts_get_mx}{$domain}} tls_verify_cert_hostnames = * ifdef(`confSMTP_AUTH_CLIENT', `ifelse(confSMTP_AUTH_CLIENT, `NO', `', `dnl hosts_try_auth = +hosts_try_auth ')') dnl ifdef(`confFALL_BACK_MX', `ifelse(confFALL_BACK_MX, `NO', `', `dnl define(`_I_',`eval(index(confFALL_BACK_MX,` ') >= 0)')`'ifelse(_I_,`1', ` fallback_hosts = ${sg{confFALL_BACK_MX}{ }{}}', ` fallback_hosts = confFALL_BACK_MX') ')') dnl ifdef(`confFALL_BACK_MX_LOCALHOST_ENABLE', `ifelse(confFALL_BACK_MX_LOCALHOST_ENABLE, `NO', `', `dnl allow_localhost ')') dnl ifdef(`confSMTP_SERIALIZE_HOSTS', `ifelse(confSMTP_SERIALIZE_HOSTS, `NO', `', `dnl serialize_hosts = +serialize_hosts ')') dnl dnl ifdef(`confSTARTTLS_SKIP_USING', `ifelse(confSTARTTLS_SKIP_USING, `NO', `', `dnl dnl hosts_avoid_tls = +skip_tls_using dnl ')') dnl hosts_avoid_tls = ${if match{$address_data}{\N\/avoid_tls\N}{*}{ifdef(`confSTARTTLS_SKIP_USING', `ifelse(confSTARTTLS_SKIP_USING, `NO', `', `+skip_tls_using')')}} dnl sinclude(confSITE_DIR`/configure.smtp_transport_options')dnl sinclude(confSITE_DIR`/configure.remote_smtp_transport_options')dnl dnl ifdef(`confMAIL_BACKUP', `ifelse_strstr(confMAIL_BACKUP, `ROUTER_REDIRECT', `dnl headers_remove = ${if eq{$local_part@$domain}{confMAIL_BACKUP_ADDR}{}{X-Recipients}} ')') dnl dnl ifelse_strstr(confAUTH_RESULTS_ADD, `CUSTOM', `dnl headers_remove = _confAUTH_RESULTS_ADD_CUSTOM_HEADER_ ') dnl ifelse_strstr(confAUTH_RESULTS_ADD, `CUSTOM', `') dnl define(`AUTHENTICATION_RESULTS_REMOVED', `NO')dnl ifelse_strstr(confAUTH_RESULTS_ADD, `DEFAULT', `dnl ifelse_strstr(confARC, `SIGN', `', `dnl headers_remove = Authentication-Results define(`AUTHENTICATION_RESULTS_REMOVED', `YES')dnl ') dnl ifelse_strstr(confARC, `SIGN', `', `') ') dnl ifelse_strstr(confAUTH_RESULTS_ADD, `DEFAULT', `') dnl ifelse(confAUTH_RESULTS_HIDE_ROOT_FORWARD, `REMOTE', `dnl ifelse(AUTHENTICATION_RESULTS_REMOVED, `YES', `', ` # блокировка добавления кастомного и штатного заголовков Authentication-Results при пересылке писем из командной строки от имени пользователя root в исходящих письмах headers_remove = ${if eq{$acl_m_auth_results_hide}{yes}{Authentication-Results}{X-Authentication-Results-Fake}} ')dnl ifelse(AUTHENTICATION_RESULTS_REMOVED, `YES', `', `') ')dnl ifelse(confAUTH_RESULTS_HIDE_ROOT_FORWARD, `REMOTE', `') dnl ifelse(confSMTP_AUTH_RELAY, `NO', `', `dnl headers_remove = X-Warn-Auth-Relay ') dnl define(`TRANSPORT', `')dnl ') dnl ifelse(SECTION, `TRANSPORTS', `')