Bruce H. Hunter
Part 1 of this article (January/February 1993) described
mail
and introduced sendmail; in Part 2, I begin with a review
of
mail routing through sendmail and then go deeper.
Mail is collected and delivered by a mail agent, classically,
but
not necessarily, the mail command. It is processed for
delivery
by a routing agent, most frequently sendmail. Unless
it is
for local delivery it is then passed on to a delivery
agent, typically
the Internet or UUCP (see Figure 1). To complete the
cycle, the delivery
agent then passes mail to the routing agent, which passes
it to a
mail agent. Simple? Not really, not when you see what
the routing
agent has to do -- let alone the protocols the delivery
agent uses.
In the Ethernet-TCP/IP protocol stacks, mail travels
just like other
traffic at the physical, link, and network layers. At
the transport
layer, however, it must rely on SMTP and must be able
to find its
own special port, TCP port 25. Have you seen these lines
in /etc/services?
sendmail listens (via socket) to that port for
incoming mail and sends mail via the same port.
Mail delivery by way of the routing agent relies on
the sendmail
command to work as a daemon. In the system's run-command
file(s)
you will find lines like
which tests for the presence of the sendmail command
and the sendmail.cf configuration file. If they are
present,
the command file starts sendmail with the appropriate
flags
to run as a daemon. It also sets the queuing time. sendmail
then uses its configuration file to define how it is
to deliver mail.
tcpuucpproto.cf
The standard distribution typically provides two .cf
files:
one, subsidiary.cf, is intended for use with all systems;
the
other, main.cf, is used by the mail master system.
sendmail.cf, like so many UNIX configuration files,
is divided
into sections. The first section, general macros, begins
with
defines D
classes C
The definitions are for such things as domain aliases,
hostname, relay mailer and host, and DNS.
These are followed by:
classes
version number
special macros
options
message precedence
trusted users
header formats
rewriting rules
mailers
rulesets
mail routing
The system administrator usually has only to provide
definitions for a few things like the domain name. sendmail
internal macros automatically provide the others, the
best example
being the hostname.
Configuring sendmail.cf
The sendmail configuration file for nodes is always
the smaller and
simpler of the two configuration files: its only job
is to get the
mail routed to the mail master. The mail master, however,
is another
story -- you'll find that most sendmail.cf files are
heavily
commented.
For speed in reading configuration files, you can use
a compiled version,
called a frozen configuration file. Unlike the .cf files
this
is not an ASCII file.
31% su
Password:
# file send*
sendmail.cf: ASCII text
sendmail.cf.orig: ASCII text
sendmail.cf.save: ASCII text
While the compiled version does read faster, it cannot
be changed without recompilation. Worse yet, if a frozen
configuration
file exists and you change sendmail.cf, the change will
not
take effect until you recompile. This has left many
a frustrated system
administrator wondering why his/her changes won't take.
To understand sendmail.cf, you have to understand that
.cf
lines are formatted for easy machine parsing rather
than for reading
by people. White space is used only where it is part
of a string and
is therefore significant only to the macros being set.
White spaces
play no role in the parsing of macro tokens.
The following example of a conditional shows just how
ugly the lines
of this file can look:
Dq$g$?x ($x)$.
This is the total name format and it is standard in
host
.cf files. Here q defines (in terms of [g]) the
sender address. It says if x (the sender name) is set,
use
it. The syntax is:
$xSTR_1 $| SRT_2$.
if ($?) x set
use STR_1
else ($|) use STR_2
endif ($.)
Format for Lines
Each line to be acted on (in the first part of the file)
starts with
an uppercase letter that denotes the type of action
(Table 1 shows
the values available for this position, along with the
action or entity
they denote).
Following this single letter is the macro name, also
a single
letter. The macros defined regularly by sendmail are
in lowercase;
those created by the system administrator are local
and are in uppercase
by convention. Table 2 shows sendmail's essential macros.
Confusion can arise when you can't find certain macro
definitions
anywhere in the .cf file. These macros are internal
to sendmail;
Table 3 presents a partial list of sendmail's internal
macros.
Header Format Conditionals
More than half of a short mail message will consist
of header information,
which suggests how important headers are to sendmail.
As a
result, sendmail.cf spends a lot of its space defining
headers.
Here is a header format conditional's format:
$?x $x $
An example would be the definition of a complete name
for the default sender name format, which must include
the sender's
name as it appears in the passwd comment field.
Dq$g$?x ($x)$.
This defines q (the default sender name format)
as the sender address ($g) plus the sendmail internal
macro ($x), which is the user name taken from the GECOS
field,
and essentially sets q to g if g is already set.
The header line that follows shows an application of
$g $x, sender
address (sender name).
From: bhunter@mfg.acme.com (Bruce H Hunter ~)
The last $. is the end of the conditional.
Rules and Rulesets
The first sections of the configuration file are a warmup
for the
rules and rulesets. This section is where the addresses
are reordered
into a consistent internal format and readied for delivery.
A ruleset
is defined by the mnemonic S. There can be 20 or 30
rules but 0
- 4 are the most critical. These are:
S0 message delivery ruleset
S1 sender ruleset
S2 recipient ruleset
S3 preamble ruleset
S4 final output ruleset
All messages must pass ruleset 3. This is the first
ruleset
the addresses ever see. Sender addresses pass ruleset
1 while recipient
addresses must pass through ruleset 2. Both output to
ruleset 4, which
is used to translate from internal address form to external
address
form. Ruleset 0 is the message delivery ruleset. It
is applied only
after ruleset 3 and only to the recipient address. Figure
2 shows
a flow diagram of how the rules are read.
Internal Names, Canonical Form, and "Focus"
Internal names are represented in user@domain format.
sendmail
uses a pair of operators -- the < and the > --
to focus on a particular part of the address. Here in
internal canonical
form with focus are several addresses as they would
be translated
by sendmail:
smith@<apex.uucp>
smith@<apex.dnet>
smith@<apex.ibm>
This canonical form is required by ruleset 0 for message
delivery.
Address Rewrite Rules
The address rewrite rule section uses white space that
is not a part
of the string needed by the macro. The form is right-hand
side, tab,
left-hand side, tab, comment; the functions are as follows:
left-hand side (lhs) pattern matched
right-hand side rewrite pattern (if match found)
comment
Table 4 shows the token matching symbols used in the
left-hand side. These symbols are never used to match
an exact token
such as "@" or ".".
For example,
$-@$+
matches bhunter@stalker, bhunter@stalker.acme.com,
bhunter@stalker.mfg.acme.com while
$-@$-
matches only bhunter@stalker. The right-hand side
metasymbols are
|
|
$1 |
match of the first metasymbol |
$2 |
match of the second metasymbol |
$3 |
match of the third metasymbol |
Exact tokens match exact tokens. So for $-@$+ on bhunter@stalker.acme.com:
$1 bhunter
$2 stalker.acme.com
@@ @
Address Transformations
The address transformation metasymbols are:
|
|
$N |
substitute indefinite token N |
$[string$] |
substitute canonical string |
$>N |
call ruleset N |
$@ |
terminate ruleset |
$: |
terminate rewrite rule |
For example, applying focus, the address
bhunter@jaeger
must transform to
bhunter@<jaeger>
so the rewrite rule is
R$+<$+>
In the transformation
$1@$2<.$B>
where $B is defined as acme.com, the address
alone will transform from
bhunter@jaeger
to
bhunter@jaeger.acme.com
the rule is written
R$+<@.$+> $1@$2<.$B>
to use Acme's full Internet address.
Getting More Help
sendmail configuration is complex and debugging sendmail
is an art (although the tools are provided). An excellent
book on
the subject is O'Reilly's Administering TCP/IP, by Craig
Hunt.
The most complete coverage I have ever seen is a seminar
called "Sendmail
Made Easy" by Robert Harker. For information, contact
harker@harker.com.
About the Author
Bruce H. Hunter is the co-author, with Karen Hunter,
of UNIX Systems
Advanced Administration and Management Handbook (Macmillan:
1991).