9.3 Set Up MX Records
An MX record is simply
the method used by DNS to route mail bound for one machine to another
instead. An MX record is created by a single line in one of your
named(8) files:
hostA IN MX 10 hostB
This line says that all mail destined for hostA in
your domain should instead be delivered to hostB
in your domain. The IN says that this is an
Internet-type record, and the 10 is the cost for
using this MX record.
An MX record can point to another host or to the original host:
hostA IN MX 0 hostA
This line says that mail for hostA will be
delivered to hostA. Such records might seem
redundant, but they are not because a host can have many MX records
(one of which can point to itself):
hostA IN MX 0 hostA
IN MX 10 hostB
Here, hostA has the lowest cost
(0 versus 10 for
hostB), so the first delivery attempt will be to
hostA. If hostA is unavailable,
delivery will be attempted to hostB instead.
Usually, MX records point to hosts inside the same domain. Therefore,
managing them does not require the cooperation of others. But it is
legal for MX records to point to hosts in different domains:
hostA IN MX 0 hostA
IN MX 10 host.other.domain.
Here, you must contact the administrator at
other.domain and obtain permission before creating
this MX record. We cover this concept in more detail when we discuss
disaster preparation later in this chapter.
Although MX records are usually straightforward, there can be a few
problems associated with them.
9.3.1 MX Must Point to Host With an A or AAAA Record
The A and AAAA
records for a host are lines that give the host's IP
address or addresses:
hostC IN A 123.45.67.8 IPv4
hostC IN AAAA 3ffe:8050:201:1860:42::1IPv6
Here, hostC is the host's name.
The IN says this is an Internet-type record. The
A marks this as an IPv4 A record, with the IP
address 123.45.67.8. The AAAA
marks this as an IPv6 AAAA record, with the IP address
3ffe:8050:201:1860:42::1.
An MX record must point to a hostname that has an A or AAAA record.
To illustrate, consider the following:
hostA IN MX 10 hostB illegal
IN MX 20 hostC
hostB IN MX 10 hostC
hostC IN A 123.45.67.8
Note that hostB lacks an A record but
hostC has one. It is illegal to point an MX record
at a host that lacks an A or AAAA record. Therefore, the first line
in the preceding example is illegal, whereas the second line is
legal.
Although such a mistake is difficult to make when maintaining your
own domain tables, it can easily happen if you rely on a name server
in someone else's domain, as shown:
hostA IN MX 10 mail.other.domain.
The other administrator might, for example, retire the machine
mail and replace its A record with an MX record
that points to a different machine. Unless you are notified of the
change, your MX record will suddenly become illegal.
Note that although an MX record must point to a hostname that has an
A or AAAA record, it is illegal for an MX record to point directly to
an A or AAAA record:
hostA IN MX 10 123.45.67.89 illegal
9.3.2 MX to CNAME Is Illegal
The sendmail
program is frequently more forgiving than other MTAs because it
accepts an MX record that points to a CNAME record. The presumption
is that, eventually, the CNAME will correctly point to an A or AAAA
record. But beware, this kind of indirection can cost additional DNS
lookups. Consider this example of an exceptionally bad setup:
hostA IN MX 10 mailhub
mailhub IN CNAME nfsmast
nfsmast IN CNAME hostB
hostB IN A 123.45.67.89
First, sendmail looks up
hostA and gets an MX record pointing to
mailhub. Because there is only a single MX record,
sendmail considers mailhub to
be official. Next, mailhub is looked up to find an
A or AAAA record (IP address), but instead a CNAME
(nfsmast) is returned. Now,
sendmail must look up the CNAME
nfsmast to find its A or AAAA record. But again a
CNAME is returned instead. So sendmail must
again look for an A or AAAA record (this time with
hostB). Finally, sendmail
succeeds by finding the A record for hostB, but
only after far too many lookups.
The correct way to form the previous DNS file entries is as follows:
hostA IN MX 10 hostB
mailhub IN CNAME hostB
nfsmast IN CNAME hostB
hostB IN A 123.45.67.89
In general, try to construct DNS records in such a way that the
fewest lookups are required to resolve any records.
9.3.3 MX Records Are Nonrecursive
Consider the
following MX setup, which causes all mail for
hostA to be sent to hostB and
all mail for hostB to be sent to
hostB, or to hostC if
hostB is down:
hostA IN MX 10 hostB
hostB IN MX 10 hostB
IN MX 20 hostC
One might expect sendmail to be smart and
deliver mail for hostA to hostC
if hostB is down. But
sendmail won't do that. The RFC
standards do not allow it to recursively look up additional MX
records. If sendmail did, it could get
hopelessly entangled in MX loops. Consider the following:
hostA IN MX 10 hostB
hostB IN MX 10 hostB
IN MX 20 hostC
hostC IN MX 10 hostA potential loop
If your intention is to have hostA MX to two other
hosts, you must state that explicitly:
hostA IN MX 10 hostB
IN MX 20 hostC
hostB IN MX 10 hostB
IN MX 20 hostC
Another reason sendmail refuses to follow MX
records beyond the target host is that costs in such a situation are
undefined. Consider the previous example with the potential loop.
What is the cost of hostA when
MX'd by hostB to
hostC? Should it be the minimum of 10, the maximum
of 20, the mean of 15, or the sum of 30?
9.3.4 Wildcard MX Records
Wildcard MX records should not be
used unless you understand all the possible risks. They can provide a
shorthand way of MX'ing many hosts with a single MX
record, but it is a shorthand that can be easily abused. For example:
*.dc.gov. IN MX 10 hostB
This says that any host in the domain .dc.gov
(where that host doesn't have any record of its own)
should have its mail forwarded to hostB.
; domain is .dc.gov
*.dc.gov. IN MX 10 hostB
hostA IN MX 10 hostC
hostB IN A 123.45.67.8
Here, mail to hostD (no record at all) will be
forwarded to hostB. But the wildcard MX record
will be ignored for hostA and
hostB because each has its own record.
Extreme care must be exercised in setting up wildcard MX records. It
is easy to create ambiguous situations that DNS might not be able to
handle correctly. Consider the following, for example:
; domain is sub.dc.gov
*.dc.gov. IN MX 10 hostB.dc.gov.
*.sub.dc.gov. IN MX 10 hostC.dc.gov.
Here, an unqualified name such as the plain hostD
matches both wildcard records. This is ambiguous, so DNS
automatically picks the most complete one
(*.sub.dc.gov.) and supplies that MX record to
sendmail.
One compelling weakness of wildcard MX records is that they match any
hostname at all, even for machines that don't exist:
; domain is sub.dc.gov
*.dc.gov. IN MX 10 hostB.dc.gov.
Here, mail to foo.dc.gov will be forwarded to
hostB.dc.gov, even if there is no host
foo in that domain.
Wildcard MX records almost never have any appropriate use on the
Internet. They are often misunderstood and are often used just to
save the effort of typing hundreds of MX records. They do, however,
have legitimate uses behind firewall machines and on non-Internet
networks.
9.3.5 What? They Ignore MX Records?
Many older MTAs on the network ignore
MX records. Some pre-Solaris Sun sites, for example, wrongly run the
non-MX version of sendmail when they should use
/usr/lib/sendmail.mx. Some Solaris sites wrongly
do all host lookups with NIS when they should list
dns on the hosts line of their
/etc/nsswitch.conf file. Because of these and
other mistakes, you will occasionally find some sites that insist on
sending mail to a host even though that host has been explicitly
MX'd to another.
To illustrate why this is bad, consider a UUCP host that has only an
MX record. It has no A record because it is not on the network:
uuhost IN MX 10 uucpserver
Here, mail to uuhost will be sent to
uucpserver, which will forward the message to
uuhost with UUCP software. An attempt to ignore
this MX record will fail because uuhost has no
other records. Similar problems can arise for printers with direct
network connections, terminal servers, and even workstations that
don't run an SMTP daemon such as
sendmail.
If you believe in DNS and disdain sites that don't,
you can simply ignore the offending sites. In this case the mail will
fail if your MX'd host doesn't run
a sendmail daemon (or another MTA). This is not
as nasty as it sounds. There is actually considerable support for
this approach; failure to obey MX records is a clear violation of
published network protocols. RFC1123, Host
Requirements, section 5.3.5, notes that obeying MX records
is mandatory. RFC1123 has existed for more than 12 years.
On the other hand, if you want to ensure that all mail is received,
even on a workstation whose mail is MX'd elsewhere,
you can run the sendmail daemon on every
machine.
9.3.6 Caching MX Records
Although you are not required to have
MX records for all hosts, there is good reason to consider doing so.
To illustrate, consider the following host that has only an A record:
hostB IN A 123.45.67.8
When V8.12 and above sendmail first looks up
this host, it asks the name server for that host's
MX records. Because there are none, that request comes back empty.
The sendmail program must then make a second
lookup for the IP address.
When pre-V8.12 sendmail first looks up this
host, it asks the local name server for all records. Because there is
only an A record, that is all it gets. But note that asking for any
record causes the local name server to cache the information.
The next time sendmail looks up this same host,
the local name server will return the A record from its cache. This
is faster and reduces Internet traffic. The cached information is
"nonauthoritative" (because it is a
copy) and includes no MX records (because there are none).
When pre-V8.12 sendmail gets a nonauthoritative
reply that lacks MX records, it is forced to do another DNS lookup.
This time, it specifically asks for MX records. In this case there
are none, so it gets none.
Because hostB lacks an MX record,
sendmail performs a DNS lookup each and every
time mail is sent to that host. If hostB were a
major mail-receiving site, its lack of an MX record would cause many
sendmail programs, all over the world, to waste
network bandwidth with useless DNS lookups.
We strongly recommend that every host on the Internet have at least
one MX record. As a minimum, it can simply point to itself with a 0
cost:
hostB IN A 123.45.67.8
IN MX 0 hostB
This will not change how mail is routed to hostB
but will reduce the number of DNS lookups required.
9.3.7 Ambiguous MX Records
RFC974
leaves the treatment of ambiguous MX records to the
implementor's discretion. This has generated much
debate in sendmail circles. Consider the
following:
foo IN MX 10 hostA
foo IN MX 20 hostB mail from hostB to foo
foo IN MX 30 hostC
When mail is sent from a host (hostB) that is an
MX record for the receiving host (foo), all MX
records that have a cost equal to or greater than that of
hostB must be discarded. The mail is then
delivered to the remaining MX host with the lowest cost
(hostA). This is a sensible rule because it
prevents hostB from wrongly trying to deliver to
itself.
It is possible to configure hostB so that it views
the name foo as a synonym for its own name. Such a
configuration results in hostB never looking up
any MX records because it recognizes mail to foo
as local.
But what should happen if hostB does not recognize
foo as local and if there is no
hostA?
no hostA
foo IN MX 20 hostB mail from hostB to foo
foo IN MX 30 hostC
Again, RFC974 says that when mail is being sent from a host
(hostB) that is an MX record for the receiving
host (foo), all MX records that have a cost equal
to or greater than that of hostB must be
discarded. In this example, that leaves zero MX
records. Three courses of action are now open to
sendmail, but RFC974 doesn't
say which it should use:
Assume that this is an error condition. Clearly,
hostB should have been configured to recognize
foo as local. It didn't (hence
the MX lookup and discarding in the first place), so it must not have
known what it was doing. V8 sendmail with the
TryNullMXList option (TryNullMXList) not set (undeclared or declared as false)
will bounce the mail message with this message:
553 5.3.5 hostconfig error: mail loops back to me (MX problem?)
Look to see whether foo has an A record. If it
does, go ahead and try to deliver the mail message directly to
foo. If it lacks an A record, bounce the
message. This approach runs the risk that foo
might not be configured to properly accept mail (thus causing mail to
disappear down a black hole). Still, this approach can be desirable
in some circumstances. V8 sendmail with the
TryNullMXList option (TryNullMXList) set to true always tries to connect to
foo.
Assume (even though it has not been configured to do so) that
foo should be treated as local to
hostB. No version of
sendmail makes this assumption.
This situation is not an idle exercise. Consider the MX record for
uuhost presented in the previous section:
uuhost IN MX 10 uucpserver
Here, uuhost has no A or AAAA record because it is
connected to uucpserver via a dial-up line. If
uucpserver is not configured to recognize
uuhost as one of its UUCP clients, and if mail is
sent from uucpserver to uuhost,
it will query DNS and get itself as the MX record for
uuhost. As we have shown, that MX record is
discarded, and an ambiguous situation has developed.
|