Re: [Exim] acl_smtp_helo

Top Page
Delete this message
Reply to this message
Author: Tor Slettnes
Date:  
To: Aaron Dalton
CC: exim-users
Subject: Re: [Exim] acl_smtp_helo
On Mar 30, 2004, at 08:58, Aaron Dalton wrote:

> I would like to reject certain messages based on the "received from"
> domain. At first I tried "sender_domain" but that only verifies
> (apparently) the "mail from:" address. I am assuming that somewhere
> there is a variable that contains the domain that actually "helo"'d.
> How can I access this information and ACL it? The Exim documentation
> is pretty sparse on this particular ACL form.


The variable is $sender_helo_name.

Exim has a mechanism to verify the by doing forward and/or reverse DNS
lookups, see 'helo_verify_name' and 'helo_try_verify_name', as well as
the 'verify = helo' ACL condition. However, some "legitimate" MTAs
(such as hotmail.com) are not configured correctly, and verification
for these will fail.

I take a slightly softer approach to HELO verification; namely, if
Exim's HELO verification fails, I stall for 20 seconds (+ 20 seconds
for each subsequent response), add 2.0 to the SpamAssassin score, and
only reject (fake_reject) the message if the total SA score is 5.0 or
above.

However, if the client greets with ANY IP address ('HELO 24.4.199.45'),
or with ANY name that points to my own IP address, I will ultimately
reject the mail (after the DATA transaction, and after stalling for 20
seconds before each response prior to that).

The point is, I am trying to make it as "expensive" as possible for
spammers (in terms of lost time) to target my machine, without
interfering too much with legitimate deliveries.

I am including my HELO and MAIL ACL snippets, most of which deal with
HELO verification.


> acl_check_helo:
>   # Accept mail received over local SMTP (i.e. not over TCP/IP).  We do
>   # this by testing for an empty sending host field.
>   # Also accept mails received over a local interface, and from hosts
>   # for which we relay mail.
>   accept hosts     = : $interface_address : +relay_from_hosts

>
>
>   # If the remote host greets with an IP address, then stall for 20
>   # seconds, and prepare a message in $acl_c0.  Later we will use the
>   # presence of this message to stall the sender further and eventually
>   # to reject the message after the DATA block.
>   warn condition   = ${if isip {$sender_helo_name}{true}{false}}
>        set acl_c0  = You greeted me with an IP address.  I want your
> name.
>        log_message = remote host used IP address in HELO/EHLO greeting

>
>
>   # Likewise if the peer greets with a name that resolves to our own
> address
>   warn condition   = ${if eq {${lookup dnsdb{a=$sender_helo_name}
> {$value}}} \
>                              {$interface_address} \
>                              {true}{false}}
>        set acl_c0  = Information you provided does not conform to the
> U.S. CAN-SPAM act.
>        log_message = remote host used our name in HELO/EHLO greeting

>
>
>   # If HELO verification fails, we stall for 20 seconds, and prepare a
>   # message in acl_c1.  We will later use the presence of this message
>   # to stall the sender further and generate a warning.
>   warn condition   = ${if def:acl_c0 {false}{true}}
>        !verify     = helo
>        set acl_c1  = ${if def:acl_c1 {$acl_c1\n}} \
>                      X-Bogus-HELO-Warning: Remote host
> $sender_host_address \
>                      incorrectly presented itself as $sender_helo_name
>        log_message = remote host presented unverifiable HELO/HELO
> greeting.

>
>
>   # If we generated one or more warnings so far, stall the sender
>   accept
>        condition   = ${if or {{def:acl_c0}{def:acl_c1}}{true}{false}}
>        delay       = 20s

>
>
> accept
>
>
> acl_check_mail:
>   # Accept mail received over local SMTP (i.e. not over TCP/IP).  We do
>   # this by testing for an empty sending host field.
>   # Also accept mails received over a local interface, and from hosts
>   # for which we relay mail.
>   accept hosts     = : $interface_address : +relay_from_hosts

>
>   # If sender did not provide a HELO/EHLO greeting, stall for 20
> seconds,
>   # and prepare a message acl_c0.  We will later use the presence of
> this
>   # message to stall the sender further, and eventually in a "deny"
> rule.
>   warn condition   = ${if def:sender_helo_name {0}{1}}
>        set acl_c0  = You did not greet. You should at least say HELO.
>        log_message = remote host did not present HELO/EHLO greeting.

>
>
>   # If we have previously generated a message in acl_c1, add a warning
> here.
>   warn message     = $acl_c1
>        condition   = ${if def:acl_c1 {true}{false}}

>
>
>   # Otherwise, if we could not look up the sender's IP address,
> generate a
>   # warning message and save a copy in $acl_c1. We will later use the
>   # presence of this message to stall the sender.
>   warn condition   = ${if def:acl_c1 {false}{true}}
>        !verify     = reverse_host_lookup
>        set acl_c1  = no host name found for IP address
> $sender_host_address
>        message     = X-Broken-Reverse-DNS: $acl_c1
>        log_message = $acl_c1

>
>
>   # Likewise, if sender address verification fails.
>   warn !verify     = sender/callout
>        set acl_c1  = Invalid sender address <$sender_address>
>        message     = X-Sender-Verify-Failed: $acl_c1
>        log_message = $acl_c1

>
>
>   # If we generated one or more warnings so far, stall the sender
>   accept
>        condition   = ${if or {{def:acl_c0}{def:acl_c1}}{true}{false}}
>        delay       = 20s

>
>
> accept