Re: [exim] ot: rDNS + spam assassin

Top Page
Delete this message
Reply to this message
Author: John McMurray
Date:  
To: Mike Tubby, exim-users
Subject: Re: [exim] ot: rDNS + spam assassin
Hi Mike,

We actually do do many of those tests and you're right, most of what
would otherwise come through gets blocked...

My reasoning for using rDNS with such a high trigger is that its such an
easy fix that I think that any mail server which doesn't implement it is
just being a bit lazy (disclaimer: I don't often know what I'm talking
about so there could well be valid reasons for not having rDNS set the
way I think it should be set)..

Thank you for your sample config, I'll definately take a closer look at
it in a day or two and I'm sure I'll be pinching something from it to
use in my own config..

Regards,

John


On 19/09/2016 17:16, Mike Tubby wrote:
> I think the problem is that you're relating an IP/DNS issue to a SPAM
> identification technology.
>
> There is no 'law' that says your reverse DNS must work and its simply
> dangerous to use the heuristic no rDNS => High probability of SPAM.
>
> You would probably be better served using extensive checking at:
>
>     1. initial TCP connection, then
>     2. at HELO/EHLO greeting, then
>     3. at the MAIL command

>
>
> Using this approach we block unwanted senders (unwanted connects)
> because they are identified as such, we block spammers that use broken
> protocol like attempting to send before they say HELO or EHLO. We
> block spammers and systems that use bare words like "HELO COMPUTER" or
> dotted quads like "HELO 1.2.3.4".
>
> By the time an email gets as far as SpamAssassin on our systems its
> already been through 30+ other pre-checks which are more efficient and
> more accurate than providing a high weighting to something that can
> give a false positive.
>
>
> Mike
>
>
>
> Here's some config to consider ...
>
>
> begin acl
>
> ###
> ### acl_check_connect: This access control list checks the inbound
> ### connection against a number of DNS based block lists
> ###
>
> acl_check_connect:
>         warn    logwrite = CONNECT: New connection from 
> $sender_host_address:$sender_host_port -> 
> $received_ip_address:$received_port
>                 set acl_m5 = 0

>
>         #
>         # accept the connection here if it is on MSA port 587
>         #
>         accept  condition = ${if eq{$interface_port}{587}{1}{0}}
>                 set acl_m5 = 1
>                 logwrite = CONNECT: Host $sender_host_address allowed 
> on MSA/MUS port 587 - connect checks skipped

>
>         #
>         # check and accept if host is white-listed in our database
>         #
>         accept  hosts = +whitelist_dnsbl_hosts
>                 logwrite = CONNECT: Host $sender_host_address is 
> whitelisted in database, RBL checks skipped

>
>         #
>         # see if its whitelisted at junkmailfilter.com - only warn
>         #
>         warn    dnslists = 
> hostdomain.junkemailfilter.com=127.0.0.1/$sender_host_name
>                 logwrite = CONNECT: Host name $sender_host_name 
> whitelisted at $dnslist_domain : $dnslist_value

>
>         #
>         # check if host white-listed at DNSWL.ORG
>         #
>         accept  dnslists = list.dnswl.org&0.0.0.2
>                 logwrite = CONNECT: Host $sender_host_address 
> whitelisted at $dnslist_domain : $dnslist_value

>
>         #
>         # checks via various DNS Block Lists. These could be condensed 
> into a single check with a
>         # multi-part dnslists = ... entry but specifying them 
> separately gives us fine-grained
>         # control.  We can log each by name and can enable/disable 
> them.  Enable by setting them to
>         # 'drop' (connection refused) and disabled them by setting to 
> 'warn' (log entry only)
>         #

>
>         # SpamHaus.org
>         drop    dnslists = zen.spamhaus.org
>                 logwrite = CONNECT: Reject: $sender_host_address 
> according to: $dnslist_domain : $dnslist_value

>
>
>         # Sorbs.net
>         warn    dnslists = dnsbl.sorbs.net
>                 logwrite = CONNECT: Reject: $sender_host_address 
> according to: $dnslist_domain : $dnslist_value

>
>
>         # SpamCop.net
>         warn    dnslists = bl.spamcop.net
>                 log_message = CONNECT: Warning: $sender_host_address 
> according to: $dnslist_domain : $dnslist_value

>
>
>         # AbuseAt.org
>         warn    dnslists = cbl.abuseat.org
>                 log_message = CONNECT: Warning: $sender_host_address 
> according to: $dnslist_domain : $dnslist_value

>
>         #
>         # accept the rest
>         #
>         accept  logwrite = CONNECT: Accepting connection from: 
> $sender_host_address - not blocked by any RBL

>
>
> ###
> ### acl_start_tls: This access control list reports client used START TLS
> ###
>
> acl_start_tls:
>
>         accept  logwrite = CRYPTO: Client 
> $sender_host_address:$sender_host_port issued STARTTLS

>
>
>
>
> ###
> ### acl_check_helo: check the HELO/EHLO
> ###
>
> acl_check_helo:
>
>         #
>         # accept for relay_from_hosts
>         #
>         accept  condition = ${if 
> match_domain{$sender_helo_name}{$+relay_from_hosts}{true}{false}}
>                 logwrite = HELO: Accepted HELO/EHLO $sender_helo_name 
> from remote host: $sender_host_address ${if def:sender_host_name 
> {($sender_host_name) }} in hostlist relay_from_hosts

>
>
>         #
>         # check for single word greeting messages like "HELO COMPUTER"
>         #
>         deny    condition = ${if match {$sender_helo_name} {\\.} 
> {no}{yes}}
>                 message = Your HELO/EHLO greeting ($sender_helo_name) 
> is a single word. \
>                         According to RFC2821 you must use your 
> fully-qualified domain-name. \
>                         Please fix your configuration if you want to 
> talk to us
>                 logwrite = HELO: HELO/EHLO was not a FQDN : 
> $sender_helo_name from $sender_fullhost

>
>         #
>         # check for raw IP address in greeting like "HELO 1.2.3.4"
>         #
>         deny    condition = ${if isip{$sender_helo_name}}
>                 #condition = ${if match 
> {$sender_helo_name}{^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\$}{yes}{no}}
>                 message = Your HELO/EHLO greeting ($sender_helo_name) 
> is a plain IP address. \
>                         According to RFC2821 you must use your 
> fully-qualified domain-name. \
>                         Please fix your configuration if you want to 
> talk to us
>                 logwrite = HELO: HELO/EHLO with bare IP : 
> $sender_helo_name from $sender_fullhost

>
>         #
>         # check for HELO from our host name... must be fake as we 
> don't SMTP to ourselves!
>         #
>         deny    condition = ${if match 
> {$sender_helo_name}{$primary_hostname}{true}{false}}
>                 message = Your HELO/EHLO greeting ($sender_helo_name) 
> is using our name! \
>                         According to RFC2821 you must use your 
> fully-qualified domain-name. \
>                         Please fix your configuration if you want to 
> talk to us
>                 logwrite = HELO: Rejected because remote host used our 
> hostname: $sender_helo_name

>
>         #
>         # check for HELO from domains that we handle (local domains 
> and relay domains)... if so this is fake
>         #
>         deny    condition = ${if 
> match_domain{$sender_helo_name}{$+local_domains:+relay_to_domains}{true}{false}}
>                 message = Your HELO/EHLO greeting ($sender_helo_name) 
> is using one of our domains! \
>                         According to RFC2821 you must use your 
> fully-qualified domain-name. \
>                         Please fix your configuration if you want to 
> talk to us
>                 logwrite = HELO: Rejected because remote host used one 
> of our domains: $sender_helo_name

>
>         #
>         # check for HELO names blacklisted in our database, if we 
> reject don't give too much help as to why
>         #
>         deny    condition = ${if 
> match_domain{$sender_helo_name}{+blacklist_helo}{yes}{no}}
>                 message = Your HELO/EHLO is not acceptable here
>                 logwrite = HELO: Rejected: $sender_helo_name (from 
> $sender_fullhost) - blacklisted in database

>
>         #
>         # attempt to verify the HELO/EHLO, if it fails just generate a 
> log warning - we cannot reject
>         # based on this. See also the check_content ACL where we add a 
> warning to headers for invalid HELO
>         #
>         warn    !verify = helo
>                 logwrite = HELO: Could not verify HELO/EHLO: 
> $sender_helo_name from remote host: $sender_host_address ${if 
> def:sender_host_name {($sender_host_name) }}

>
>         #
>         # accept everything else
>         #
>         accept  message = Hello $sender_helo_name
>                 logwrite = HELO: Accepted HELO/EHLO $sender_helo_name 
> from remote host: $sender_host_address ${if def:sender_host_name 
> {($sender_host_name) }}

>
>
>
> ###
> ### acl_check_mail: this access control list checks the SMTP 'MAIL'
> (ie. MAIL FROM:)
> ### part of the transaction
> ###
>
> acl_check_mail:
>
>         #
>         # check that they have said HELO/EHLO earlier (before MAIL)
>         #
>         deny    condition = ${if !def:sender_helo_name {true}{false}}
>                 message = Missing or blank HELO/EHLO greeting. 
> According to RFC2821 \
>                         you must say HELO/EHLO before sending traffic.
>                 logwrite = MAIL: Missing or blank HELO/EHLO from 
> $sender_fullhost

>
>         #
>         # log the SPF result
>         #
>         warn    spf = !none
>                 logwrite = MAIL: SPF Result=$spf_result 
> ($sender_address_domain / $sender_fullhost)

>
>         #
>         # check blacklisted 'From:' addresses
>         #
>         deny    condition = ${lookup mysql 
> {MYSQL_BLACKLIST_SENDER}{true}{false}}
>                 message = Sender address blacklisted. Go away!
>                 logwrite = MAIL: Rejected sender's from: 
> $sender_address - blacklisted in database

>
>         #
>         # accept everything else (we won't know until we call-out 
> verify/route it)
>         #
>         accept  logwrite = MAIL: Accept from: $sender_address host: 
> $sender_fullhost

>
>
>
>
>
>
>
>
> On 9/19/2016 1:58 PM, John McMurray wrote:
>> Hi everyone,
>>
>> I hope its ok to ask an off topic question in this group. I ask here
>> because even though it is off topic its obviously closely related and
>> I'd love to hear what your thoughts are on the following:
>>
>> In my exim servers I assign a very high spam assassin score to
>> incoming mail servers without rDNS (RDNS_NONE = 4.5).
>>
>> This has worked well for me blocking a fair amount of spam (or
>> rather, pushing the overall score high enough to block the spam).
>>
>> I have a client on my servers who cannot receive mail from one of
>> their contacts. It turns out that this sender's forward and reverse
>> records don't match exactly, eg:
>>
>> mailsecurity-01.example.com. => 1.2.3.4
>>
>> but
>>
>> dig -x 1.2.3.4 => gateway.example.com.
>>
>>
>> So my question(s) are basically:
>>
>> 1) am I being too over the top assigning such high spam assassin to
>> incoming mail without valid rDNS?
>>
>> 2) Should it be considered valid if the tld matches but not the sub
>> domain as in the example above (and if so any pointers on how to
>> achieve that in exim)?
>>
>>
>> Thank you,
>>
>> John McMurray
>>
>> john@???
>>
>>
>
>