在 acl 部分(紧随begin acl之后),我们需要定义这些 ACL。 在此过程中,我们将结合本文档前面描述的一些基本 技巧,即 DNS 检查 和 SMTP 检查。
在这一遍中,我们将在 acl_rcpt_to 中完成大部分检查,而将其他 ACL 大部分留空。 这是因为大多数常用的垃圾邮件软件无法理解 SMTP 事务早期的拒绝 - 它会不断尝试。 另一方面,如果 RCPT TO: 失败,大多数垃圾邮件软件客户端会放弃。
但是,我们创建所有这些 ACL,因为我们稍后会使用它们。
# This access control list is used at the start of an incoming # connection. The tests are run in order until the connection # is either accepted or denied. acl_connect: # In this pass, we do not perform any checks here. accept |
# This access control list is used for the HELO or EHLO command in # an incoming SMTP transaction. The tests are run in order until the # greeting is either accepted or denied. acl_helo: # In this pass, we do not perform any checks here. accept |
# This access control list is used for the MAIL FROM: command in an # incoming SMTP transaction. The tests are run in order until the # sender address is either accepted or denied. # acl_mail_from: # Accept the command. accept |
# This access control list is used for every RCPT command in an
# incoming SMTP message. The tests are run in order until the
# recipient address is either accepted or denied.
acl_rcpt_to:
# 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 from hosts for which we relay mail.
#
# Recipient verification is omitted here, because in many
# cases the clients are dumb MUAs that don't cope well with
# SMTP error responses.
#
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 = *
######################################################################
# DNS checks
######################################################################
#
# The results of these checks are cached, so multiple recipients
# does not translate into multiple DNS lookups.
#
# If the connecting host is in one of a select few DNSbls, then
# reject the message. Be careful when selecting these lists; many
# would cause a large number of false postives, and/or have no
# clear removal policy.
#
deny
dnslists = dnsbl.sorbs.net : \
dnsbl.njabl.org : \
cbl.abuseat.org : \
bl.spamcop.net
message = $sender_host_address is listed in $dnslist_domain\
${if def:dnslist_text { ($dnslist_text)}}
# If reverse DNS lookup of the sender's host fails (i.e. there is
# no rDNS entry, or a forward lookup of the resulting name does not
# match the original IP address), then reject the message.
#
deny
message = Reverse DNS lookup failed for host $sender_host_address.
!verify = reverse_host_lookup
######################################################################
# Hello checks
######################################################################
# If the remote host greets with an IP address, then reject the mail.
#
deny
message = Message was delivered by ratware
log_message = remote host used IP address in HELO/EHLO greeting
condition = ${if isip {$sender_helo_name}{true}{false}}
# Likewise if the peer greets with one of our own names
#
deny
message = Message was delivered by ratware
log_message = remote host used our name in HELO/EHLO greeting.
condition = ${if match_domain{$sender_helo_name}\
{$primary_hostname:+local_domains:+relay_to_domains}\
{true}{false}}
deny
message = Message was delivered by ratware
log_message = remote host did not present HELO/EHLO greeting.
condition = ${if def:sender_helo_name {false}{true}}
# If HELO verification fails, we add a X-HELO-Warning: header in
# the message.
#
warn
message = X-HELO-Warning: Remote host $sender_host_address \
${if def:sender_host_name {($sender_host_name) }}\
incorrectly presented itself as $sender_helo_name
log_message = remote host presented unverifiable HELO/EHLO greeting.
!verify = helo
######################################################################
# Sender Address Checks
######################################################################
# If we cannot verify the sender address, deny the message.
#
# You may choose to remove the "callout" option. In particular,
# if you are sending outgoing mail through a smarthost, it will not
# give any useful information.
#
# Details regarding the failed callout verification attempt are
# included in the 550 response; to omit these, change
# "sender/callout" to "sender/callout,no_details".
#
deny
message = <$sender_address> does not appear to be a \
valid sender address.
!verify = sender/callout
######################################################################
# Recipent Address Checks
######################################################################
# 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 = ^.*[@%!/|] : ^\\.
# Drop the connection if the envelope sender is empty, but there is
# more than one recipient address. Legitimate DSNs are never sent
# to more than one address.
#
drop
message = Legitimate bounces are never sent to more than one \
recipient.
senders = : postmaster@*
condition = $recipients_count
# Reject the recipient address if it is not in a domain for
# which we are handling mail.
#
deny
message = relay not permitted
!domains = +local_domains : +relay_to_domains
# Reject the recipient if it is not a valid mailbox.
# If the mailbox is not on our system (e.g. if we are a
# backup MX for the recipient domain), then perform a
# callout verification; but if the destination server is
# not responding, accept the recipient anyway.
#
deny
message = unknown user
!verify = recipient/callout=20s,defer_ok
# Otherwise, the recipient address is OK.
#
accept
|
# This access control list is used for message data received via
# SMTP. The tests are run in order until the recipient address
# is either accepted or denied.
acl_data:
# Add Message-ID if missing in messages received from our own hosts.
warn
condition = ${if !def:h_Message-ID: {1}}
hosts = : +relay_from_hosts
message = Message-ID: <E$message_id@$primary_hostname>
# 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 from hosts for which we relay mail.
#
accept
hosts = : +relay_from_hosts
# Accept if the message arrived over an authenticated connection, from
# any host.
#
accept
authenticated = *
# Enforce a message-size limit
#
deny
message = Message size $message_size is larger than limit of \
MESSAGE_SIZE_LIMIT
condition = ${if >{$message_size}{MESSAGE_SIZE_LIMIT}{true}{false}}
# Deny unless the address list header is syntactically correct.
#
deny
message = Your message does not conform to RFC2822 standard
log_message = message header fail syntax check
!verify = header_syntax
# Deny non-local messages with no Message-ID, or no Date
#
# Note that some specialized MTAs, such as certain mailing list
# servers, do not automatically generate a Message-ID for bounces.
# Thus, we add the check for a non-empty sender.
#
deny
message = Your message does not conform to RFC2822 standard
log_message = missing header lines
!hosts = +relay_from_hosts
!senders = : postmaster@*
condition = ${if or {{!def:h_Message-ID:}\
{!def:h_Date:}\
{!def:h_Subject:}} {true}{false}}
# Warn unless there is a verifiable sender address in at least
# one of the "Sender:", "Reply-To:", or "From:" header lines.
#
warn
message = X-Sender-Verify-Failed: No valid sender in message header
log_message = No valid sender in message header
!verify = header_sender
# Accept the message.
#
accept
|