5.3 The MX Algorithm
That's the basic idea behind MX
records and mail exchangers, but there are a few more wrinkles you
should know about. To avoid
routing loops, mailers need to use a
slightly more complicated algorithm than what we've described
when they determine where to send mail.
Imagine what would happen if mailers didn't check for routing
loops. Let's say you send mail from your workstation to
nuts@oreilly.com, raving (or raging) about the quality
of this book. Unfortunately, ora.oreilly.com is down at the moment.
No problem! Recall oreilly.com's MX records:
oreilly.com. IN MX 0 ora.oreilly.com.
oreilly.com. IN MX 10 ruby.oreilly.com.
oreilly.com. IN MX 10 opal.oreilly.com.
Your mailer falls back and sends your message to ruby.oreilly.com, which is up. The
mailer of ruby.oreilly.com
then tries to forward the mail on to ora.reilly.com, but can't, because
ora.oreilly.com is down. Now
what? Unless ruby.oreilly.com checks the sanity of
what it's doing, it'll try to forward the message to
opal.oreilly.com, or maybe
even to itself. That's certainly not going to help get the mail
delivered. If ruby.oreilly.com sends the message to
itself, we have a mail routing loop. If ruby.oreilly.com sends the message to
opal.oreilly.com,
opal.oreilly.com will either
send it back to ruby.oreilly.comor send it to itself, and we again have a mail routing
loop.
To
prevent this from happening, mailers discard certain MX records
before they decide where to send a message. A mailer sorts the list
of MX records by preference value and looks in the list for the
canonical domain name of the host it's running on. If the local
host appears as a mail exchanger, the mailer discards that MX record
and all MX records in which the preference value is equal or higher
(that is, equally or less preferred mail exchangers). That prevents
the mailer from sending messages to itself or to mailers
"farther" from the eventual destination.
Let's think about this in the context of our airport analogy.
This time, imagine you're an airline passenger (a message), and
you're trying to get to Greeley, Colorado. You can't get
a direct flight to Greeley, but you can fly to either Fort Collins or
Denver (the two next highest mail exchangers). Since Fort Collins is
closer to Greeley, you opt to fly to Fort Collins.
Now, once you've arrived in Fort Collins, there's no
sense in flying to Denver, away from your destination (a lower
preference mail exchanger). (And flying from Fort Collins to Fort
Collins would be pretty silly, too.) So the only acceptable flight to
get you to your destination is now a Fort Collins-Greeley flight. You
eliminate flights to less preferred destinations to prevent frequent
flyer looping and wasteful travel time.
One caveat: most mailers will only look for
their local host's canonical domain name
in the list of MX records. They don't check for
aliases (domain names
on the left side of CNAME records). Unless you always use canonical
names in your MX records, there's no guarantee that a mailer
will be able to find itself in the MX list, and you'll run the
risk of having your mail loop.
If you do list a mail exchanger by an alias and it unwittingly tries
to deliver mail to itself, it will detect the loop and bounce the
mail with the error:
554 MX list for movie.edu points back to relay.isp.com
554 <root@movie.edu>... Local configuration error
This replaces the quainter "I refuse to talk to myself"
error in newer versions of sendmail. The moral:
in an MX record, always use the mail exchanger's
canonical name.
One more caveat: the hosts you list as
mail exchangers must
have address records. A mailer needs to find an address for each mail
exchanger you name or else it can't attempt delivery there.
To go back to our oreilly.comexample, when ruby.oreilly.com receives the message
from your workstation, its mailer checks the list of MX records:
oreilly.com. IN MX 0 ora.oreilly.com.
oreilly.com. IN MX 10 ruby.oreilly.com.
oreilly.com. IN MX 10 opal.oreilly.com.
Finding the local host's domain name in the list at preference
value 10, ruby.oreilly.com's mailer discards
all the records at preference value 10 or higher (the records in
bold):
oreilly.com. IN MX 0 ora.oreilly.com.
oreilly.com. IN MX 10 ruby.oreilly.com.
oreilly.com. IN MX 10 opal.oreilly.com.
leaving only:
oreilly.com. IN MX 0 ora.oreilly.com.
Since ora.oreilly.com is
down, ruby.oreilly.com
defers delivery until later and queues the message.
What happens if a mailer finds itself at the
highest preference (lowest preference value) and has to discard the
whole MX list? Some mailers attempt delivery directly to the
destination host's IP address as a last-ditch effort. In most
mailers, however, it's an error. It may indicate that DNS
thinks the mailer should be processing (not just forwarding) mail for
the destination, but the mailer hasn't been configured to know
that. Or it may indicate that the administrator has ordered the MX
records incorrectly by using the wrong preference values.
Say, for example, the folks who run acme.com add a mail exchanger record to
direct mail addressed to acme.com to a mailer at their Internet
Service Provider:
acme.com. IN MX 10 mail.isp.net.
Most mailers need to be configured to identify their aliases and the
names of other hosts they process mail for. Unless the mailer on
mail.isp.net is configured
to recognize email addressed to acme.com as local mail, it will assume
it's being asked to relay the mail and attempt to forward the
mail to a mail exchanger closer to the final destination. When it looks up the MX records for
acme.com, it finds itself as
the most preferred mail exchanger and bounces the mail back to the
sender with the familiar error:
554 MX list for acme.com points back to mail.isp.com
554 <root@acme.com>... Local configuration error
Many versions of
sendmail use class w or fileclass
w as the list of "local"
destinations. Depending on your sendmail.cf
file, adding an alias can be as easy as adding the line:
Cw acme.com
to sendmail.cf. If your mailer uses another mail
transport, such as UUCP, to deliver mail to the hosts for which it
acts as a mail exchanger, this will probably require more involved
configuration.
You may have noticed that we tend to use multiples of 10 for our
preference values. This is convenient
because it allows you to insert other MX records temporarily at
intermediate values without changing the other preferences, but
otherwise there's nothing magical about it. We could just as
easily use increments of 1 or 100 —the effect would
be
the same.
|