Misc about the check_* rulesets in sendmail 8.8 and 8.9
Last Update 1999-02-24
This document tries to answer some of the frequently asked questions about the
check_*
rulesets in
sendmail 8.8 and beyond.
check_rcpt
can be used to prevent unauthorized
relaying,
which means that neither the
sender
nor the
recipient
are local or allowed to use the mailserver.
The algorithm works like this (in
sendmail 8.9
the steps are reversed):
-
Check the address
(${client_addr})
or the name
(${client_name})
of the host which tries to send e-mail through this system.
Is it a
local
system?
If yes: it can do whatever it wants.
(This is the case:
internal to external
or
internal to internal.)
If no: goto next step.
-
Check the address given as
RCPT.
Is it a
local
address
or is it an address for which we relay?
If yes: the mail is accepted,
i.e., no error is generated.
(This is the case:
external to internal.)
If no: an error is generated, relaying is denied.
There are some things which needs to be considered with algorithm:
-
What is a
local
sender?
-
What is a
local
(or allowed) recipient?
As already said, the address of the sender is determined by
${client_addr}
or
${client_name},
it is
not
based on the envelope
MAIL FROM
address!
Hence
check_rcpt
can not be fooled by giving a false
MAIL FROM
address, it doesn't check this address at all
(unless the option
_ALLOW_SOME_
is explicitly defined.)
Which hosts you consider as
local
with respect to sending e-mail through your system
is listed in classes
$={LocalIP}
(for
${client_addr},
enabled by
HACK(use_ip)
)
or
$={LocalNames}
(for
${client_name},
enabled by
HACK(use_names)
),
respectively.
This address is listed as
relay=
in the sendmail logfile.
If both
HACKs
are used, it is a logical
OR
condition:
the client address must be in
$={LocalIP},
or
the client name must be in
$={LocalNames},
Detecting whether the recipient address is local
isn't an easy task because there are many ways to specify an address.
sendmail
considers all elements of class
$=w
as local, so these are allowed by default.
However, it isn't sufficient to check whether an address ends
in an element of this class, since this can be fooled,
e.g.,
<user%remote.site@local.site>.
Hence the ruleset
remove_local
(repeatedly) removes the local part of an address.
If there is still some domain part available after this process,
it is considered as a relay attempt.
In addition to class
$=w
a
$={RelayTo}
class can be used to specify allowed recipient domains
or individual hosts
(enabled by
HACK(use_relayto)
.)
Allowing relaying to other systems
than local ones
has some
problems.
The address of the recipient is listed as
to=
in the sendmail logfile, or as
arg1=
if
check_rcpt
denied the operation.
Why doesn't
check_rcpt
simply use
(like the
anti-spam rules at sendmail.org)
just one class to specify
local senders and local recipients?
This is possible by specifying
HACK(use_names,`/etc/sendmail.cR')
HACK(use_relayto,`/etc/sendmail.cR')
However, the use of separate classes allows finer control.
Even though it might not be necessary in common cases,
someone would have asked for this feature
(judging from the number of
available options. )
The DNS check in
check_mail
contains the comment:
# no DNS entry? this is dangerous!
for the rule:
R$*<@$*$~P>$* $#error $@ 4.1.8 $: "451 unresolvable host name, check your configuration." no real name
Why is this dangerous?
Some MTAs may react on the reply code, which indicates a temporary error,
with very fast retries.
This may tie up some of your resources and quickly fill your logfile.
sendmail 8.9
can distinguish between
temporary and permanent DNS failures,
so this isn't a problem in the new version.
check_compat
has several problems which doesn't make it useful to prevent relaying.
These are based on the fact that the ruleset operates on the sender
and recipient address given in the envelope.
So the straight-forward approach to deny access
if one of these address is not local doesn't work with forwarding.
In this case, the sender address is not changed,
hence an e-mail from an external site
to a local address which is forward to an external site
will be rejected as unauthorized relaying attempt.
Let's take an example:The sender is
A@extern.site
the recipient is
B@local.site
and B has a
.forward
installed with
C@external.site
(here we naturally assume that only
local.site
is local to your site.)
In this case,
the e-mail will be accepted when sent from
A to B, but it can't be fowarded to C, since
check_compat
is called with
A@extern.site $| C@external.site,
which will be rejected in our scenario.
As explained above,
it is not well advised to base the decision about
a relay attempt on the envelope
MAIL FROM
address.
However, this is what the proposed simple
check_compat
ruleset does.
sendmail 8.8
introduced several new macros:
${client_name},
${client_addr},
and
${client_port}
that have the name, IP address, and port number of the SMTP client, respectively.
That is, these macros are only defined during SMTP transactions.
In other cases, they are empty.
If ${client_addr}
can't be resolved (by the name services available to
sendmail)
or the forward and reverse lookup do not match, then
${client_name}
will be
[${client_addr}]
i.e., the IP address in square brackets.
[(links)]
[Hints]
[Avoiding UBE]
[cf/README]
[New]
Copyright ©
Claus Aßmann
Please send comments to:
<ca@sendmail.org>