dnl dnl Проверка комбинации адреса отправителя и получателя dnl dnl NO - не проводить проверку dnl REJECT - возврат клиенту кода 5xx dnl REJECT_ALL - отказ в приеме письма для всех получателей dnl QUARANTINE - принять письмо с сохранением в карантин без доставки получателям dnl QUARANTINE_OTHER - при отказе в приеме письма текущему получателю и наличии других получателей dnl письмо доставляется в карантин без доставки этим остальным получателям dnl DEFER - возврат клиенту кода 451 dnl WARN - вывод в лог файл предупреждения dnl GREYLIST:XX - добавить XX баллов к счетчику опционального грейлистинга dnl REJECT:XX - добавить XX баллов к счетчику опционального reject'а dnl DELAY:XX - задержка XX секунд перед ответом на RCPT TO dnl define(`confCHECK_COMPAT', `NO')dnl dnl dnl место хранения списков доступа dnl TEXT - хранение списков доступа в access-compat dnl DBM - хранение списков доступа в dbm файле dnl SQLITE - хранение списков доступа в БД SQLite dnl MYSQL - хранение списков доступа в БД MySQL dnl define(`confCHECK_COMPAT_BACKEND', `TEXT')dnl dnl dnl при TEXT в confCHECK_COMPAT_BACKEND: dnl dnl комбинации адресов отправителей и получателей указываются в файле CONFDIR/access-compat dnl в виде: dnl sender_mailbox@sender.domain<@>rcpt_mailbox@rcpt.domain : действие : сообщение dnl dnl в качестве "действия" могут быть использованы: dnl ok - принимать сообщения с данной парой mail from и rcpt to dnl whitelist - исключить из проверок пары адресов отправителя и получателя dnl warn - выдача предупреждения в лог файл и в заголовки письма dnl и добавление в заголовки сообщения поле X-Warn-Compat dnl текст сообщения об ошибке может быть указан через двоеточие dnl deny или reject - отказ в приеме сообщения dnl reject_all - отказ в приеме письма для всех получателей dnl quarantine - принять письмо с сохранением в карантин без доставки получателям dnl quarantine_other - при отказе в приеме письма текущему получателю и наличии других получателей dnl письмо доставляется в карантин без доставки этим остальным получателям dnl drop - отказ в приеме сообщения с обрывом соединения dnl discard - прием письма без доставки получателю dnl defer - возврат временной ошибки отправителю dnl greylist:xx - добавление xx баллов к счетчику опционального greylisting'а dnl greylisting:xx - синоним greylist:xx dnl reject:yy - добавление yy баллов к счетчику опционального reject'а dnl deny:yy - синоним reject:yy dnl delay:zz - задержка на zz секунд перед продолжением обработки сообщения dnl pause:zz - синоним delay:zz dnl submit_mysql - занесение записи о хосте в базу MySQL (только в enterprise версии) dnl submit_sqlite - занесение записи о хосте в базу SQLite (только в enterprise версии) dnl submit_rbl - занесение записи о хосте в DNSBL (только в enterprise версии) dnl dnl если в файле CONFDIR/access-compat будет отсутствовать поле "действие", dnl то будет выполнено действие по умолчанию из переменно confCHECK_COMPAT dnl поле "сообщение" может отсутствовать dnl dnl в адресе отправителя в левой части допустимо использование масок: dnl *@sender.domain<@>rcpt_mailbox@rcpt.domain : deny : Access denied dnl dnl допустимо использование регулярных выражений: dnl \N^<@>(hostmaster|ftpmaster)@rcpt\.domain$\N : deny : Null sender rejected. Thist is incoming address only. dnl dnl если доставка производится в unix mailbox'ы, то возможно указание dnl только почтового ящика в качестве адреса получателя, если домен dnl получателя входит в список локальных доменов dnl dnl примеры: dnl <@>hostmaster@domain.tld : deny : Null sender rejected. Thist is incoming address only. dnl a@b.c<@>hostmaster@domain.tld : warn dnl *@b.c<@>hostmaster@domain.tld : drop dnl *<@>hostmaster@domain.tld : warn dnl \N^<@>.+@domain.tld\N : deny dnl \N^a@b.c<@>.+@domain.tld\N : warn dnl \N^.+@b.c<@>.+@domain.tld\N : defer dnl \N^.+<@>.+@domain.tld\N : warn dnl *@sender.domain<@>user1 : reject dnl dnl при DBM в confCHECK_COMPAT_BACKEND: dnl dnl ключи записи в DBM файле и значение записи такие же, как для TEXT файлов dnl исключением является возможность в поле действия указать время жизни записи в виде expires="время в unixtime" dnl это поле может использоваться для автоматически формируемых временных персональных whitelist'ов dnl dnl путь к DBM файлу dnl define(`confCHECK_COMPAT_DBM_FILE', `/var/spool/exim/db/access-compat.dbm')dnl dnl ключ записи DBM файла указывается в виде: dnl адрес_отправителя<@>адрес_получателя dnl значение записи DBM файла указывается в виде: dnl expires="время в unixtime" action="действие" message="сообщение smtp клиенту" log_message="сообщение в файл протокола" dnl поле expires может отсуствовать, оно может использоваться для автоматически формируемых временных white lists dnl dnl при SQLITE в confCHECK_COMPAT_BACKEND: dnl dnl путь к файлу sqlite dnl define(`confCHECK_COMPAT_SQLITE_FILE', `/var/spool/exim/db/access_list.db')dnl dnl запрос к БД SQLite dnl define(`confCHECK_COMPAT_SQLITE_QUERY', `SELECT action FROM access_list WHERE recipient="${quote_sqlite:$local_part@$domain}" AND sender="${quote_sqlite:$sender_address}"')dnl dnl второй запрос к БД SQLite (опциональный) dnl define(`confCHECK_COMPAT_SQLITE_QUERY2', `SELECT action FROM access_list WHERE recipient="${quote_sqlite:$local_part@$domain}" AND sender="${quote_sqlite:$sender_address_local_part@}"')dnl dnl dnl при MYSQL в confCHECK_COMPAT_BACKEND: dnl dnl запрос к БД MySQL dnl define(`confCHECK_COMPAT_MYSQL_QUERY', `SELECT action FROM access_list WHERE recipient="${quote_mysql:$local_part@$domain}" AND sender="${quote_mysql:$sender_address}"')dnl dnl второй запрос к БД MySQL (опциональный) dnl define(`confCHECK_COMPAT_MYSQL_QUERY2', `SELECT action FROM access_list WHERE recipient="${quote_mysql:$local_part@$domain}" AND sender="${quote_mysql:$sender_address_local_part@}"')dnl dnl ifelse(confCHECK_COMPAT, `YES', `define(`confCHECK_COMPAT', `REJECT')') # Проверка комбинации адреса отправителя и получателя warn set acl_m1 = set acl_m0 = ifelse_strstr(confCHECK_COMPAT_BACKEND, `DBM', ` warn condition = ${if eq{$acl_m0}{}{yes}{no}} set acl_m0 = ${lookup{$sender_address<@>$local_part@$domain}dbm{confCHECK_COMPAT_DBM_FILE}\ {${if eq{$value}{}{confCHECK_COMPAT}{EXPAND_VALUE}}}{}} ifelse_strstr(confDELIVERY_TO, `MBOX', `dnl warn condition = ${if eq{$acl_m0}{}{yes}{no}} domains = +local_domains set acl_m0 = ${lookup{$sender_address<@>$local_part}dbm{confCHECK_COMPAT_DBM_FILE}\ {${if eq{$value}{}{confCHECK_COMPAT}{EXPAND_VALUE}}}\ {\ ${lookup{$sender_address_local_part@<@>$local_part}dbm{confCHECK_COMPAT_DBM_FILE}\ {${if eq{$value}{}{confCHECK_COMPAT}{EXPAND_VALUE}}}\ {}}\ }} ') dnl ifelse_strstr(confDELIVERY_TO, `MBOX', `') ') dnl ifelse(confCHECK_COMPAT_BACKEND, `DBM', `') ifelse_strstr(confCHECK_COMPAT_BACKEND, `SQLITE', ` warn condition = ${if eq{$acl_m0}{}{yes}{no}} set acl_m0 = ${lookup sqlite{confCHECK_COMPAT_SQLITE_FILE \ confCHECK_COMPAT_SQLITE_QUERY \ }{EXPAND_VALUE}{\ ifdef(`confCHECK_COMPAT_SQLITE_QUERY2', `dnl ${lookup sqlite{confCHECK_COMPAT_SQLITE_FILE \ confCHECK_COMPAT_SQLITE_QUERY2 \ }{EXPAND_VALUE}{}}\ ') dnl ifdef(`confCHECK_COMPAT_SQLITE_QUERY2', `') }} ') dnl ifelse(confCHECK_COMPAT_BACKEND, `SQLITE', `') ifelse_strstr(confCHECK_COMPAT_BACKEND, `MYSQL', ` warn condition = ${if eq{$acl_m0}{}{yes}{no}} set acl_m0 = ${lookup mysql{\ confCHECK_COMPAT_MYSQL_QUERY \ }{EXPAND_VALUE}{\ ifdef(`confCHECK_COMPAT_MYSQL_QUERY2', `dnl ${lookup mysql{\ confCHECK_COMPAT_MYSQL_QUERY2 \ }{EXPAND_VALUE}{}}\ ') dnl ifdef(`confCHECK_COMPAT_MYSQL_QUERY2', `') }} ') dnl ifelse(confCHECK_COMPAT_BACKEND, `MYSQL', `') ifelse_strstr(confCHECK_COMPAT_BACKEND, `TEXT', ` warn condition = ${if eq{$acl_m0}{}{yes}{no}} set acl_m0 = ${lookup{$sender_address<@>$local_part@$domain}\ wildlsearch{CONFDIR/access-compat}\ {${if eq{$value}{}{confCHECK_COMPAT}{EXPAND_VALUE}}}\ {\ ${lookup{$sender_address_local_part@<@>$local_part@$domain}\ wildlsearch{CONFDIR/access-compat}\ {${if eq{$value}{}{confCHECK_COMPAT}{EXPAND_VALUE}}}\ {}}\ }} ifelse_strstr(confDELIVERY_TO, `MBOX', `dnl warn condition = ${if eq{$acl_m0}{}{yes}{no}} domains = +local_domains set acl_m0 = ${lookup{$sender_address<@>$local_part}\ wildlsearch{CONFDIR/access-compat}\ {${if eq{$value}{}{confCHECK_COMPAT}{EXPAND_VALUE}}}\ {\ ${lookup{$sender_address_local_part@<@>$local_part}\ wildlsearch{CONFDIR/access-compat}\ {${if eq{$value}{}{confCHECK_COMPAT}{EXPAND_VALUE}}}\ {}}\ }} ') dnl ifelse_strstr(confDELIVERY_TO, `MBOX', `') ') dnl ifelse(confCHECK_COMPAT_BACKEND, `TEXT', `') warn condition = ${if eq{$acl_m0}{}{no}{yes}} set acl_m1 = ${extract{1}{:}{$acl_m0}} acl = normalize_action set acl_m1 = ${sg{$acl_m1 }{\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_m2 = ${if eq{$acl_m2}{}{Access denied}{$acl_m2}} set acl_m0 = ${expand:${sg{${extract{3}{:}{$acl_m0}}}{\N^\s+\N}{}}} set acl_m_check_compat_msg = ${if eq{$acl_m0}{}{}{: $acl_m0}} set acl_m0 = ${if eq{$acl_m0}{}{sender/recipient addresses pair blacklisted${if eq{$acl_m2}{}{}{: $acl_m2}}}{$acl_m0}} accept condition = ${if eq{${extract{whitelist}{$acl_m1}}}{}{no}{yes}} set acl_m9 = white_list_compat=1 $acl_m9 set acl_m_wl_flag_msg = white_list_compat=1 $acl_m_wl_flag_msg acl = acl_check_rcpt_before_accept ifdef(`confENTERPRISE_USER', `dnl warn condition = ${if match{$acl_m1}{submit_mysql}{yes}{no}} ENTERPRISE(`mysql', `submit', `mail-rcpt', `blacklisted', `$sender_address|$local_part@$domain', `0') warn condition = ${if match{$acl_m1}{submit_sqlite}{yes}{no}} ENTERPRISE(`sqlite', `submit', `mail-rcpt', `blacklisted', `$sender_address|$local_part@$domain', `0') warn condition = ${if match{$acl_m1}{submit_rbl}{yes}{no}} dnl ENTERPRISE(`rbl', `update', `mx.org.ua', `mail-rcpt.rbl.mx.org.ua', `blacklisted', `$sender_address|$local_part@$domain') ENTERPRISE(`rbl', `submit', `mail-rcpt', `blacklisted', `$sender_address|$local_part@$domain') ')dnl # warn warn condition = ${if match{$acl_m1}{warn}{yes}{no}} log_message = $acl_m0 add_header = X-Warn-Compat: $acl_m2 # pause warn condition = ${if eq{${extract{pause}{$acl_m1}}}{}{no}{yes}} delay = ${extract{pause}{$acl_m1}}s set acl_m15 = ${acl_m15}\t\ delay=${extract{pause}{$acl_m1}}s\t\t\ $acl_m0\n # quarantine_other warn condition = ${if eq{${extract{quarantine_other}{$acl_m1}}}{00}{yes}{no}} add_header = X-Quarantine-Compat: sender address $sender_address and recipient address $local_part@$domain pair blacklisted${acl_m_check_compat_msg} log_message = message will be quarantined for all other recipients: sender address $sender_address and recipient address $local_part@$domain pair blacklisted set acl_m_add_x_orig_rcpt = yes ifdef(`confRECIPIENTS_SPAM_HATERS', `ifelse(confRECIPIENTS_SPAM_HATERS, `NO', `', `dnl set acl_m9 = spam_hater=1 $acl_m9 set acl_m_wl_flag_msg = spam_hater=1 $acl_m_wl_flag_msg ')') dnl ifdef(`confRECIPIENTS_SPAM_HATERS', `ifelse(confRECIPIENTS_SPAM_HATERS, `NO', `')') # reject all warn condition = ${if eq{${extract{reject_all}{$acl_m1}}}{00}{yes}{no}} set acl_m16 = sender address $sender_address and recipient address $local_part@$domain blacklisted; message rejected for all the recipients: $acl_m0\ |message rejected for all the recipients: ${expand:$acl_m2} log_message = message will be rejected for all other recipients # quarantine and !reject accept condition = ${if eq{${extract{quarantine}{$acl_m1}}}{00}{yes}{no}} condition = ${if or{\ {eq{${extract{reject}{$acl_m1}}}{00}}\ {eq{${extract{reject_all}{$acl_m1}}}{00}}\ }{no}{yes}} add_header = X-Quarantine-Compat: sender address $sender_address and recipient address $local_part@$domain pair blacklisted${acl_m_check_compat_msg} log_message = message will be quarantined: sender address $sender_address and recipient address $local_part@$domain pair blacklisted set acl_m_skip_verify_recipient = yes set acl_m_add_x_orig_rcpt = yes ifdef(`confRECIPIENTS_SPAM_HATERS', `ifelse(confRECIPIENTS_SPAM_HATERS, `NO', `', `dnl set acl_m9 = spam_hater=1 $acl_m9 set acl_m_wl_flag_msg = spam_hater=1 $acl_m_wl_flag_msg ')') dnl ifdef(`confRECIPIENTS_SPAM_HATERS', `ifelse(confRECIPIENTS_SPAM_HATERS, `NO', `')') # reject and quarantine accept condition = ${if eq{${extract{quarantine}{$acl_m1}}}{00}{yes}{no}} condition = ${if or{\ {eq{${extract{reject}{$acl_m1}}}{00}}\ {eq{${extract{reject_all}{$acl_m1}}}{00}}\ }{yes}{no}} log_message = message will be quarantined: sender address $sender_address and recipient address $local_part@$domain pair blacklisted set acl_m_fakereject = \ message will be quarantined: sender address $sender_address and recipient address $local_part@$domain pair blacklisted\ |X-Quarantine-Compat: sender address $sender_address and recipient address $local_part@$domain pair blacklisted${acl_m_check_compat_msg}\ |${expand:$acl_m2} set acl_m_skip_verify_recipient = yes set acl_m_add_x_orig_rcpt = yes ifdef(`confRECIPIENTS_SPAM_HATERS', `ifelse(confRECIPIENTS_SPAM_HATERS, `NO', `', `dnl set acl_m9 = spam_hater=1 $acl_m9 set acl_m_wl_flag_msg = spam_hater=1 $acl_m_wl_flag_msg ')') dnl ifdef(`confRECIPIENTS_SPAM_HATERS', `ifelse(confRECIPIENTS_SPAM_HATERS, `NO', `')') # reject and !quarantine deny condition = ${if or{\ {eq{${extract{reject}{$acl_m1}}}{00}}\ {eq{${extract{reject_all}{$acl_m1}}}{00}}\ }{yes}{no}} condition = ${if eq{${extract{quarantine}{$acl_m1}}}{00}{no}{yes}} log_message = $acl_m0 message = ${expand:$acl_m2} defer condition = ${if match{$acl_m1}{defer}{yes}{no}} log_message = $acl_m0 message = ${expand:$acl_m2} drop condition = ${if match{$acl_m1}{drop}{yes}{no}} log_message = $acl_m0 message = ${expand:$acl_m2} discard condition = ${if match{$acl_m1}{discard}{yes}{no}} log_message = $acl_m0 ifelse(confGREYLIST, `OPTIONAL', `dnl warn condition = ${if eq{${extract{greylist}{$acl_m1}}}{}{no}{yes}} set acl_c8 = \ scores=${eval:${extract{scores}{$acl_c8}}+${extract{greylist}{$acl_m1}}} \ log_message="${extract{log_message}{$acl_c8}} $acl_m0;" set acl_m15 = ${acl_m15}\t\ greylist scores=${extract{greylist}{$acl_m1}}\t\ $acl_m0\n ') dnl ifelse(confGREYLIST, `OPTIONAL', `') ifdef(`confOPTIONAL_REJECT', `ifelse(confOPTIONAL_REJECT, `NO', `dnl', `dnl warn condition = ${if eq{${extract{reject}{$acl_m1}}}{}{no}{yes}} condition = ${if eq{${extract{reject}{$acl_m1}}}{00}{no}{yes}} set acl_c6 = \ scores=${eval:${extract{scores}{$acl_c6}}+${extract{reject}{$acl_m1}}} \ log_message="${extract{log_message}{$acl_c6}} $acl_m0;" set acl_m15 = ${acl_m15}\t\ reject scores=${extract{reject}{$acl_m1}}\t\t\ $acl_m0\n ')') dnl ifdef(`confOPTIONAL_REJECT', `ifelse(confOPTIONAL_REJECT, `NO', `', `')')