+
+### acl/30_exim4-config_check_rcpt
+#################################
+
+# This access control list is used for every RCPT command in an incoming
+# SMTP message. The tests are run in order until the address is either
+# 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.
+ #
+ # Non-alphanumeric characters other than dots are rarely found in genuine
+ # local parts, but are often tried by people looking to circumvent
+ # relaying restrictions. Therefore, although they are valid in local
+ # parts, these rules disallow certain non-alphanumeric characters, as
+ # a precaution.
+ #
+ # Empty components (two dots in a row) are not valid in RFC 2822, but Exim
+ # allows them because they have been encountered. (Consider local parts
+ # constructed as "firstinitial.secondinitial.familyname" when applied to
+ # a name without a second initial.) However, a local part starting
+ # with a dot or containing /../ can cause trouble if it is used as part of a
+ # file name (e.g. for a mailing list). This is also true for local parts that
+ # contain slashes. A pipe symbol can also be troublesome if the local part is
+ # incorporated unthinkingly into a shell command line.
+ #
+ # 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.
+ .ifdef CHECK_RCPT_LOCAL_LOCALPARTS
+ deny
+ domains = +local_domains
+ local_parts = CHECK_RCPT_LOCAL_LOCALPARTS
+ message = restricted characters in address
+ .endif
+
+
+ # The second rule applies to all other domains, and its default is
+ # considerably less strict.
+ .ifdef CHECK_RCPT_REMOTE_LOCALPARTS
+ deny
+ domains = !+local_domains
+ local_parts = CHECK_RCPT_REMOTE_LOCALPARTS
+ message = restricted characters in address
+ .endif
+
+
+ # Accept mail to postmaster in any local domain, regardless of the source,
+ # and without verifying the sender.
+ #
+ accept
+ .ifndef CHECK_RCPT_POSTMASTER
+ local_parts = postmaster
+ .else
+ local_parts = CHECK_RCPT_POSTMASTER
+ .endif
+ domains = +local_domains
+
+
+ # 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.
+ 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
+ senders = ${if exists{CONFDIR/local_sender_blacklist}\
+ {CONFDIR/local_sender_blacklist}\
+ {}}
+
+
+ # deny bad sites (IP address)
+ # CONFDIR/local_host_blacklist holds a list of host names, IP addresses
+ # and networks (CIDR notation) that should have their access denied to
+ # The local host. Messages coming in from a listed host will have all
+ # RCPT statements rejected.
+ #
+ # 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.
+ deny
+ message = sender IP address $sender_host_address is locally blacklisted here. If you think this is wrong, get in touch with postmaster
+ !acl = acl_whitelist_local_deny
+ hosts = ${if exists{CONFDIR/local_host_blacklist}\
+ {CONFDIR/local_host_blacklist}\
+ {}}
+
+
+ # 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
+ # to enable this.
+ # If sender_host_address is defined, it's a remote call. If
+ # sender_host_name is not defined, then reverse lookup failed. Use
+ # this instead of !verify = reverse_host_lookup to catch deferrals
+ # as well as outright failures.
+ .ifdef CHECK_RCPT_REVERSE_DNS
+ warn
+ message = X-Host-Lookup-Failed: Reverse DNS lookup failed for $sender_host_address (${if eq{$host_lookup_failed}{1}{failed}{deferred}})
+ condition = ${if and{{def:sender_host_address}{!def:sender_host_name}}\
+ {yes}{no}}
+ .endif
+
+
+ # Check against classic DNS "black" lists (DNSBLs) which list
+ # sender IP addresses
+ .ifdef CHECK_RCPT_IP_DNSBLS
+ warn
+ message = X-Warning: $sender_host_address is listed at $dnslist_domain ($dnslist_value: $dnslist_text)
+ log_message = $sender_host_address is listed at $dnslist_domain ($dnslist_value: $dnslist_text)
+ dnslists = CHECK_RCPT_IP_DNSBLS
+ .endif
+
+
+ # 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.
+ .ifdef CHECK_RCPT_DOMAIN_DNSBLS
+ warn
+ message = X-Warning: $sender_address_domain is listed at $dnslist_domain ($dnslist_value: $dnslist_text)
+ log_message = $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
+ .endif
+
+
+ # This hook allows you to hook in your own ACLs without having to
+ # modify this file. If you do it like we suggest, you'll end up with
+ # a small performance penalty since there is an additional file being
+ # accessed. This doesn't happen if you leave the macro unset.
+ .ifdef CHECK_RCPT_LOCAL_ACL_FILE
+ .include CHECK_RCPT_LOCAL_ACL_FILE
+ .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).
+ #
+ accept
+ domains = +local_domains
+ endpass
+ message = unknown user
+ verify = recipient
+
+
+ # 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
+ 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.
+ ############
+
+ # 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