dnl dnl Поддержка RSPAMD dnl dnl ВНИМАНИЕ!!! dnl при использовании интеграции с rspamd необходимо включить использование dnl системного фильтра (см. параметр confSYSTEM_FILTER) dnl dnl команда получения названия и версии демона RSPAMD dnl define(`confRSPAMD_NAME_VERSION', `pkg_info -I rspamd\* | perl -p -e "s/^rspamd-(\S+).+\$/\$1/;s/\n//;"') dnl define(`confRSPAMD_NAME_VERSION_DEFAULT', `rspamd --help | grep -i rspamd | grep version | perl -p -e "s/^\s+//;s/\n//;"') dnl dnl параметры подключения к RSPAMD dnl define(`confRSPAMD_ADDRESS', `127.0.0.1 11333') dnl dnl действие в случае отсутствия ответа от RSPAMD либо возврата кода ошибки dnl NO - возвращать клиенту 4xx dnl YES - продолжать обработку письма dnl define(`confRSPAMD_DEFER_OK', `YES') dnl dnl действие для писем, опознанных как SPAM dnl REJECT - отказ в приеме письма (возврат клиенту кода 5xx) dnl DENY - синоним для REJECT dnl DROP - отказ в приеме сообщения с обрывом соединения dnl DISCARD - прием письма без доставки получателю dnl QUARANTINE - вывод в лог файл предупреждения и помещение письма в карантин dnl QUARANTINE_MAILLIST - сохранение в карантине писем из списков рассылки вместо отказа в приеме письма dnl (используется только одновременно с REJECT) dnl DISCARD_MAILLIST - игнорирование писем из списков рассылки вместо отказа в приеме письма dnl (используется только одновременно с REJECT) dnl define(`confRSPAMD_ACTION', `NO')dnl dnl если не будут указаны действия REJECT, DROP или DISCARD, то письмо будет просто помечено dnl действие QUARANTINE можно указывать вместо с REJECT и DISCARD через пробел dnl действия QUARANTINE_MAILLIST и DISCARD_MAILLIST можно указывать вместе с REJECT и DROP dnl dnl сообщение полностью исключается из проверки, если в значении $acl_m_wl_flag_msg dnl поля white_list_relays, white_list_senders или white_list_compat равны 1 dnl и поле spam_hater не равно 1 dnl dnl действие для старых заголовков dnl RENAME - переименование старых заголовков (в конец имени добавляется -Old) dnl REMOVE - удаление старых заголовков dnl NOTHING - оставлять заголовки без изменений dnl define(`confRSPAMD_OLD_HEADERS', `RENAME')dnl dnl dnl заголовки RSPAMD dnl define(`confRSPAMD_HEADERS', `:X-Rspamd-Info:X-Rspamd-Protocol-Version:X-Rspamd-Urls:X-Rspamd-Status:X-Rspamd-Score:X-Rspamd-Report') dnl ifelse(SECTION, `ACLS_ADDITIONAL', `dnl acl_check_data_rspamd: warn set acl_m0 = ${dlfunc{confDLFUNC_PATH/confDLFUNC_FNAME}{rspamd}\ {confRSPAMD_ADDRESS}{defer_ok}} # добавляем информацию о версии RSPAMD warn add_header = X-Rspamd-Version: _RSPAMD_VER_ on $primary_hostname\n warn condition = ${if eq{$acl_m0}{}{yes}{no}} log_message = RSPAMD connection failes add_header = X-Rspamd-Info: RSPAMD check failed on $primary_hostname set acl_m_contentscan_result = defer warn condition = ${if eq{$acl_m0}{RSPAMD answer: }{yes}{no}} log_message = RSPAMD returned empty answer add_header = X-Rspamd-Info: returned empty answer on $primary_hostname set acl_m0 = set acl_m_contentscan_result = defer warn set acl_m0 = ${sg{${sg{$acl_m0}{\r\n}{\n}}}{\N\n+$\N}{\n}} warn condition = ${if match{$acl_m0}{\N^rspamd dlfunc:\s*\N}{yes}{no}} log_message = RSPAMD connection deferred: ${sg{$acl_m0}{\N^rspamd dlfunc:\s*\N}{}} add_header = X-Rspamd-Info: RSPAMD connection deferred on $primary_hostname: ${sg{$acl_m0}{\N^rspamd dlfunc:\s*\N}{}} set acl_m0 = set acl_m_contentscan_result = defer warn condition = ${if eq{$acl_m0}{}{no}{yes}} set acl_m1 = ${if match{$acl_m0}\ {\N^RSPAMD answer: RSPAMD/(\S+) 0 EX_OK\N}{$1}{}} # logwrite = RSPAMD check: RSPAMD protocol version: ${if eq{$acl_m1}{}{not found}{$acl_m1}} add_header = X-Rspamd-Protocol-Version: ${if eq{$acl_m1}{}{not found}{$acl_m1}} set acl_m0 = ${sg{$acl_m0}{\N^RSPAMD answer: RSPAMD/.+?\n\N}{}} warn condition = ${if eq{$acl_m0}{}{no}{yes}} set acl_m1 = ${if match{$acl_m0}{\N^((.+?\n)*?)Urls: ([^\n]*)\N}{$3}{}} set acl_m0 = ${if match{$acl_m0}{\N^((.+?\n)*?)Urls: ([^\n]*)\n((.*\n)*)$\N}{$1$4}{$acl_m0}} set acl_m1 = ${sg{$acl_m1}{\N, $\N}{}} condition = ${if eq{$acl_m1}{}{no}{yes}} # logwrite = RSPAMD check: RSPAMD Urls: $acl_m1 add_header = X-Rspamd-Urls: $acl_m1 warn condition = ${if eq{$acl_m0}{}{no}{yes}} set acl_m1 = ${if match{$acl_m0}{\N^((.+?\n)*?)Emails: ([^\n]*)\N}{$3}{}} set acl_m0 = ${if match{$acl_m0}{\N^((.+?\n)*?)Emails: ([^\n]*)\n((.*\n)*)$\N}{$1$4}{$acl_m0}} set acl_m1 = ${sg{$acl_m1}{\N, $\N}{}} condition = ${if eq{$acl_m1}{}{no}{yes}} # logwrite = RSPAMD check: RSPAMD Emails: $acl_m1 add_header = X-Rspamd-Emails: $acl_m1 warn condition = ${if eq{$acl_m0}{}{no}{yes}} set acl_m1 = ${if match{$acl_m0}{\N^((.+?\n)*?)Message-ID: ([^\n]*)\N}{$3}{}} set acl_m0 = ${if match{$acl_m0}{\N^((.+?\n)*?)Message-ID: ([^\n]*)\n((.*\n)*)$\N}{$1$4}{$acl_m0}} set acl_m1 = ${sg{$acl_m1}{\N, $\N}{}} condition = ${if eq{$acl_m1}{}{no}{yes}} # logwrite = RSPAMD check: RSPAMD Message-ID: $acl_m1 add_header = X-Rspamd-Message-ID: $acl_m1 warn set acl_m_certainly_spam = set acl_m_rspamd_status = set acl_m_rspamd_score = condition = ${if eq{$acl_m0}{}{no}{yes}} acl = acl_process_rspamd_answer warn condition = ${if match{$acl_m_rspamd_status}{Spam}{yes}{no}} set acl_m_rspamd_status = Spam add_header = X-Rspamd-Status: Spam logwrite = RSPAMD check: Status is Spam set acl_m_certainly_spam = certainly_spam warn condition = ${if match{$acl_m_rspamd_status}{Probably spam}{yes}{no}} set acl_m_rspamd_status = Probably spam add_header = X-Rspamd-Status: Probably spam logwrite = RSPAMD check: Status is Probably spam warn condition = ${if match{$acl_m_rspamd_status}{Ham}{yes}{no}} set acl_m_rspamd_status = Ham add_header = X-Rspamd-Status: Ham logwrite = RSPAMD check: Status is Ham warn condition = ${if match{$acl_m_rspamd_status}{unknown}{yes}{no}} set acl_m_rspamd_status = unknown add_header = X-Rspamd-Status: unknown logwrite = RSPAMD check: Status unknown warn condition = ${if eq{$acl_m_rspamd_score}{}{no}{yes}} condition = ${if eq{${extract{2}{:}{$acl_m_rspamd_score}}}{}{yes}{no}} add_header = X-Rspamd-Score: $acl_m_rspamd_score logwrite = RSPAMD score $acl_m_rspamd_score accept acl_process_rspamd_answer: accept condition = ${if eq{$acl_m0}{}{yes}{no}} warn set acl_m2 = ${sg{$acl_m0}{\N^(Metric:(?:.+?\n)+?)(Metric:(?:.+\n)+)*$\N}{\$1}} accept condition = ${if eq{$acl_m2}{}{yes}{no}} warn condition = ${if eq{$acl_m0}{acl_m2}{yes}{no}} set acl_m0 = warn set acl_m0 = ${sg{$acl_m0}{\N^(Metric:(?:.+?\n)+?)(Metric:(?:.+\n)+)*$\N}{\$2}} warn set acl_m3 = warn set acl_m1 = ${if match{$acl_m2}{\N^(?:.*?\n)*?Action:\s*(.+?)\n\N}{$1}{}} set acl_m3 = ${if eq{$acl_m1}{}{unknown}{\ ${if eq{$acl_m1}{reject}{Spam}{\ ${if eq{$acl_m1}{soft reject}{Probably spam}{\ ${if eq{$acl_m1}{rewrite subject}{Probably spam}{\ ${if eq{$acl_m1}{add header}{Probably spam}{\ ${if eq{$acl_m1}{greylist}{Probably spam}{\ ${if eq{$acl_m1}{no action}{Ham}{unknown}}\ }}\ }}\ }}\ }}\ }}\ }} set acl_m_rspamd_status = ${if eq{$acl_m_rspamd_status}{}{}{$acl_m_rspamd_status:}}${acl_m3} logwrite = RSPAMD check: RSPAMD status: $acl_m3 warn condition = ${if eq{$acl_m3}{}{no}{yes}} condition = ${if eq{$acl_m3}{unknown}{no}{yes}} set acl_m2 = ${sg{$acl_m2}{${expand:Action: $acl_m1}}{${expand:Status: $acl_m3}}} warn set acl_m1 = ${if match{$acl_m2}{\N^Metric: [^;]+?; (\S+?); (-?\d+\.\d+ / \d+\.\d+ / \d+\.\d+)\N}{$2}{}} set acl_m_rspamd_score = ${if eq{$acl_m_rspamd_score}{}{}{$acl_m_rspamd_score:}}${acl_m1} logwrite = RSPAMD check: RSPAMD scores: ${if eq{$acl_m1}{}{not found}{$acl_m1}} warn logwrite = RSPAMD check: RSPAMD report: ${if eq{$acl_m2}{}{not found}{$acl_m2}} add_header = X-Rspamd-Report: ${sg{$acl_m2}{\N\n(.)\N}{\n\t\$1}} warn acl = acl_process_rspamd_answer accept ') dnl ifelse(SECTION, `ACLS_ADDITIONAL', `') ifelse(SECTION, `ACL_CHECK_DATA_TOP', `dnl ifelse(confRSPAMD_OLD_HEADERS, `REMOVE', `dnl warn remove_header = confRSPAMD_HEADERS ') dnl ifelse(confRSPAMD_OLD_HEADERS, `REMOVE', `') ifelse(confRSPAMD_OLD_HEADERS, `RENAME', `dnl warn remove_header = confRSPAMD_HEADERS RENAME_HEADERS(confRSPAMD_HEADERS) ') dnl ifelse(confRSPAMD_OLD_HEADERS, `RENAME', `') ') dnl ifelse(SECTION, `ACL_CHECK_DATA_TOP', `') ifelse(SECTION, `ACL_CHECK_DATA', `dnl # RSPAMD ifdef(`confRSPAMD_NAME_VERSION',`define(`_RSPAMD_VER_', `esyscmd(confRSPAMD_NAME_VERSION)')',`define(`_RSPAMD_VER_', `esyscmd(confRSPAMD_NAME_VERSION_DEFAULT)')')dnl ifelse(len(X`'_RSPAMD_VER_), `1', `ifdef(`confRSPAMD_NAME_VERSION_DEFAULT',`define(`_RSPAMD_VER_', confRSPAMD_NAME_VERSION_DEFAULT)',`define(`_RSPAMD_VER_', `RSPAMD')')')dnl warn condition = ${if eq{$acl_m_contentscan_skip}{skip}{no}{yes}} acl = acl_check_data_rspamd warn set acl_m0 = condition = ${if eq{$acl_m_contentscan_skip}{skip}{no}{yes}} condition = ${if eq{$acl_m_contentscan_result}{defer}{no}{yes}} condition = ${if eq{$acl_m_certainly_spam}{certainly_spam}{yes}{no}} set acl_m0 = certainly_spam add_header = X-Spam-Original-Recipients: $recipients\n dnl ifelse_strstr(confRSPAMD_ACTION, `SUBMIT_GREYLIST', `ENTERPRISE(`greylist', `submit_rspamd')') dnl ifelse_strstr(confRSPAMD_ACTION, `SUBMIT_MYSQL', `ENTERPRISE(`mysql', `submit_rspamd')') dnl ifelse_strstr(confRSPAMD_ACTION, `SUBMIT_SQLITE', `ENTERPRISE(`sqlite', `submit_rspamd')') ifdef(`confRSPAMD_DEFER_OK', `ifelse(confRSPAMD_DEFER_OK, `YES', `dnl warn condition = ${if eq{$acl_m_contentscan_skip}{skip}{no}{yes}} condition = ${if eq{$acl_m_contentscan_result}{defer}{yes}{no}} # add_header = X-Rspamd-Info: RSPAMD connection deferred on $primary_hostname\n # log_message = RSPAMD connection deferred ', ` dnl ifdef(`confRSPAMD_DEFER_OK', `ifelse(confRSPAMD_DEFER_OK, `YES', `')') defer condition = ${if eq{$acl_m_contentscan_skip}{skip}{no}{yes}} condition = ${if eq{$acl_m_contentscan_result}{defer}{yes}{no}} message = System busy. Try again later # log_message = RSPAMD connection deferred ')') dnl ifdef(`confRSPAMD_DEFER_OK', `ifelse(confRSPAMD_DEFER_OK, `YES', `')') dnl define(`confRSPAMD_ACTION', confRSPAMD_ACTION` ') ifelse_strstr(confRSPAMD_ACTION` ', `REJECT ', ` dnl ifelse_strstr(confRSPAMD_ACTION` ', `QUARANTINE_MAILLIST ', ` # Quarantine spam messages warn condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} condition = ${if or{{!eq{$h_List-Id:}{}}{eq{$h_Precedence:}{list}}}{yes}{no}} logwrite = Spam is blocked and quarantined set acl_m_quarantined = $acl_m_quarantined content_scanner add_header = X-Spam-Action: quarantined\n accept condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} condition = ${if or{{!eq{$h_List-Id:}{}}{eq{$h_Precedence:}{list}}}{yes}{no}} logwrite = original recipients: $recipients ') dnl ifelse_strstr(confRSPAMD_ACTION` ', `QUARANTINE_MAILLIST ', `') dnl ifelse_strstr(confRSPAMD_ACTION` ', `DISCARD_MAILLIST ', ` # Discard spam messages discard condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} condition = ${if or{{!eq{$h_List-Id:}{}}{eq{$h_Precedence:}{list}}}{yes}{no}} logwrite = Spam is discarded ') dnl ifelse_strstr(confRSPAMD_ACTION` ', `DISCARD_MAILLIST ', `') dnl ifelse_strstr(confRSPAMD_ACTION` ', `QUARANTINE ', ` # Reject and quarantine spam messages warn condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} control = fakereject/Spam is blocked (${message_id}) logwrite = Spam is blocked and quarantined set acl_m_quarantined = $acl_m_quarantined content_scanner add_header = X-Spam-Action: quarantined\n accept condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} logwrite = original recipients: $recipients ',` dnl ifelse_strstr(confRSPAMD_ACTION` ', `QUARANTINE ', `') # Reject spam messages deny condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} logwrite = Spam is rejected message = Spam is blocked (${message_id}) ') dnl ifelse_strstr(confRSPAMD_ACTION` ', `QUARANTINE ', `') ') dnl ifelse_strstr(confRSPAMD_ACTION` ', `REJECT ', `') ifelse_strstr(confRSPAMD_ACTION` ', `DROP ', ` dnl ifelse_strstr(confRSPAMD_ACTION` ', `QUARANTINE_MAILLIST ', ` # Quarantine spam messages warn condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} condition = ${if or{{!eq{$h_List-Id:}{}}{eq{$h_Precedence:}{list}}}{yes}{no}} logwrite = Spam is blocked and quarantined set acl_m_quarantined = $acl_m_quarantined content_scanner add_header = X-Spam-Action: quarantined\n accept condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} condition = ${if or{{!eq{$h_List-Id:}{}}{eq{$h_Precedence:}{list}}}{yes}{no}} logwrite = original recipients: $recipients ') dnl ifelse_strstr(confRSPAMD_ACTION` ', `QUARANTINE_MAILLIST ', `') dnl ifelse_strstr(confRSPAMD_ACTION` ', `DISCARD_MAILLIST ', ` # Discard spam messages discard condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} condition = ${if or{{!eq{$h_List-Id:}{}}{eq{$h_Precedence:}{list}}}{yes}{no}} logwrite = Spam is discarded ') dnl ifelse_strstr(confRSPAMD_ACTION` ', `DISCARD_MAILLIST ', `') dnl # Drop spam messages drop condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} logwrite = Spam is rejected message = Spam is blocked (${message_id}) ') dnl ifelse_strstr(confRSPAMD_ACTION` ', `REJECT ', `') ifelse_strstr(confRSPAMD_ACTION` ', `DISCARD ', ` ifelse_strstr(confRSPAMD_ACTION` ', `QUARANTINE ', ` # Discard and quarantine spam messages warn condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} logwrite = Spam is quarantined set acl_m_quarantined = $acl_m_quarantined content_scanner add_header = X-Spam-Action: quarantined\n accept condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} logwrite = original recipients: $recipients ',` dnl ifelse_strstr(confRSPAMD_ACTION` ', `QUARANTINE ', `') # Discard spam messages discard condition = ${if eq{$acl_m0}{certainly_spam}{yes}{no}} logwrite = Spam is discarded ') dnl ifelse_strstr(confRSPAMD_ACTION` ', `QUARANTINE ', `') ') dnl ifelse_strstr(confRSPAMD_ACTION` ', `DISCARD ', `') ') dnl ifelse(SECTION, `ACL_CHECK_DATA', `')