dnl dnl Проверка HELO в черном списке dnl dnl NO - не проводить проверку dnl DROP - возврат клиенту кода 5xx и обрыв соединения dnl REJECT - возврат клиенту кода 5xx dnl DEFER - возврат клиенту кода 4xx dnl WARN - вывод в лог файл предупреждения dnl QUARANTINE - принять письмо с сохранением в карантин без доставки получателям dnl PAUSE:XX - пауза XX секунд dnl GREYLIST:XX - добавить XX баллов к счетчику опционального greylisting'а dnl REJECT:XX - добавить XX баллов к счетчику опционального reject'а dnl define(`confCHECK_ACCESS_HELO', `WARN')dnl dnl dnl действия PAUSE:XX, GREYLIST:XX, REJECT:XX можно указывать через пробел с dnl другими действиями dnl dnl черный список HELO находится в файле confCONFDIR/access-helo в виде: dnl helo : action : message : log_message dnl dnl возможные значения для action: dnl ok - исключение из проверки для указанного helo dnl warn - вывод в лог файл предупреждения dnl reject - отказ в приеме сообщения dnl deny - синоним для reject dnl defer - возврат временной ошибки dnl quarantine - принять письмо с сохранением в карантин без доставки получателям dnl delay=zz - задержка на zz секунд перед продолжением обработки сообщения dnl pause=zz - синоним delay=zz dnl greylist=X - добавление X баллов к счетчику опционального грейлистинга dnl reject=X - добавление X баллов к счетчику опционального reject'а dnl submit_mysql - занесение записи о хосте в базу MySQL dnl submit_sqlite - занесение записи о хосте в базу SQLite dnl submit_rbl - занесение записи о хосте в DNSBL dnl dnl если action отсутствует, то будет использовано значение из confCHECK_ACCESS_HELO dnl dnl message - ответ SMTP клиенту (может отсутствовать) dnl log_message - сообщение в лог файл (может отсутствовать) dnl dnl пример: dnl [127.0.0.1] : deny : Invalid greeting used dnl localhost : deny : Invalid greeting used dnl [194.183.174.249] : deny : Invalid greeting used dnl domain.tld : deny : Invalid greeting used dnl \N^.+\.localhost\N : deny : Invalid greeting used dnl localhost.localdomain : deny : Invalid greeting used dnl compuserv.com : deny : Invalid greeting used dnl microsoft.com : deny : Invalid greeting used dnl QRJATIDY : deny : Invalid greeting used : helo blacklisted dnl QRJATYDI : deny : Invalid greeting used dnl dnl \N^[^\.]+\N : deny : Invalid greeting used : HELO without point dnl \N^\.$\N : deny : Invalid greeting used : HELO with only point dnl \N\.\.\N : deny : Invalid greeting used : HELO with double point dnl \N^\.\N : deny : Invalid greeting used : HELO begins with point dnl \N^[^\.]+\.$\N : deny : Invalid greeting used : HELO ends with point dnl \N^<.*>$\N : deny : Invalid greeting used dnl \N^<.+$\N : deny : Invalid greeting used dnl \N^.+>$\N : deny : Invalid greeting used dnl \N^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$\N : deny : Invalid greeting used : HELO used IP address dnl \N^.*\@.*$\N : deny : Invalid greeting used : @ found in HELO/EHLO dnl *.in-addr.arpa : deny : Invalid greeting used dnl \N^.+\.in-addr\.arpa\..+$\N : deny : Invalid greeting used dnl dnl для следующих проверок необходимо, чтобы helo_allow_chars содержал символы _|:/ dnl \N^.*_.*$\N : deny : Access denied. Underscores in HELO are not permitted by RFC2821. Fix your broken mail server and try again dnl \N^.*\|.*$\N : deny : Pipe found in HELO/EHLO dnl \N^.*http://.*$\N : deny : HTTP url found in HELO/EHLO dnl dnl ifelse(confCHECK_ACCESS_HELO, `YES', `define(`confCHECK_ACCESS_HELO', `REJECT')') # Проверка наличия HELO в черном списке # в т. ч. проверка HELO в виде имени хоста, принадлежащего к dial-up/dsl/cable сетям warn set acl_m1 = set acl_m0 = ${lookup{$sender_host_address}\ iplsearch{CONFDIR/access-helo}\ {${if eq{$value}{}{confCHECK_ACCESS_HELO}{$value}}}\ {\ ${lookup{$sender_helo_name}\ wildlsearch{CONFDIR/access-helo}\ {${if eq{$value}{}{confCHECK_ACCESS_HELO}{$value}}}\ {no}}\ }} condition = ${if eq{$acl_m0}{no}{no}{yes}} set acl_m0 = ${if match{$acl_m0}{\N.+(lookup |\$\{|[\{\}])\N}{${expand:$acl_m0}}{$acl_m0}} acl = acl_normalize_action "${extract{1}{:}{$acl_m0}}" set acl_m1 = ${sg{$acl_m_normalize_action_result }{\N\b([^=\s\d]+)(\s)\N}{\$1=00\$2}} # message = $acl_m2 # log_message = $acl_m0 set acl_m2 = ${expand:${sg{${extract{2}{:}{$acl_m0}}}{\N^\s+\N}{}}} set acl_m0 = ${expand:${sg{${extract{3}{:}{$acl_m0}}}{\N^\s+\N}{}}} set acl_m_check_helo_msg = ${if eq{$acl_m0}{}{${if eq{$acl_m2}{}{}{: $acl_m2}}}{: $acl_m0}} set acl_m0 = ${if eq{$acl_m0}{}{helo $sender_helo_name blacklisted${if eq{$acl_m2}{}{}{: $acl_m2}}}{$acl_m0}} set acl_m2 = ${if eq{$acl_m2}{}{Invalid greeting used}{$acl_m2}} ifdef(`confENTERPRISE_USER', `dnl warn condition = ${if match{$acl_m1}{submit_mysql}{yes}{no}} ENTERPRISE(`mysql', `submit', `helo', `blacklisted', `$sender_helo_name', `0') warn condition = ${if match{$acl_m1}{submit_sqlite}{yes}{no}} ENTERPRISE(`sqlite', `submit', `helo', `blacklisted', `$sender_helo_name', `0') warn condition = ${if match{$acl_m1}{submit_rbl}{yes}{no}} dnl ENTERPRISE(`rbl', `update', `mx.org.ua', `helo.rbl.mx.org.ua', `blacklisted', `$sender_helo_name') ENTERPRISE(`rbl', `submit', `helo', `blacklisted', `$sender_helo_name') ') dnl # warning warn condition = ${if match{$acl_m1}{warn}{yes}{no}} add_header = X-Warn-HELO-Blacklisted: HELO $sender_helo_name is blacklisted${acl_m_check_helo_msg} log_message = $acl_m0${if eq{${extract{pause}{$acl_m1}}}{}{}{: message delayed for ${extract{pause}{$acl_m1}}s}} # pause warn condition = ${if eq{${extract{pause}{$acl_m1}}}{}{no}{yes}} delay = ${extract{pause}{$acl_m1}}s set acl_m_spam_action = ${acl_m_spam_action}\t\ delay=${extract{pause}{$acl_m1}}s\t\t\ $acl_m0\n # quarantine and reject accept condition = ${if eq{${extract{quarantine}{$acl_m1}}}{00}{yes}{no}} condition = ${if eq{${extract{reject}{$acl_m1}}}{00}{yes}{no}} log_message = message will be quarantined and rejected: sender helo $sender_helo_name blacklisted${acl_m_check_helo_msg} set acl_m_fakereject = \ message will be quarantined and rejected: sender helo $sender_helo_name blacklisted${acl_m_check_helo_msg}\ |X-Quarantine-HELO: sender helo $sender_helo_name blacklisted${acl_m_check_helo_msg}\ |$acl_m2 set acl_m_add_x_orig_rcpt = yes set acl_m_quarantined = $acl_m_quarantined envelope # quarantine and !reject warn condition = ${if eq{${extract{quarantine}{$acl_m1}}}{00}{yes}{no}} condition = ${if eq{${extract{reject}{$acl_m1}}}{00}{no}{yes}} add_header = X-Quarantine-HELO: sender helo $sender_helo_name blacklisted${acl_m_check_helo_msg} log_message = message will be quarantined: sender helo $sender_helo_name blacklisted${acl_m_check_helo_msg} set acl_m_add_x_orig_rcpt = yes set acl_m_quarantined = $acl_m_quarantined envelope accept condition = ${if eq{${extract{quarantine}{$acl_m1}}}{00}{yes}{no}} condition = ${if eq{${extract{reject}{$acl_m1}}}{00}{no}{yes}} # !quarantine and reject deny condition = ${if eq{${extract{reject}{$acl_m1}}}{00}{yes}{no}} condition = ${if eq{${extract{quarantine}{$acl_m1}}}{00}{no}{yes}} log_message = $acl_m0 message = $acl_m2 # Defer в случае принадлежности HELO к blacklisted сетям # Defer if sender HELO in blacklisted network defer condition = ${if match{$acl_m1}{defer}{yes}{no}} message = $acl_m2 log_message = $acl_m0 # Drop в случае принадлежности HELO к blacklisted сетям # Drop if sender HELO in blacklisted network drop condition = ${if match{$acl_m1}{drop}{yes}{no}} message = $acl_m2 log_message = $acl_m0 ifelse(confGREYLIST, `OPTIONAL', `dnl # greylist в случае принадлежности HELO к blacklisted сетям # greylist if sender HELO in blacklisted network warn condition = ${if eq{${extract{greylist}{$acl_m1}}}{}{no}{yes}} set acl_m_optional_greylist = \ scores=${eval:${extract{scores}{$acl_m_optional_greylist}}+${extract{greylist}{$acl_m1}}} \ log_message="${extract{log_message}{$acl_m_optional_greylist}} $acl_m0;" set acl_m_spam_action = ${acl_m_spam_action}\t\ greylist scores=${extract{greylist}{$acl_m1}}\t\ $acl_m0\n ') dnl ifelse(confGREYLIST, `OPTIONAL', `') ifdef(`confOPTIONAL_REJECT', `ifelse(confOPTIONAL_REJECT, `NO', `dnl', `dnl # optional reject в случае принадлежности HELO к blacklisted сетям # optional reject if sender HELO in blacklisted network warn condition = ${if eq{${extract{reject}{$acl_m1}}}{}{no}{yes}} condition = ${if eq{${extract{reject}{$acl_m1}}}{00}{no}{yes}} set acl_m_optional_reject = \ scores=${eval:${extract{scores}{$acl_m_optional_reject}}+${extract{reject}{$acl_m1}}} \ log_message="${extract{log_message}{$acl_m_optional_reject}} $acl_m0;" set acl_m_spam_action = ${acl_m_spam_action}\t\ reject scores=${extract{reject}{$acl_m1}}\t\t\ $acl_m0\n ')') dnl ifdef(`confOPTIONAL_REJECT', `ifelse(confOPTIONAL_REJECT, `NO', `', `')')