A.12.1. Check for Recipient Mailbox
The first method is performed in the acl_rcpt_to ACL. Here, we check that the
recipient address corresponds to a local mailbox:
# Deny mail for users that do not have a mailbox (i.e. postmaster,
# webmaster...) if no sender address is provided. These users do
# not send outgoing mail, so they should not receive returned mail.
#
deny
message = This address never sends outgoing mail. \
You are responding to a forged sender address.
log_message = bogus bounce for system user <$local_part@$domain>
senders = : postmaster@*
domains = +local_domains
!mailbox check
|
Unfortunately, how we perform the mailbox
check will depend on how you deliver your mail (as
before, we extract the portion before the first "="
sign of the recipient address, to accomodate for Envelope Sender Signatures):
If mailboxes map to local user accounts on your server, we
can check that the recipient name maps to a user ID that
corresponds to "regular" users on your
system, e.g. in the range 500 - 60000:
set acl_m9 = ${extract{1}{=}{${lc:$local_part}}}
set acl_m9 = ${extract{2}{:}{${lookup passwd {$acl_m9}{$value}}}{0}}
condition = ${if and {{>={$acl_m9}{500}} {<${acl_m9}{60000}}} {true}}
|
If you deliver mail to the Cyrus IMAP
suite, you can use the provided mbpath
command-line utility to check that the mailbox exists.
You will want to make sure that the Exim user has
permission to check for mailboxes (for instance, you may
add it to the cyrus group:
# adduser exim4 cyrus).
set acl_m9 = ${extract{1}{=}{${lc:$local_part}}}
condition = ${run {/usr/sbin/mbpath -q -s user.$acl_m9} {true}}
|
If you forward all mail to a remote machine for delivery,
you may need to perform a Recipient Callout Verification
and let that machine decide whether to accept the mail.
You need to keep the original envelope sender intact in
the callout:
verify = recipient/callout=use_sender
|
Since in the case of locally delivered mail, this mailbox
check duplicates some of the logic that is performed in the
routers, and since it is specific to the mail delivery
mechanism on our site, it is perhaps a bit kludgy for the
perfectionists among us. So we will now provide an alternate
way.
A.12.2. Check for Empty Sender in Aliases Router
You probably have a router named
system_aliases or similar, to redirect mail
for users such as postmaster and
mailer-demon. Typically, these aliases are
not used in the sender address of outgoing mail. As such, you
can ensure that incoming Delivery Status Notifications are not routed
through it by adding the following condition to the router:
!senders = : postmaster@* |
A sample aliases router may now look like this:
system_aliases:
driver = redirect
domains = +local_domains
!senders = : postmaster@*
allow_fail
allow_defer
data = ${lookup{$local_part}lsearch{/etc/aliases}}
user = mail
group = mail
file_transport = address_file
pipe_transport = address_pipe
|
Although we now block bounces to some
system aliases, other aliases were merely shadowing existing
system users (such as "root",
"daemon", etc). If you deliver local mail
through the the accept driver, and use
check_local_user to validate the recipient
address, you may now find yourself routing mail directly to
these system accounts.
To fix this problem, we now want to add an additional
condition in the router that handles your local mail
(e.g. local_user) to ensure that the
recipient not only exists, but is a "regular"
user. For instance, as above, we can check that the user ID
is in the range 500 - 60000:
condition = ${if and {{>={$local_user_uid}{500}}\
{<{$local_user_uid}{60000}}}\
{true}}
|
A sample router for local delivery may now look like this:
local_user:
driver = accept
domains = +local_domains
check_local_user
condition = ${if and {{>={$local_user_uid}{500}}\
{<{$local_user_uid}{60000}}}\
{true}}
transport = transport
|
Beware that if you implement this method, the reject response
from your server in response to bogus bounce mail for system
users will be the same as for unknown recipients (550
Unknown User in our case).