Re: [Exim] acl_smtp_helo

Top Page
Delete this message
Reply to this message
Author: Kjetil Torgrim Homme
Date:  
To: Marc Perkel
CC: 'Exim Users'
Subject: Re: [Exim] acl_smtp_helo
On Tue, 2004-07-13 at 18:34 -0700, Marc Perkel wrote:
> I see - ok - I guess I can move my HELO test to another section?


(please don't top post.)

I'll just paste in our HELO tests, as they are quite general, the
exceptions being the hardcoding of our B-net 129.240.x.x (that ACL
actually never blocks anything) and the lookup in LDAP for finding local
hostnames. these tests require the argument to HELO to be correct,
except when the recipient is postmaster. if you use Exim's builtin HELO
check, it's harder to allow postmaster, plus it accepts bare IP
addresses, which is one of the most important rules for blocking badly
written spamware.


# Explanation for the ACL variables used in this file
#
# acl_c0:  the keyword used for referring to the relevant explanation
#          on our webpage.
# acl_c1:  contains the verbose error message
#
# acl_c0 and acl_c1 should always set simultaneously, but there is no
# ACL for RSET.  Therefore, we reset acl_c0 whenever the ACL is
# successful, and leave a possibly stale value in acl_c1.


acl_check_helo:

  # Our own users can do anything.  Authenticated users will get a
  # slight delay if they have a misconfigured system.
  accept  hosts      = +relay_from_hosts
          set acl_c0 =


  accept  condition  = ${if isip {$sender_helo_name} {true}{false}}
          set acl_c0 = helo_bareip
          set acl_c1 = \
              Improper HELO/EHLO: IP address without brackets. RFC 2821,\r\n\
              section 4.1.3: "[an address literal] uses four small decimal\r\n\
              integers separated by dots and enclosed by brackets [...]"
          delay      = 5s


  # IPv6 address literals have no "." in them, so we must check for
  # them before doing the "not fully qualified" test.  We only cover
  # the syntactically correct IPv6 case here.
  accept  condition  = ${if and {{match {$sender_helo_name}\
                                        {\N^(?i)\[IPv6:(.+)\]$\N}}\
                                 {isip6 {$1}}}\
                            {true}{false}}
          set acl_c0 =


  # Sending host claims to have an 129.240.0.0/16 IP address.
  accept  condition  = ${if match {$sender_helo_name}\
                                  {\N^\[129\.240\.\d{1,3}\.\d{1,3}\]$\N}\
                            {true}{false}}
          set acl_c0 = helo_uioip
          set acl_c1 = \
              Improper HELO/EHLO: You provided one of my IP addresses,\r\n\
              not your own.
          delay      = 5s


  # Handle syntactically correct IPv4 case.
  accept  condition  = ${if and {{match {$sender_helo_name}\
                                        {\N^\[(.+)\]$\N}}\
                                 {isip4 {$1}}}\
                            {true}{false}}
          set acl_c0 =


  # Exim will reject address literal syntax errors before even calling
  # this ACL, but it accepts IPv6 addresses without the "IPv6" prefix,
  # and we don't.
  accept  condition  = ${if match {$sender_helo_name}\
                                  {\N^\[(.+)\]$\N}\
                            {true}{false}}
          set acl_c0 = helo_badipv6
          set acl_c1 = \
              Improper HELO/EHLO: Invalid IPv6 address literal. RFC 2821,\r\n\
              section 4.1.3: "For IPv6 [...] the form consists of a\r\n\
              standardized "tag" that identifies the address syntax, a\r\n\
              colon, and the address itself [...]"
          delay      = 5s


  # No "." in the name.
  accept  condition  = ${if !match {$sender_helo_name}\
                                   {\N\.\N}\
                            {true}{false}}
          set acl_c0 = helo_nonfqdn
          set acl_c1 = \
              Improper HELO/EHLO: Not fully qualified. RFC 2821, section\r\n\
              4.1.1: "The argument field contains the fully-qualified\r\n\
              domain name of the SMTP client [...]"
          delay      = 5s


  # Illegal characters.
  accept  condition  = ${if !match {$sender_helo_name}\
                                   {\N^[A-Za-z0-9][A-Za-z0-9-]*\
                                       (\.[A-Za-z0-9][A-Za-z0-9-]*)+$\N}\
                            {true}{false}}
          set acl_c0 = helo_illegal
          set acl_c1 = \
              Improper HELO/EHLO: Illegal characters. RFC 2821 specifies\r\n\
              that the name given as argument to HELO/EHLO must only\r\n\
              contain letters (a-z or A-Z), digits (0-9) and hyphens (-).
          delay      = 5s


  # See if the sending host claims to have the name of one our domains
  # or hosts.  Since we handle e-mail for external domains, we have to
  # check DNS for the caller, too.  Currently, only maidanak.org has A
  # RR outside +relay_from_hosts, but their PTR records don't match up.
  # Nevertheless, a properly configured server outside UiO is bound to
  # show up some day.
  accept  condition  = ${if !eq {${extract{1}{ }{$sender_rcvhost}}}\
                                {$sender_helo_name}\
                            {${lookup ldap {ldap:HOST_BASE?cn?sub?\
                                      (cn=${quote_ldap:$sender_helo_name})}\
                                {true}{false}}}\
                           {false}}
          set acl_c0 = helo_uiohost
          set acl_c1 = \
              Improper HELO/EHLO: You provided one of the hostnames in\r\n\
              my domain, rather than your own.
          delay      = 5s


accept set acl_c0 =

acl_check_rcpt:

# Accept if the source is local SMTP (i.e. not over TCP/IP). We do this by
# testing for an empty sending host field.

accept hosts = :

# Deny if the local part contains @ or % or / or | or !. These are
# rarely found in genuine local parts, but are often tried by people
# looking to circumvent relaying restrictions.
#
# Also deny if the local part starts with a dot. Empty components
# aren't strictly legal in RFC 2822, but Exim allows them because
# this is common. However, actually starting with a dot may cause
# trouble if the local part is used as a file name (e.g. for a
# mailing list).

  deny    local_parts   = ^.*[@%!/|] : ^\\.


  # Accept mail to postmaster in any local domain, regardless of the
  # source, and without verifying the sender.
  #
  # We use verify = recipient for two reasons:
  #   1) we want $address_data to get set always
  #   2) if the postmaster alias is missing (due to some error),
  #      it is better to reject it than for it to end up in limbo.


  accept  local_parts   = postmaster
          domains       = +local_domains
          verify        = recipient


  # Add all other (non-<postmaster@local_domains>) recipients to
  # acl_m0, for use in the DATA ACL.  Note that the 'warn' verb here
  # will not actually do anything, as there are no modifiers.
  warn    set acl_m0    = $local_part@$domain:$acl_m0


  # Do a little HELO/EHLO argument verification.
  warn  ! authenticated = *
          hosts         = ! +relay_from_hosts : *
          condition     = ${if !def:sender_helo_name {true}{false}}
          set acl_c0    = helo_missing
          set acl_c1    = \
              Improper HELO/EHLO: Missing. RFC 2821, section 4.1.1.1: "a\r\n\
              client MUST issue HELO or EHLO before starting a mail\r\n\
              transaction."


  deny  ! authenticated = *
          condition     = ${if def:acl_c0 {true}{false}}
          message       = \
              $acl_c1\r\n\
              See http://www.usit.uio.no/it/epost/system/#$acl_c0
          delay         = 45s
....




--
Kjetil T.