This is something I’ve been tweaking for a few months now. I’ve got it filtering 99% of spam before it hits content filtering.
Postfix v2.5.5 using PostFWD v1.18 as a policy daemon with PostGrey v1.31 for greylisting.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
## ---------------------------------- # Trusted networks (internal usually) &&TRUSTED_NETS { client_address=192.168.0.0/16 ; }; # Trusted hostnames &&TRUSTED_HOSTS { client_name~=.nooblet.org$ ; }; # Trusted sasl usernames &&TRUSTED_USERS { sasl_username==stalks ; }; # Free mailers we don't need to greylist &&FREEMAIL { client_name~=.gmx.net$ ; client_name~=.web.de$ ; client_name~=.(aol|yahoo|h(ush|ot)mail).co(.uk|m)$ ; }; # Static IPs, no need to greylist # contains freemailers &&STATIC { &&FREEMAIL ; client_name~=[.-]static[[.-] ; client_name~=^(mail|smtp|mout|mx)[-]*[0-9]*. ; }; # Client reverse != smtp helo &&BADHELO { client_name==!!($$(helo_name)) ; }; &&NORDNS { client_name==unknown ; }; &&DYNAMIC { &&NORDNS ; client_name~=(-.+){4} ; client_name~=d{5} ; client_name~=[_.-]([axt]{0,1}dsl|br(e|oa)dband|ppp|pppoe|dynamic|dynip|adsl|dial(up|in)|pool|dhcp|leased)[_.-] ; }; &&DYNL { rbl=zen.spamhaus.org/^127.0.0.1[0-1]$/3600 ; rbl=dul.dnsbl.sorbs.net ; }; &&RWL { rbl=list.dnswl.org ; rbl=hostkarma.junkemailfilter.com/^127.0.0.1$/3600 ; rhsbl_client=hostkarma.junkemailfilter.com/^127.0.0.1$/3600 ; }; &&RBL { rbl=zen.spamhaus.org/^127.0.0.[2-8]$/3600 ; rbl=hostkarma.junkemailfilter.com/^127.0.0.(2|4)$/3600 ; rbl=bl.spamcop.net ; rbl=problems.dnsbl.sorbs.net ; rhsbl_client=hostkarma.junkemailfilter.com/^127.0.0.(2|4)$/3600 ; rhsbl=rhsbl.ahbl.org ; rhsbl=rhsbl.sorbs.net ; }; ## ## Ruleset ## # stress-friendly behaviour (will not match on postfix version pre 2.5) id=STRESS ; stress==yes ; action=dunno # Whitelists (fixed) id=WL_001 ; &&TRUSTED_NETS ; action=dunno id=WL_002 ; &&TRUSTED_HOSTS ; action=dunno id=WL_003 ; &&TRUSTED_USERS ; action=dunno # Dynamic Counter id=DYNL_001 ; &&DYNL ; rblcount=all ; action=set(HIT_dynls=$$rblcount, DYNL_text=$$dnsbltext) # DNS Block Lists id=RBL_001 ; &&RBL ; rhsblcount=all ; rblcount=all ; action=set( HIT_rbls=$$rblcount, HIT_rbls+=$$rhsblcount, RBL_text=$$dnsbltext) id=RBL_002 ; HIT_rbls>=2 ; action=REJECT You are listed on $$HIT_rbls RBLs. [$$RBL_text] id=RBL_003 ; HIT_rbls>=1 ; HIT_dynls>=1 ; action=REJECT Host listed as dynamic and listed on RBL. [$$RBL_text] id=RBL_004 ; HIT_rbls>=1 ; &&NORDNS ; action=REJECT No reverse DNS and listed on RBL. [$$RBL_text] id=RBL_005 ; HIT_rbls>=1 ; &&DYNAMIC ; action=REJECT Host looks dynamic and listed on RBL. [$$RBL_text] id=RBL_006 ; HIT_rbls>=1 ; &&BADHELO ; action=REJECT (helo $$helo_name) != ($$client_name) and listed on RBL. [$$RBL_text] # Whitelists (rwl) id=RWL_001 ; &&RWL ; rhsblcount=all ; rblcount=all ; action=set( HIT_rwls=$$rblcount, HIT_rwls+=$$rhsblcount, RWL_text=$$dnsbltext) id=RWL_002 ; HIT_rwls>=1 ; action=PREPEND X-POSTFWD: Listed on $$HIT_rwls whitelists. [$$RWL_text] # Rate limits id=RATE_001 ; HIT_rbls>=1 ; action=rate($$client_address/1/300/450 4.7.1 Throttled. Listed on RBL. Limited to 1 message every 5 minutes. [$$RBL_text]) id=RATE_002 ; HIT_dynls>=1 ; action=rate($$client_address/1/300/450 4.7.1 Throttled. Listed as dynamic. Limited to 1 message every 5 minutes.) id=RATE_003 ; &&NORDNS ; action=rate($$client_address/1/300/450 4.7.1 Throttled. No reverse DNS. Limited to 1 message every 5 minutes.) id=RATE_004 ; &&DYNAMIC ; action=rate($$client_address/1/300/450 4.7.1 Throttled. Host is probably dynamic. Limited to 1 message every 5 minutes.) # Selective greylist id=GREY_001 ; action=greylist ; HIT_rbls>=1 id=GREY_002 ; action=dunno ; &&STATIC id=GREY_003 ; action=dunno ; $$client_name~=$$(sender_domain)$ id=GREY_004 ; action=dunno ; HIT_rwls>=1 id=GREY_005 ; action=greylist ; HIT_dynls>=1 id=GREY_006 ; action=greylist ; &&DYNAMIC ## greylist should be safe during out-of-office-hours # id=GREY_007 ; action=greylist ; days=Sat-Sun # id=GREY_008 ; action=greylist ; days=Mon-Fri ; time=!!06:00:00-20:00:0 |