在 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 |