7.4 Relaying
Promiscuous relaying is
the process of accepting email from outside your site and then
transmitting it to another host also outside your site. Hosts that
relay are quickly discovered by spam programs, and used to mask the
identity of the originating spam site. Prior to V8.9, promiscuous
relaying was allowed by default. Beginning with V8.9, promiscuous
relaying is turned off by default.
In place of default relaying, V8.9 and above
sendmail provides a variety of features, macros,
and databases that allow you to relay in a variety of manners. The
access database (Section 7.5)
provides a way to relay on a host-by-host, or network basis. Adding
domains to the class $=R ($=R) is another method. In this section we
describe features that allow you to tune relaying to your taste.
Table 7-2 lists the features available as of
V8.12.
Table 7-2. Relay features
access_db
|
Section 7.5
|
Screen addresses and set policy
|
loose_relay_check
|
Section 7.4.2
|
Allow %-hack relaying
|
promiscuous_relay
|
Section 7.4.3
|
Allow all relaying
|
relay_based_on_MX
|
Section 7.4.4
|
Relay for any site for which you are an MX server
|
relay_entire_domain
|
Section 7.4.5
|
Relay based on $=m
|
relay_hosts_only
|
Section 7.4.6
|
Interpret domains in relay-domains, and access database, as hosts
|
relay_local_from
|
Section 7.4.7
|
Relay if SMTP MAIL domain is in $=w
|
relay_mail_from
|
Section 7.4.8
|
Relay if SMTP MAIL address is RELAY in access database, and provided
the entry is properly tagged.
|
In addition to the features we discuss here, you should also see
Chapter 10 for a discussion of how relaying can be
controlled with AUTH= and STARTTLS.
Before you turn on relaying of any sort, be sure you understand the
potential risks of your decision. A mistake that loosens relaying
restrictions too much can open your site to abuse as a spam relay
from anywhere in the world.
The following features are presented in alphabetical order, not in
order of recommendation or safety. In fact, the first is more fraught
with risk than the others. Take care to read about all these relaying
features so that you fully understand them before choosing any.
7.4.1 Macros to Allow Relaying
Hosts and domains to which mail can
be relayed are listed either in a special
sendmail class, or in the
access database. You add hosts and domains to
the special class with either the RELAY_DOMAIN
mc macro, or the RELAY_DOMAIN_FILE
mc macro.
7.4.1.1 The RELAY_DOMAIN mc macro
A special class (currently
$=R) holds as its list of values host and domain names to
which sendmail should allow mail to be relayed.
Relaying is discussed in general in the sections that follow.
You add domain names to this class like this:
RELAY_DOMAIN(`list of hosts and domains')
Here, the list is one or more hosts or domains separated from each
other by spaces:
RELAY_DOMAIN(`our.internal.domain our.company.domain')
If you find it more convenient to list them on separate lines you can
do so like this:
RELAY_DOMAIN(`our.internal.domain')
RELAY_DOMAIN(`our.company.domain')
The list can be host or domain names, or IP numbers, or network
numbers. IPv6 addresses can be specified by prefixing each with the
literal text IPv6:, as for example:
host.another.domain a hostname
your.domain a domain name
123.45 a network (leftmost numbers)
123.45.67.89 a host IP address
IPv6:2002:c0a8:02c7 an IPv6 network
IPv6:2002:c0a8:51d2::23f4 an IPv6 host address
7.4.1.2 The RELAY_DOMAIN_FILE mc macro
You can also maintain a list of hosts,
domains, and addresses that can be relayed to in an external file.
That file is declared with the following macro:
define(confCR_FILE, `path') deprecated
RELAY_DOMAIN_FILE(`path')
The recommended value for path is
/etc/mail/relay-domains:
RELAY_DOMAIN_FILE(`/etc/mail/relay-domains')
This declaration causes a list of relay hosts, domains, or addresses
to be read from the file
/etc/mail/relay-domains. Because
RELAY_DOMAIN_FILE is implemented with an F
configuration command (Section 22.1.2), you can add
whatever F command arguments you desire. For
example:
RELAY_DOMAIN_FILE(`-o /etc/mail/relay-domains')
Here, the -o switch makes the presence of the
/etc/mail/relay-domains file optional.
If you are currently reading relaying information from a file
declared directly with the F configuration
command, you are encouraged to convert to this new macro. Use of it
will insulate you from change in the future if a different class name
is ever used.
7.4.2 FEATURE(loose_relay_check)
The percent-hack is a form of address that
uses the % character to route mail through one
host to another. For example, the following address uses the
percent-hack to relay mail through hostA for
delivery to hostB:
user%hostB@hostA
The intention here is to cause sendmail to
connect to the hostA host and send the message
by specifying user@hostB as the
envelope-recipient, meaning that hostA will
relay the message to hostB.
V8 sendmail no longer allows the percent-hack
form of relaying without first performing two checks. First, the
connected-to host, the one following the @
(hostA), is looked up in the class macro defined
by the RELAY_DOMAIN mc macro, and in the
access database. If the connected-to host is
neither in that class nor OK'd by the
access database, the message is rejected
with:
550 5.7.1 Relaying denied.
If the connected-to host is OK, sendmail looks
up the destination host hostB, also in the class
macro defined by the RELAY_DOMAIN mc macro
(Section 7.4.1.1), and in the
access database. If the destination host is
neither in that class nor OK'd by the
access database, the message is rejected;
otherwise it is accepted for delivery.
In brief, for the percent-hack to work, both hosts must be listed in
the class macro defined by the RELAY_DOMAIN mc
macro, or OK'd by the access
database, or both.
One way to list them might look like this in your
mc configuration file:
RELAY_DOMAIN(`hostA.domain hostB.domain') V8.9 and above
If it is not possible for you to know ahead of time which hosts
should be listed in that class, you might want
to loosen this check. But be forewarned, if you think you need to
loosen this check, you probably do not need to.
To loosen these checks, you can use the
loose_relay_check feature, which is declared in
your mc configuration file like this:
FEATURE(loose_relay_check) CAUTION!
Use this feature with caution! It risks allowing spammers to relay
through your server because it skips the check for the destination
host—that is, the host following the %
(hostA in our example). Consider, for example, a
spam site sending a spam message with the following
envelope-recipient:
user%site.to.spam@your.mail.server
If your mail server is listed with RELAY_DOMAIN (as it would be if it
relays mail inward to your internal network), and if your mail server
uses this loose_relay_check feature, there is
nothing to prevent this spam message from being relayed to any
arbitrary site on the Internet, or for your site to be abused as a
spam relay.
Note that this feature can be of benefit in an internal network
protected by a well-configured mail gateway and a firewall because it
allows testing of internal mail hubs as potential MX servers for
internal-only email.
7.4.3 FEATURE(promiscuous_relay)
Sometimes it is beneficial to set up a mail server
that will relay mail from any host that connects to it. Consider a
main mail-sending machine that exists behind a firewall. In this
example, the mail-sending machine is separate from the mail-receiving
machine. The mail-sending machine has inbound port 25 blocked at the
firewall so that it cannot receive mail from anywhere but the
internal network. In such an arrangement, it is simpler to allow any
internal host to relay mail than to specify individual hosts or
domains in the access database, or with the class
$=R, or with authentication.
If this simpler approach is applicable to your site, and if your
network is totally secure around port 25, you can enable unfettered
or "promiscuous" relaying with this
promiscuous_relay feature. You declare it like
this:
FEATURE(`promiscuous_relay')
To underscore the risk associated with this feature, the following
warning will be printed each time you build with your
mc configuration file:
*** WARNING: FEATURE(`promiscuous_relay') configures your system as open
relay. Do NOT use it on a server that is connected to the Internet!
By declaring this feature, you tell sendmail to
allow mail received by the local machine from anywhere in the world
to be relayed outward to any machine in the world. This opens up the
local machine to be used by spam engines worldwide, and almost
guarantees that the local machine will eventually become listed by
one or more DNSBL sites.
You should use this feature only if the affected machine is secured
by other means. If you don't have an effective
firewall, or don't have knowledgeable network
administrators, you should avoid using this
promiscuous_relay feature.
7.4.4 FEATURE(relay_based_on_MX)
When sendmail receives a
message bound for another host, it might be doing so because the
local machine is listed as an MX record for that other host (Section 9.2) and the other host is temporarily down. When
that other host comes back up, sendmail will
deliver all such queued messages to it. You allow relaying for hosts
for which your site serves as an MX record, by listing the names of
those sites in your relay-domains file ($=R).
There might be times, however, when your site must be an MX server
for an unknown number of sites, or an unknown variety of domains. One
such example might occur when your machine is behind a firewall on a
private network. You might be the central MX site for all internal
domains that are created or renamed often. For such sites,
sendmail offers the
relay_based_on_MX feature, which looks like this:
FEATURE(`relay_based_on_MX')
When you declare this feature, you allow
sendmail to relay mail to any host for which
your site is listed as an MX record. Fortunately you
don't have to keep track of which hosts do list your
site because this feature makes the process automatic.
This feature should be used only in an environment where you
administer or trust the DNS records. You should not use it if your
DNS lookups come from the Internet at large because, in that
instance, anyone in the world would be able to use your machine as an
MX server without your knowledge or permission.
Note that you should not use this
relay_based_on_MX feature if you also use the
-z switch with the bestmx
database map (bestmx).
Also note that relaying for MX purposes is different from relaying
for the % hack (see Section 7.4.2).
7.4.5 FEATURE(relay_entire_domain)
By default, only hosts listed in the
access database (Section 7.5)
with the righthand side keyword RELAY, or hosts that are listed with
the RELAY_DOMAIN macro (Section 7.4.1.1), are allowed to
relay mail through the local host. You can allow all the hosts in
your domain to relay mail through the mail server by listing them
there, but it is much easier to use the shorthand method provided by
the relay_entire_domain feature:
FEATURE(`relay_entire_domain')
When you define this feature, you enable any host listed in the class
$=m ($=m), your domain,
to relay mail through the local host. Note, however, that if your
host is named something such as bob.gov, your
host and domain will be the same. Whatever you do, never put a
top-level domain such as gov, or
com, or de into
$=m, or you will find your site relaying mail for
any host in that top-level domain.
Note that $=m should not be used to have mail
accepted as local under a variety of domains. Instead use the
domaintable feature (FEATURE(domaintable)).
7.4.6 FEATURE(relay_hosts_only)
Normally, relaying is based on the domains listed
with the RELAY_DOMAIN mc macro (Section 7.4.1.1) or in the file specified by the
RELAY_DOMAIN_FILE mc macro (Section 7.4.1.2), or on the domains allowed to relay in the
access database. When
sendmail checks to see if a domain should be
allowed to relay, it interprets each domain as a top-level domain.
For example, if RELAY_DOMAIN listed the following entry, or if the
RELAY_DOMAIN_FILE file contained the following entry:
your.domain
all the following domains would also match that single domain entry:
sub.your.domain
a.very.deep.sub.your.domain
As an alternative, you can have sendmail
interpret each name as the literal name of a host. If you prefer this
second method, you can enable it by declaring the
relay_hosts_only feature like this:
FEATURE(relay_hosts_only)
With this feature declared, sendmail will
compare the sending host to the list of hosts, and to hosts looked up
in the access database, on a host-by-host basis.
For example, if the RELAY_DOMAIN defined the following:
sub.domain
only a host named sub.domain would be allowed to
relay. Another host—say, hostB.sub.domain,
would not be allowed to relay unless it too was listed, or
OK'd by the access database.
Clearly this feature gives you more control over who can and cannot
relay. It can be of value at a site that is populated by some network
printers and some Unix machines. The file specified by
RELAY_DOMAIN_FILE could be set up to allow the Unix machines to
relay, but not the printers.
7.4.7 FEATURE(relay_local_from)
During an SMTP conversation the sending host
specifies the address of the envelope-sender by issuing a MAIL SMTP
command. RFC2822 commentary and DSN extensions are then discarded
from that specified address, and the result is stored in the
$f macro ($f).
If you wish, you can use the value in the $f macro
to determine if a message should be relayed to any outside or inside
host. Although such a method is fraught with risk, it is still made
available with the relay_local_from feature, which
is declared like this:
FEATURE(`relay_local_from')
Because this feature poses risk, the following warning will be
printed each time you build with your mc
configuration file:
*** WARNING: FEATURE(`relay_local_from') may cause your system to act as open
relay. Use SMTP AUTH or STARTTLS instead. If you cannot use those,
try FEATURE(`relay_mail_from').
When you declare this feature you cause the domain part of the
address in $f (the portion of the address to the
right of the @ character) to be compared to the
list of hosts in the $=w class macro ($=w). Recall that the class $=w
contains all the names by which the local host can be known. If the
domain in $f is found in that class, relaying is
allowed.
The risk should be obvious. Because $f is given
its value as a part of the SMTP MAIL command, that address can be
forged to appear local by anyone on the Internet. That is, by
declaring this feature, you are opening up your host to abuse by the
entire world.
So why does sendmail offer this
relay_local_from feature? If you administer a site
that is behind a firewall and an Internet mail hub, and if your
internal machines cannot be contacted on any port from the outside
world, you might find this a simple way to allow global relaying
within that network.
We suggest, however, that SMTP AUTH (Section 10.9) or
STARTTLS (Section 10.10) will provide a safer way to
authenticate local origination addresses upon which to base the
permission to relay. A safer way to relay based on connection domains
is the Connect: keyword in the
access database. If you prefer a simpler solution,
the relay_mail_from feature, described next, might
be just what you are looking for, although it, too, is risky.
7.4.8 FEATURE(relay_mail_from)
During an SMTP conversation the sending host
specifies the address of the envelope-sender by issuing a MAIL SMTP
command. RFC2822 commentary and DSN extensions are then discarded
from that address, and the result is stored in the
$f sendmail macro ($f).
If you wish, you can use the value in the $f
sendmail macro to determine if a message should
be relayed to any outside or inside host. Although such a method is
fraught with risk, it is still made available with the
relay_mail_from feature, which is declared like
this:
FEATURE(`relay_mail_from')
Because this feature poses risk, the following warning will be
printed each time you build your cf file from
your mc file:
*** WARNING: FEATURE(`relay_mail_from') may cause your system to act as open
relay. Use SMTP AUTH or STARTTLS instead.
By declaring this feature, you cause the address in the
$f sendmail macro to be
prefixed with a literal From: and looked up in the
access database (Section 7.5). If
it is found in that database, and the value returned is a literal
RELAY, that address is allowed to be relayed:
From:bob@your.domain RELAY this sender can relay
If you want to base the decision to relay on a domain instead of on
an individual's address, you can declare this
feature with an additional argument that is a literal
domain:
FEATURE(`relay_mail_from', `domain')
With this extra argument in place, the domain part of the address in
$f (the portion of the address to the right of the
@ character) will be prefixed with a literal
From: and looked up in the
access database. If it is found, and if the value
returned is a literal RELAY, that domain will be allowed to be
relayed:
From:your.domain RELAY this domain can relay
This feature is fraught with risk. By defining it, you allow anyone
on the Internet to spoof allowed addresses as part of any SMTP MAIL
command. If you want to allow local hosts to relay mail from the
local network to the world, you can either authenticate with SMTP
AUTH (Section 10.9) or STARTTLS (Section 10.10), or you can relay based on connections using
the Connect: keyword in the
access database.
7.4.9 Risk with FEATURE(nouucp)
UUCP addresses are those that use a
! character to separate address components. For
example, the following address says to send the message first to the
host hostA, and then hostA
will relay that message to user@hostB:
hostB!user@hostA
If you have tuned your site to prevent unintended relaying, misuse of
the nouucp features can open your site to an
unexpected form of relaying.
Consider a workstation on your network that forwards all its mail to
the central mail hub using LOCAL_RELAY (Section 4.5.4)
or LUSER_RELAY ($L). If that workstation
also defines:
FEATURE(`nouucp', `nospecial')
addresses containing the ! character will not be
recognized as special and will be forwarded to the mail hub as is.
If, on the mail hub, you forget to declare the
nouucp feature, the as-is address forwarded to it
will be recognized as special. Because the
address was received from an internal workstation, relaying is
allowed. The ! address will have the
hostA part stripped and the result will be
relayed to user@hostB.
Thus, it is a good idea to define nouucp on the
mail hub if you define it on any of your workstations.
7.4.10 FEATURE(accept_unresolvable_domains)
Beginning
with V8.9, sendmail
will refuse a mail message if the address specified as part of the
SMTP MAIL FROM: has a domain part that cannot be looked up. For
example, if the domain foo.bar does not exist,
the following error will be logged with syslog
and the message will be rejected with the same error message:
553 5.1.8 <user@your.domain>... Domain of sender address other@foo.bar does not
exist
If the domain cannot be looked up, the result is a temporary error:
451 4.1.8 <user@your.domain>... Domain of sender address other@foo.bar does not
resolve
We recommend rejecting such addresses, but there might be
circumstances where you cannot. If, for example, you are behind a
firewall and lack access to full DNS lookups, you might want to
accept everything. But if that is the case, you will need a sending
mail hub with good DNS access so that you can reply to such messages.
You can accept such addresses by defining the
accept_unresolvable_domains feature:
FEATURE(`accept_unresolvable_domains')
This tells sendmail to accept all
envelope-sender addresses, even if the domain part following the
@ cannot be looked up with DNS.
7.4.11 FEATURE(accept_unqualified_senders)
The sendmail program
refuses to accept a message if the address specified as part of an
SMTP MAIL command lacks a domain. That is, if the address has a user
part but lacks the @ followed by a domain, the
message will be rejected:
MAIL FROM:<bob@foo.com> good, has a domain part
MAIL FROM:<bob> bad, lacks a domain part
Some mail submission programs will submit mail without including a
domain part. Improperly configured PCs are one example, as are poorly
configured Unix hosts. Generally, such problems will appear on your
local network. If you lack the authority to fix such a problem, you
can tweak sendmail to accept such addresses by
including the accept_unqualified_senders feature
like this:
FEATURE(`accept_unqualified_senders')
Note that this feature accepts unqualified addresses regardless of
the port on which they are received. Such a broad solution might be
acceptable on an internal network, but is discouraged on machines
that service the Internet. For those hosts, we recommend you tune
acceptance or rejection of unqualified addresses on a port-by-port
basis.
The DaemonPortOptions option u
modifier (See this section), when set, has the same
effect as declaring this feature for the given single port. That is,
unqualified addresses are accepted on a port-by-port basis, without
the need to declare this feature.
The DaemonPortOptions option f
modifier (See this section), when set, tells
sendmail to reject unqualified addresses
received on this port, even if this feature is declared. That is, you
accept unqualified addresses on all ports by declaring this feature,
then reject them on a port-by-port basis with this
f key word.
|