# accepted or denied.
#
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 = :
- # Add missing Date and Message-ID header for relayed messages
- warn
- hosts = +relay_from_hosts
- control = submission/sender_retain
-
-
# The following section of the ACL is concerned with local parts that contain
# certain non-alphanumeric characters. Dots in unusual places are
# handled by this ACL as well.
# contain slashes. A pipe symbol can also be troublesome if the local part is
# incorporated unthinkingly into a shell command line.
#
+ # These ACL components will block recipient addresses that are valid
+ # from an RFC2822 point of view. We chose to have them blocked by
+ # default for security reasons.
+ #
+ # If you feel that your site should have less strict recipient
+ # checking, please feel free to change the default values of the macros
+ # defined in main/01_exim4-config_listmacrosdefs or override them from a
+ # local configuration file.
+ #
# Two different rules are used. The first one has a quite strict
# default, and is applied to messages that are addressed to one of the
# local domains handled by this host.
- # If you have local accounts that include strange characters, you can
- # use the macro provided to change the ACL range or to disable the
- # check completely.
+
+ # The default value of CHECK_RCPT_LOCAL_LOCALPARTS is defined in
+ # main/01_exim4-config_listmacrosdefs:
+ # CHECK_RCPT_LOCAL_LOCALPARTS = ^[.] : ^.*[@%!/|`#&?]
+ # This blocks local parts that begin with a dot or contain a quite
+ # broad range of non-alphanumeric characters.
.ifdef CHECK_RCPT_LOCAL_LOCALPARTS
deny
domains = +local_domains
# The second rule applies to all other domains, and its default is
# considerably less strict.
+
+ # The default value of CHECK_RCPT_REMOTE_LOCALPARTS is defined in
+ # main/01_exim4-config_listmacrosdefs:
+ # CHECK_RCPT_REMOTE_LOCALPARTS = ^[./|] : ^.*[@%!`#&?] : ^.*/\\.\\./
+
+ # It allows local users to send outgoing messages to sites
+ # that use slashes and vertical bars in their local parts. It blocks
+ # local parts that begin with a dot, slash, or vertical bar, but allows
+ # these characters within the local part. However, the sequence /../ is
+ # barred. The use of some other non-alphanumeric characters is blocked.
+ # Single quotes might probably be dangerous as well, but they're
+ # allowed by the default regexps to avoid rejecting mails to Ireland.
+ # The motivation here is to prevent local users (or local users' malware)
+ # from mounting certain kinds of attack on remote sites.
.ifdef CHECK_RCPT_REMOTE_LOCALPARTS
deny
domains = !+local_domains
.else
local_parts = CHECK_RCPT_POSTMASTER
.endif
- domains = +local_domains
+ domains = +local_domains : +relay_to_domains
+
+
+ # Deny unless the sender address can be verified.
+ #
+ # This is disabled by default so that DNSless systems don't break. If
+ # your system can do DNS lookups without delay or cost, you might want
+ # to enable this feature.
+ #
+ # This feature does not work in smarthost and satellite setups as
+ # with these setups all domains pass verification. See spec.txt chapter
+ # 39.31 with the added information that a smarthost/satellite setup
+ # routes all non-local e-mail to the smarthost.
+ .ifdef CHECK_RCPT_VERIFY_SENDER
+ deny
+ message = Sender verification failed
+ !acl = acl_whitelist_local_deny
+ !verify = sender
+ .endif
+
+ # Verify senders listed in local_sender_callout with a callout.
+ #
+ # In smarthost and satellite setups, this causes the callout to be
+ # done to the smarthost. Verification will thus only be reliable if the
+ # smarthost does reject illegal addresses in the SMTP dialog.
+ deny
+ !acl = acl_whitelist_local_deny
+ senders = ${if exists{CONFDIR/local_sender_callout}\
+ {CONFDIR/local_sender_callout}\
+ {}}
+ !verify = sender/callout
+
+
+ # Accept if the message comes from one of the hosts for which we are an
+ # outgoing relay. It is assumed that such hosts are most likely to be MUAs,
+ # so we set control=submission to make Exim treat the message as a
+ # submission. It will fix up various errors in the message, for example, the
+ # lack of a Date: header line. If you are actually relaying out out from
+ # MTAs, you may want to disable this. If you are handling both relaying from
+ # MTAs and submissions from MUAs you should probably split them into two
+ # lists, and handle them differently.
+
+ # Recipient verification is omitted here, because in many cases the clients
+ # are dumb MUAs that don't cope well with SMTP error responses. If you are
+ # actually relaying out from MTAs, you should probably add recipient
+ # verification here.
+
+ # Note that, by putting this test before any DNS black list checks, you will
+ # always accept from these hosts, even if they end up on a black list. The
+ # assumption is that they are your friends, and if they get onto black
+ # list, it is a mistake.
+ accept
+ hosts = +relay_from_hosts
+ control = submission/sender_retain
+
+
+ # Accept if the message arrived over an authenticated connection, from
+ # any host. Again, these messages are usually from MUAs, so recipient
+ # verification is omitted, and submission mode is set. And again, we do this
+ # check before any black list tests.
+ accept
+ authenticated = *
+ control = submission/sender_retain
+
+
+ # Insist that any other recipient address that we accept is either in one of
+ # our local domains, or is in a domain for which we explicitly allow
+ # relaying. Any other domain is rejected as being unacceptable for relaying.
+ require
+ message = relay not permitted
+ domains = +local_domains : +relay_to_domains
+
+
+ # We also require all accepted addresses to be verifiable. This check will
+ # do local part verification for local domains, but only check the domain
+ # for remote domains.
+ require
+ verify = recipient
+
+
+ # Verify recipients listed in local_rcpt_callout with a callout.
+ # This is especially handy for forwarding MX hosts (secondary MX or
+ # mail hubs) of domains that receive a lot of spam to non-existent
+ # addresses. The only way to check local parts for remote relay
+ # domains is to use a callout (add /callout), but please read the
+ # documentation about callouts before doing this.
+ deny
+ !acl = acl_whitelist_local_deny
+ recipients = ${if exists{CONFDIR/local_rcpt_callout}\
+ {CONFDIR/local_rcpt_callout}\
+ {}}
+ !verify = recipient/callout
- # deny bad senders (envelope sender)
# CONFDIR/local_sender_blacklist holds a list of envelope senders that
# should have their access denied to the local host. Incoming messages
# with one of these senders are rejected at RCPT time.
#
# The explicit white lists are honored as well as negative items in
- # the black list. See /usr/share/doc/exim4-config/default_acl for details.
+ # the black list. See exim4-config_files(5) for details.
deny
message = sender envelope address $sender_address is locally blacklisted here. If you think this is wrong, get in touch with postmaster
!acl = acl_whitelist_local_deny
{}}
- # Deny unless the sender address can be verified.
- #
- # This is disabled by default so that DNSless systems don't break. If
- # your system can do DNS lookups without delay or cost, you might want
- # to enable this feature.
- .ifdef CHECK_RCPT_VERIFY_SENDER
- deny
- message = Sender verification failed
- !acl = acl_whitelist_local_deny
- !verify = sender
- .endif
-
- # For some sender domains, we do callout to verify if a sender
- # exists.
- deny
- !acl = acl_whitelist_local_deny
- senders = ${if exists{CONFDIR/local_sender_callout}\
- {CONFDIR/local_sender_callout}\
- {}}
- !verify = sender/callout
-
-
- # For some recipient domains, we do callout to verify if a recipient
- # exists. This is especially handy for customers that receive a lot of
- # spam to non-existent addresses.
- deny
- !acl = acl_whitelist_local_deny
- recipients = ${if exists{CONFDIR/local_rcpt_callout}\
- {CONFDIR/local_rcpt_callout}\
- {}}
- !verify = recipient/callout
-
-
# Warn if the sender host does not have valid reverse DNS.
#
# If your system can do DNS lookups without delay or cost, you might want
.endif
+ # Use spfquery to perform a pair of SPF checks (for details, see
+ # http://www.openspf.org/)
+ #
+ # This is quite costly in terms of DNS lookups (~6 lookups per mail). Do not
+ # enable if that's an issue. Also note that if you enable this, you must
+ # install "libmail-spf-query-perl" which provides the spfquery command.
+ # Missing libmail-spf-query-perl will trigger the "Unexpected error in
+ # SPF check" warning.
+ .ifdef CHECK_RCPT_SPF
+ deny
+ message = [SPF] $sender_host_address is not allowed to send mail from ${if def:sender_address_domain {$sender_address_domain}{$sender_helo_name}}. \
+ Please see http://www.openspf.org/why.html?sender=$sender_address&ip=$sender_host_address
+ log_message = SPF check failed.
+ condition = ${run{/usr/bin/spfquery --ip \"$sender_host_address\" --mail-from \"$sender_address\" --helo \"$sender_helo_name\"}\
+ {no}{${if eq {$runrc}{1}{yes}{no}}}}
+
+ defer
+ message = Temporary DNS error while checking SPF record. Try again later.
+ condition = ${if eq {$runrc}{5}{yes}{no}}
+
+ warn
+ message = Received-SPF: ${if eq {$runrc}{0}{pass}{${if eq {$runrc}{2}{softfail}\
+ {${if eq {$runrc}{3}{neutral}{${if eq {$runrc}{4}{unknown}{${if eq {$runrc}{6}{none}{error}}}}}}}}}}
+ condition = ${if <={$runrc}{6}{yes}{no}}
+
+ warn
+ log_message = Unexpected error in SPF check.
+ condition = ${if >{$runrc}{6}{yes}{no}}
+
+ # Support for best-guess (see http://www.openspf.org/developers-guide.html)
+ warn
+ message = X-SPF-Guess: ${run{/usr/bin/spfquery --ip \"$sender_host_address\" --mail-from \"$sender_address\" \ --helo \"$sender_helo_name\" --guess true}\
+ {pass}{${if eq {$runrc}{2}{softfail}{${if eq {$runrc}{3}{neutral}{${if eq {$runrc}{4}{unknown}\
+ {${if eq {$runrc}{6}{none}{error}}}}}}}}}}
+ condition = ${if <={$runrc}{6}{yes}{no}}
+
+ defer
+ message = Temporary DNS error while checking SPF record. Try again later.
+ condition = ${if eq {$runrc}{5}{yes}{no}}
+ .endif
+
+
# Check against classic DNS "black" lists (DNSBLs) which list
# sender IP addresses
.ifdef CHECK_RCPT_IP_DNSBLS
# Check against DNSBLs which list sender domains, with an option to locally
- # whitelist certain domains that might be blacklisted. If you want one
- # blacklist per domain, you need to replicate the stanza for each DNSBL.
+ # whitelist certain domains that might be blacklisted.
+ #
+ # Note: If you define CHECK_RCPT_DOMAIN_DNSBLS, you must append
+ # "/$sender_address_domain" after each domain. For example:
+ # CHECK_RCPT_DOMAIN_DNSBLS = rhsbl.foo.org/$sender_address_domain \
+ # : rhsbl.bar.org/$sender_address_domain
.ifdef CHECK_RCPT_DOMAIN_DNSBLS
warn
message = X-Warning: $sender_address_domain is listed at $dnslist_domain ($dnslist_value: $dnslist_text)
!senders = ${if exists{CONFDIR/local_domain_dnsbl_whitelist}\
{CONFDIR/local_domain_dnsbl_whitelist}\
{}}
- dnslists = CHECK_RCPT_DOMAIN_DNSBLS/$sender_address_domain
+ dnslists = CHECK_RCPT_DOMAIN_DNSBLS
.endif
.endif
- # Accept if the address is in a local domain, but only if the recipient can
- # be verified. Otherwise deny. The "endpass" line is the border between
- # passing on to the next ACL statement (if tests above it fail) or denying
- # access (if tests below it fail).
+ #############################################################################
+ # This check is commented out because it is recognized that not every
+ # sysadmin will want to do it. If you enable it, the check performs
+ # Client SMTP Authorization (csa) checks on the sending host. These checks
+ # do DNS lookups for SRV records. The CSA proposal is currently (May 2005)
+ # an Internet draft. You can, of course, add additional conditions to this
+ # ACL statement to restrict the CSA checks to certain hosts only.
#
- accept
- domains = +local_domains
- endpass
- message = unknown user
- verify = recipient
+ # require verify = csa
+ #############################################################################
- # Accept if the address is in a domain for which we are relaying, but again,
- # only if the recipient can be verified.
- #
- # If you want to use the more conservative "unknown user" error
- # message in case of a non-existing local part, you might want to
- # set CHECK_RCPT_GIVE_UNKNOWN_USER. However, this might reveal
- # local information, which is the cause for it not being enabled by
- # default.
+ # Accept if the address is in a domain for which we are an incoming relay,
+ # but again, only if the recipient can be verified.
+
accept
domains = +relay_to_domains
endpass
- .ifdef CHECK_RCPT_GIVE_UNKNOWN_USER
- message = ${if eq{$acl_verify_message}{Unrouteable address}{unknown user}{$acl_verify_message}}
- .else
- message = unrouteable address
- .endif
verify = recipient
- ############
- # If control reaches this point, the domain is neither in +local_domains
- # nor in +relay_to_domains.
- ############
+ # At this point, the address has passed all the checks that have been
+ # configured, so we accept it unconditionally.
- # Accept if the message comes from one of the hosts for which we are an
- # outgoing relay. Recipient verification is omitted here, because in many
- # cases the clients are dumb MUAs that don't cope well with SMTP error
- # responses. If you are actually relaying out from MTAs, you should probably
- # add recipient verification here.
- #
accept
- hosts = +relay_from_hosts
-
-
- # Accept if the message arrived over an authenticated connection, from
- # any host. Again, these messages are usually from MUAs, so recipient
- # verification is omitted.
- #
- accept
- authenticated = *
-
-
- # Reaching the end of the ACL causes a "deny", but we might as well give
- # an explicit message.
- #
- deny
- message = relay not permitted