標準メールサービスを使用してスパムを処理します(例としてEximを使用)

私は、スパム対策システム(spamassassinなど)をメーラーにねじ込むことに関する記事を定期的に見つけます。 毎回、これらのバンドルとそれらがもたらす多くの問題を見て、私は「肩をすくめて」、なぜこれがすべてなのかを理解していませんか? スパムは、サードパーティのプログラムを使用することなく、メーラーによって非常に効果的に直接ハッキングされる可能性があります。



この記事で説明するスパムキャプチャ方法の効率は約97%です。 10台のサーバーでテストされ、少なくとも7年間実行されています。



mysqlサポートを使用して構築されたEximメールサーバーのすべての構成例を示します。 ただし、それらを同じ接尾辞に転送することは難しくありません。



ユーザーはデータベースに保存されます。 記事を散らかさないように、添付ファイルのデータベース構造( link )。 構造は、postfixadminの以前のバージョンから取得されます。 ユーザーを便利に管理するため。



まず、メールチェックで使用されるいくつかの変数を初期化します。 変数の名前は非常に「おしゃべり」です。



domainlist local_domains = ${lookup mysql{SELECT `domain` FROM `domain` WHERE `domain`='${domain}' AND `active`='1'}} domainlist relay_to_domains = ${lookup mysql{SELECT `domain` FROM `domain` WHERE `domain`='${domain}' AND `active`='1'}}
      
      







メールをチェックするルールをメーラーに示します

 acl_smtp_rcpt = acl_check_rcpt acl_smtp_data = acl_check_data
      
      







レター自体のヘッダーとテキスト。



それでは、メールのチェックを始めましょう。 見出しから始めます。



 acl_check_rcpt: #      ,   TCP/IP accept hosts = : #        @; %; !; /; |. deny message = "Incorrect symbol in address" domains = +local_domains local_parts = ^[.] : ^.*[@%!/|] #      : deny message = "Incorrect symbol in address" domains = !+local_domains local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ #          accept local_parts = postmaster domains = +local_domains # ,     (    ) require verify = sender #  ,      (HELO/EHLO) deny message = "HELO/EHLO require by SMTP RFC" condition = ${if eq{$sender_helo_name}{}{yes}{no}} #    ,   accept authenticated = * #  ,    IP  HELO deny message = "Your IP in HELO - access denied!" #    ,   relay_from_hosts hosts = * : !+relay_from_hosts condition = ${if eq{$sender_helo_name}{$sender_host_address} \ {true}{false}} #    *adsl*; *dialup*; *pool*;.... deny message = "your hostname is bad (adsl, poll, ppp & etc)." condition = ${if match{$sender_host_name} \ {adsl|dialup|pool|peer|dhcp} \ {yes}{no}} #  ,   -. deny message = "you in blacklist - $dnslist_domain" hosts = !+relay_from_hosts dnslists = dul.dnsbl.sorbs.net : \ sbl-xbl.spamhaus.org #      .     . warn set acl_m0 = 0 logwrite = "ACL m0 set default as $acl_m0 for \ host=$sender_host_name [$sender_host_address] with \ HELO=$sender_helo_name (domain in e-mail = $sender_address_domain)" #     Vigra,    ,      # 200  warn condition = ${if match{$h_subject} \ {viagra} \ {yes}{no}} set acl_m0 = ${eval:$acl_m0+200} logwrite = "STAGE0: ACL m0 set = $acl_m0 for \ host=$sender_host_name [$sender_host_address] with \ HELO=$sender_helo_name - VIAGRA!!!!" #   HELO    DNS -       # 30  warn condition = ${if !eq{$sender_helo_name}{$sender_host_name}{yes}{no}} hosts = !+relay_from_hosts : * set acl_m0 = ${eval:$acl_m0+30} logwrite = "STAGE1: ACL m0 set = $acl_m0 for \ host=$sender_host_name [$sender_host_address] with \ HELO=$sender_helo_name - reverse zone not match with HELO" #       # 30  warn condition = ${if eq{$host_lookup_failed}{1}{yes}{no}} hosts = !+relay_from_hosts : * set acl_m0 = ${eval:$acl_m0+30} logwrite = "STAGE2: ACL m0 set = $acl_m0 for \ host=$sender_host_name [$sender_host_address] with \ HELO=$sender_helo_name - no reverse zone for host" #        .   4-      # 40  warn condition = ${if match{$sender_host_name} \ {\N((?>\w+[\.|\-]){4,})\N}{yes}{no}} hosts = !+relay_from_hosts : * set acl_m0 = ${eval:$acl_m0+40} logwrite = "STAGE3: ACL m0 set = $acl_m0 for \ host=$sender_host_name [$sender_host_address] with \ HELO=$sender_helo_name - more dots or defice in name" #     .  30    # 10  warn condition = ${if >{${strlen:$sender_address}}{30}{yes}{no}} hosts = !+relay_from_hosts : * set acl_m0 = ${eval:$acl_m0+10} logwrite = STAGE4: ACL m0 set = $acl_m0 for \ host=$sender_host_name [$sender_host_address] with HELO=$sender_helo_name \ - many big sender address [$sender_address] #      .        . ,   ,      #        ,        # 60  warn condition = ${lookup{$sender_host_name} \ wildlsearch{/usr/local/etc/exim/dialup_hosts} \ {yes}{no}} hosts = !+relay_from_hosts : * set acl_m0 = ${eval:$acl_m0+60} logwrite = "STAGE5: ACL m0 set = $acl_m0 for \ host=$sender_host_name [$sender_host_address] with \ host=$sender_helo_name - dialup, ppp & etc..." #     HELO # 60  warn condition = ${lookup{$sender_helo_name} \ wildlsearch{/usr/local/etc/exim/dialup_hosts} \ {yes}{no}} hosts = !+relay_from_hosts : * set acl_m0 = ${eval:$acl_m0+60} logwrite = "STAGE6: ACL m0 set = $acl_m0 for \ host=$sender_host_name [$sender_host_address] with \ HELO=$sender_helo_name - dialup, ppp & etc..." #        HELO # 150  warn condition = ${if !eq{${lookup mysql{SELECT 1 FROM \ `list_top_level_domains` WHERE `zone` = \ LCASE(CONCAT('.', SUBSTRING_INDEX( \ '${quote_mysql:$sender_helo_name}', \ '.', -1)))}}}{1}{yes}{no}} hosts = !+relay_from_hosts : * set acl_m0 = ${eval:$acl_m0+150} logwrite = non-existent domain in HELO - \ '$sender_helo_name' setting acl_m0 = $acl_m0 warn set acl_m2 = 0 # ,          . #    whitelist       warn condition = ${if eq{${lookup mysql{SELECT 1 FROM `sended_list` \ WHERE `user_to` = \ LCASE('${quote_mysql:$sender_address}') \ AND `user_from` \ = LCASE('${quote_mysql:$local_part@$domain}') \ AND `last_mail_timestamp` < `last_mail_timestamp` \ + (60*24*60*60) LIMIT 1}}}{1}{yes}{no}} condition = ${lookup mysql{INSERT IGNORE INTO `domain_whitelist` \ (`domainname`, `domain_ip`, `added_timestamp`, \ `last_mail_timestamp`, `mail_count`) VALUES \ (LCASE('${quote_mysql:$sender_address_domain}'), \ '${quote_mysql:$sender_host_address}', \ UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), '1') \ ON DUPLICATE KEY UPDATE \ `last_mail_timestamp` = UNIX_TIMESTAMP(), \ `mail_count` = `mail_count` + 1}} hosts = !+relay_from_hosts : * set acl_m2 = 1 logwrite = STAGE7: $sender_address ==> $local_part@$domain; \ setting acl_m2 = $acl_m2; WHITELIST for this addresses #     whitelist warn condition = ${if eq{${lookup mysql{SELECT 1 \ FROM `domain_whitelist` \ WHERE `domain_ip` = \ '${quote_mysql:$sender_host_address}' \ LIMIT 1}}}{1}{yes}{no}} hosts = !+relay_from_hosts : * set acl_m2 = 1 logwrite = STAGE8: $sender_address ==> $local_part@$domain; \ setting acl_m2 = $acl_m2; WHITELIST for ALL domains #         whitelist        warn condition = ${if eq{$acl_m2}{1}{yes}{no}} logwrite = Resetting acl_m0 $acl_m0 --> 0, host in whitelist \ ($sender_address ==> $local_part@$domain) set acl_m0 = 0 #     .   ,    ACL accept domains = +local_domains endpass message = "In my mailserver not stored this user" verify = recipient #      accept domains = +relay_to_domains endpass message = "main server not know relay to this address" verify = recipient #       relay_from_hosts accept hosts = +relay_from_hosts #      -     deny message = "This is not open relay"
      
      







それでは、手紙の本文を確認しましょう。



 acl_check_data: deny message = contains $found_extension file (blacklisted). demime = com:vbs:bat:pif:scr:exe deny message = This message contains a MIME error ($demime_reason) demime = * condition = ${if >{$demime_errorlevel}{2}{1}{0}} deny message = This message contains NUL characters log_message = NUL characters! condition = ${if >{$body_zerocount}{0}{1}{0}} deny message = Incorrect headers syntax hosts = !+relay_from_hosts:* !verify = header_syntax #         .     99, ,   . # ,   ,    ,      #  -       ,       :)       #     #deny message = Possible SPAM message # log_message = Possible SPAM message # condition = ${if >{$acl_m0}{99}{yes}{no}} #   accept
      
      







Eximにはシステムフィルターメカニズムがあります。 ここに追加します



 if $acl_m0 matches ^\\d+ then logwrite "FILTER: debug - digit in variable acl_m0 = $acl_m0 (after first if)" if $acl_m0 is above 99 then headers add "X-Spam-Description: if spam count >= 100 - this is spam" headers add "X-Spam-Count: $acl_m0" headers add "Old-Subject: $h_subject:" headers remove "Subject" headers add "Subject: (*** SPAM ***) $h_old-subject:" headers add "X-Spam: YES" logwrite "EXIM FILTER: Spam count = $acl_m0 ; Added SPAM header" endif endif
      
      







つまり 件名行の先頭に「(*** SPAM ***)」という行を挿入します。これは、どのユーザーのクライアントがすでにスパムをソートするかによって異なります。

ご覧のとおり、ルールのセットは素晴らしいものではありませんが、追加のシステムを追加することなく、スパムを効果的にフィルタリングできます。 もちろん、誤検知の可能性はありますが、ユーザーから誤ってスパムに含まれていたユーザーへの最初の手紙の後、彼はホワイトリストに入ります。



繰り返しますが、私の観察によると、このような非常に単純なルールは、スパムの約97%を逃しません。



All Articles