Linux Server Security (2nd Edition( [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Linux Server Security (2nd Edition( [Electronic resources] - نسخه متنی

Michael D. Bauer

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







9.4. Sendmail


Sendmail
is one of the most venerable Internet software packages still in
widespread use: it first appeared in 4.1c BSD Unix (April 1983), and
to this day, it has remained the most relied-upon application of its
kind. But Sendmail has both advantages and disadvantages.


9.4.1. Sendmail Pros and Cons


On the plus side, Sendmail has a huge
user community; as a result, it's easy to find both
free and commercial support for it, not to mention a wealth of
electronic and print publications. It's also stable
and predictable, one of the most mature network applications of all
time.

On the downside, Sendmail has acquired a certain amount of
"cruft" (layers of old code) over
its long history, resulting in a reputation of it being insecure and
bloated. Both charges are open to debate, however.

While it's true that Sendmail has had a number of
significant
vulnerabilities
over the years, these have been brought to light and fixed very
rapidly. An argument can therefore be made that Sendmail security is
a glass half-empty/half-full situation. Depending on your viewpoint,
Sendmail's various vulnerability reports and
subsequent patches may prove that Sendmail is inherently insecure; or
perhaps the fact that they come to light and are fixed quickly proves
that Sendmail's development team and user community
are pretty much on top of things, or maybe you think the truth is
somewhere in between. (I'm in this last camp.) A more useful criticism is that Sendmail is monolithic: a
vulnerability in one portion of its functionality results in the
compromise of the entire application. Since Sendmail must run as
root when performing some of its duties,
any Sendmail vulnerability has the potential to
be used to gain root privileges.

As for the "bloatware" charge,
it's true that Sendmail has a much larger code base
than other MTAs such as Qmail and Postfix, as well as a larger RAM
footprint. This probably has at least as much to do with
Sendmail's monolithic architecture (one executable
provides the great majority of Sendmail's
functionality) as it does with cruft. However,
Sendmail's code has been scrutinized so closely by
so many programmers over the years that it's a
little hard to believe that too much blatantly unnecessary or
inefficient code has survived intact over the past 20 years.

Sendmail is also criticized for its complexity. The syntax of its
configuration file, sendmail.cf, is
nonintuitive, to say the least. In my opinion, its difficulty ranks
somewhere between C and regular expressions. Like them, this is due
to Sendmail's power. Regardless, this point is now
largely moot: modern versions of Sendmail can be configured via
m4 macros, which provide a much less
user-hostile experience than editing sendmail.cf
directly.


A Disclaimer


I'm a Postfix fan myself. I run Postfix as my
domain's public SMTP gateway (though I do use
Sendmail on my private network for local mail delivery). Therefore,
nothing in this section, including its very existence, should be
construed to mean that I think Sendmail is the best choice for
everyone's MTA needs. You'll need
to decide for yourself whether Sendmail is the best tool for your
environment.

However, I will say that I've spent a good deal of
time over the past few years using and helping others to use
Sendmail, and I think it's a lot better than many
people give it credit for. In my experience, Sendmail is
not the lumbering, slobbering, fragile beast
some of its critics make it out to be.

In fact, I've found Sendmail to be stable and
powerful, if a bit scary in its complexity. Furthermore, since the
last CERT® advisory involving a remote-exploit
vulnerability in Sendmail was in 1997 (number CA-1997-05),
I'm simply not convinced that Sendmail is inherently
unsecurable, as D. J. Bernstein and others insist. If it were, the
CERT® advisories would continue to roll right out:
Sendmail has been under more scrutiny in the
past seven years than it was beforehand!

So while other MTAs (notably Postfix and Qmail) may have clear
advantages over Sendmail in performance and, yes, security, I also
think that Sendmail is nonetheless useful and securable enough to
take seriously.

Regardless of one's opinions on
Sendmail's cruftiness, it's
unquestionably a powerful and well-supported piece of software. If
Sendmail's benefits are more compelling to you than
its drawbacks, you're in good company. If you also
take the time to configure and maintain Sendmail with security in
mind, you're in better company still.


9.4.2. Sendmail Architecture


As I mentioned earlier,
Sendmail
is monolithic in that it does all its real work with one executable,
sendmail. sendmail has two
modes of operation: it can be invoked as needed, in which case it
will process any queued mail and then quit, or it can be run as a
persistent background daemon.

Daemon
mode is required only when
Sendmail's role is to receive mail from external
hosts; if you just use Sendmail to send mail, you
shouldn't run sendmail as a
daemon. In fact, you can probably stop reading now since
sendmail doesn't really need
any customization to do this, unless you wish to run it chrooted (see
the section "Configuring Sendmail to Run
Semichrooted").

The way sendmail works, then, depends on how
it's being run. If it's running as
a daemon (i.e., with the -bd flag), it listens for
incoming SMTP connections on TCP port 25 and periodically tries to
send out any outbound messages in its queue directory,
/var/spool/mqueue. If it's
being invoked on the fly, it attempts to deliver whatever outbound
message it's been invoked to send and/or checks
/var/spool/mqueue for other pending outbound
messages.

Sendmail's
configuration files are kept mainly in
/etc/mail, with a few files (usually
aliases, aliases.db, and
sendmail.cf) residing one level higher in
/etc. /etc/sendmail.cf is
its primary configuration file. /etc/mail
contains sendmail.mc, which can be used to
generate /etc/sendmail.cf.
/etc/aliases.db, which is generated from the
text file /etc/ aliases, contains mappings of
username aliases.

There's one other main repository of Sendmail files,
containing its static
m4
scripts (as opposed to the dynamic configuration files in
/etc/mail). On Red Hat systems, this repository
is /usr/share/sendmail-cf; on SUSE systems,
it's /usr/share/sendmail; and
on Debian GNU/Linux hosts, it's
/usr/share/sendmail/sendmail.cf. You
shouldn't need to edit these files.

That's as much as most of us need to know about how
Sendmail is structured. Which is not to discourage you from seeking
greater understanding, for which I recommend Costales and
Allman's book sendmail
(O'Reilly).


9.4.3. Obtaining and Installing Sendmail


I can state with absolute certainty
that your Linux distribution of choice includes one or more packages
for Sendmail. Whether it's presently installed on
your system and is an appropriate version for you to use, however, is
another matter.

If you use an RPM-based distribution (Red Hat, Mandrake, SUSE, etc.),
you can see whether Sendmail is installed and what its version is by
issuing the command:

rpm -qv sendmail If you use Debian GNU/Linux, you can do the same thing with
dpkg:

dpkg -s sendmail Note that Red Hat and its derivatives split Sendmail into three
packages: sendmail,
sendmail-cf, and
sendmail-doc. SUSE and Debian, however, each use
a single package named sendmail (in their
respective package formats).

The major Linux distributions' respective Sendmail
packages are all based on current versions of Sendmail that support
both SMTP AUTH and START-TLS. Therefore, the odds of you needing to
compile Sendmail from source are fairly slim, unless you need some
obscure feature or wish to compile Sendmail with only those features
you need (e.g., to minimize the binary's size for
use on an embedded platform). Sendmail source code is available at
http://www.sendmail.org.

Once you've installed Sendmail, either in the form
of a binary package from your distribution or a source-code tarball
you've compiled yourself, you've
still got a couple of tasks left before you can use
sendmail as a daemon. For the remainder of this
discussion, I'll assume that you're
using Sendmail 8.12.0 or higher unless otherwise noted.

9.4.3.1 Sendmail on SUSE


With SUSE Linux, you can use yast to configure
Sendmail if your SMTP needs are simple enough. Start
yast, select "Network
Services," and then select "Mail
Transfer Agent." For any bastion server (SMTP relay) you'll want to
set "(Internet) Connection type" to
"permanent" and your
"Outgoing mail server" to
" " (blank) in the
yast MTA applet's initial
screen. In the subsequent screens you can set up masquerading, which
determines how Sendmail should rewrite the senders'
addresses of outbound messages, and the equivalent aliases and
virtual domains settings for incoming mail.

yast will then automatically rewrite the file
/etc/sysconfig/sendmail and the relevant files
in /etc/mail, generate the hash databases in
/etc/mail (if applicable), and restart Sendmail.
You may then manually tweak
/etc/sysconfig/sendmail and the others as you
see fit, in order to further customize your Sendmail setup.

Configuing Sendmail via yast
isn't mandatory; in fact, the Section 9.4.5 is written for those who
prefer the hands-on approach of manually editing
/etc/mail/linux.mc and creating tables in
/etc/mail. This approach is the only way to take
advantage of Sendmail's advanced security features
(STARTTLS, et al).


If you intend to create a custom Sendmail configuration (without
yast), you'll need to set the
parameter MAIL_CREATE_CONFIG to
no in /etc/sysconfig/mail.
Otherwise, SuSEconfig will eventually overwrite
your custom configuration.

9.4.3.2 Red Hat Sendmail preparation


If you're a Red
Hat user, you need perform only one task prior to configuring
Sendmail: edit the file /etc/sysconfig/sendmail
so that the variable DAEMON is set to
yes. This will tell the startup script
/etc/init.d/sendmail to start
sendmail as a daemon at boot time.

9.4.3.3 Debian Sendmail preparation


If
you've decided to use Debian's
official package of Sendmail, you'll get a head
start on configuring Sendmail at installation time: the deb
package's post-installation script
includes an interactive question-and-answer session that leads to the
automatic generation of sendmail.cf. Depending
on how straightforward your needs are, this may suffice. Even if your
configuration requires subsequent fine-tuning,
you'll probably find Debian's
automatically generated configuration to be a convenient starting
point.


9.4.4. Configuring Sendmail: Overview


The
easiest way to generate Sendmail configurations is to follow these
steps:

Enable needed features and tweak settings in
sendmail.mc.[1] [1] In SUSE, this file
is named linux.mc.
Set up domain-name masquerading, if needed, in
sendmail.mc.

Run m4 to generate
sendmail.cf from
sendmail.mc.

Configure delivery rules by editing mailertable.

Configure relaying rules by editing access.

Configure multiple-domain handling rules by editing
virtusers.

Define local user aliases in aliases.

Convert mailertable,
access, virtusers, and
aliases to databases.

Define all valid hostnames of the local system in the file
local-host-names.

(Re)start sendmail.

Once set up properly, sendmail.mc,
mailertable, access, and
virtusers won't need to be
changed very often, if at all. The most volatile configuration
information on any email system is usually user information.
Therefore, on Sendmail systems, /etc/aliases is
the file that will probably need the most ongoing maintenance.


9.4.5. Configuring sendmail.mc


The
first task in setting up an SMTP server is generating
/etc/sendmail.cf, for which I strongly suggest
you use /etc/mail/sendmail.mc (on SUSE systems,
/etc/mail/linux.mc). That's the
method I describe here.


Depending on which Linux distribution you use, a complete
configuration reference for sendmail.mc can be
found in /usr/share/sendmail-cf/README.cf (Red
Hat and its derivatives),
/usr/share/sendmail/README (SUSE), or
/usr/share/doc/sendmail/cf.README.gz (Debian).

The "mc" in sendmail.mc
is short for "macro
configuration." sendmail.mc
consists mainly of parameters, or
"directives" in
Sendmail's parlance, that are passed to Sendmail
macros, or that dereference (expand to) other macros. There are
several types of macro directives to be aware of, most notably
dnl, define,
undefine, and FEATURE, all
of which appear in the truncated sendmail.mc
listing in Example 9-1.

Example 9-1. Excerpt from an /etc/mail/sendmail.mc file


dnl This is a comment line
include(`/usr/lib/sendmail-cf/m4/cf.m4')
VERSIONID(`Mail server')dnl
OSTYPE(`linux')
define(`confDEF_USER_ID',``8:12'')dnl
define(`confPRIVACY_FLAGS', `authwarnings,needmailhelo,noexpn,novrfy')dnl
define(`confSMTP_LOGIN_MSG', ` Sendmail')dnl
define(`confSAFE_FILE_ENV', `/var/mailjail')dnl
define(`confUNSAFE_GROUP_WRITES')dnl
undefine(`UUCP_RELAY')dnl
undefine(`BITNET_RELAY')dnl
FEATURE(`access_db',`hash -o /etc/mail/access.db')dnl
FEATURE(`smrsh',`/usr/sbin/smrsh')dnl
FEATURE(`dnsbl')dnl
FEATURE(`blacklist_recipients')dnl
FEATURE(`mailertable',`hash -o /etc/mail/mailertable.db')dnl
FEATURE(`virtusertable',`hash -o /etc/mail/virtusertable.db')dnl
FEATURE(`use_cw_file')dnl
FEATURE(`masquerade_entire_domain')dnl
FEATURE(`masquerade_envelope')dnl
FEATURE(`nouucp')dnl
MASQUERADE_AS(`hackenbush.com')dnl
MASQUERADE_DOMAIN(`.hackenbush.com')dnl
EXPOSED_USER(`root')dnl
MAILER(smtp)dnl
MAILER(procmail)dnl The first important type of sendmail.mc
entry is the comment. Comment lines begin with the string
dnl, which is short for "delete
through newline." Besides appearing at the beginning
of each comment line, dnl can also be used at the
end of "real" lines, which prevents
unnecessary blank lines from being inserted into
/etc/sendmail.cf. The first line in Example 9-1 is a comment line.

The next interesting type of sendmail.mc directive
is an m4 variable definition, which always
begins with the string define or
undefine, followed by a variable name and, if
applicable, a value to assign to it. The syntax for definitions
should be obvious in Example 9-1. Note that the
`' marks enclosing variable names and values
prevent them from being prematurely expanded by
m4. Some variables are Boolean
(TRue or false).

Another
important kind of directive is the FEATURE. These
lines each begin with the string FEATURE, followed
by one or more parameters enclosed in directed quotation marks
(`').

Similar in
syntax to FEATURE statements,
MAILER directives are placed at or near the end of
sendmail.mc and define which mailers are
supported on the system. In Example 9-1, the last
two lines tell Sendmail to support the exchange of mail with SMTP and
procmail agents.

Finally, there are some directives that invoke and configure macros
directly by name. MASQUERADE_DOMAIN,
MASQUERADE_AS, and
EXPOSED_USER are a few such macros that are
present in Example 9-1.

9.4.5.1 Some sendmail.mc m4 variable definitions


Let's look at specific
sendmail.mc
directives that affect security, beginning with some definitions:

define(`confDEF_USER_ID',` userid:groupid')dnl

The confDEF_USER_ID
definition tells Sendmail under
which user ID and group ID it should run by default. If this variable
isn't defined, its values default to
1:1 (user=bin,
group=bin), but I recommend changing it, since
the bin user account and group account provide
greater privileges than Sendmail really needs. Red
Hat's default of 8:12
(user=mail, group=mail) is
more sensible. Sendmail is intelligent enough to run as
root while listening on TCP port 25 (which is a
privileged port) but to demote itself to whatever value is set in
confDEF_USER_ID once mail arrives.

Beforehand, you may need to add a user and group for Sendmail to use.
If your system doesn't already have a group named
mail, use this command:

groupadd -g 12 mail Similarly, if your system doesn't have a user
account named mail, use this command to create
one:

useradd -u 8 -g 12 -d /var/spool/mail -s /bin/false mail

define(`confPRIVACY_FLAGS', ` flag1,flag2,etc.')dnl


As you can see, when we define the macro
confPRIVACYFLAGS, we can specify a list of one
or more flags that determine how Sendmail behaves in SMTP sessions.
Table 9-1 shows some flags I recommend using on
any publicly accessible Sendmail server.

Table 9-1. Useful privacy flags in Sendmail


Privacy flag

Description

Goaway

Sets all privacy flags except noreceipts,
restrictmailq, restrictqrun,
restrictexpand, and noetrn.


needmailhelo

Forces all SMTP clients to begin their sessions by identifying
themselves with a HELO or
EHLO command.


Noexpn

Disables the EXPN and VERB
commands.


Novrfy

Disables the VRFY command.


noreceipts

Disables the returning of return and read receipts.


restrictmailq

Allows only members of the group that owns
/var/spool/mqueue to view
Sendmail's queue files via the
mailq command. Note that if you set this flag,
the permissions on /var/spool/mqueue may still
be at 0700 without impairing mail-group
members' ability to run mailq.


restrictqrun

Allows only root or the owner of
/var/spool/mqueue to process
Sendmail's queue (i.e., to tell Sendmail to attempt
to send all messages currently in its queue, à la
sendmail -q).


authwarnings

Indicates discrepancies (e.g., sender claims her hostname is
tubby.tubascoundrels.org, but her IP
reverse-resolves to matahari.boldimposters.net)
within the affected message's
X-Authentication- Warning header.


needexpnhelo

Indicates that SMTP clients needn't begin with
HELO or EHLO unless they
wish to use the EXPN command at some point, in
which case they must HELO or
EHLO first.


needvrfyhelo

Indicates that SMTP clients needn't begin with
HELO/EHLO unless they wish
to use the VRFY command at some point, in which
case they must HELO or EHLO
first.


define(`confSMTP_LOGIN_MSG', ` message')dnl



This variable defines the banner string that
sendmail sends to remote clients at the
beginning of each SMTP session. By default, this string is set to:

`$j Sendmail $v/$Z; $b' where $j expands to the local Fully Qualified
Domain Name (FQDN), $v expands to the
sendmail daemon's version,
$Z expands to the version number of the
m4 configuration, and $b
expands to a time/date stamp.

In truth, none of this information needs to be provided. I personally
prefer to set my Sendmail login message to a minimal
`Sendmail'.


define(`confSAFE_FILE_ENV', ` /path/to/jail')dnl



This definition tells Sendmail to set
sendmail.cf's
SafeFileEnvironment variable to some subdirectory
of / to which sendmail will
chroot when writing files. For more information, see the section
entitled Section 9.4.6.


define(`confUNSAFE_GROUP_WRITES')dnl



In Example 9-1,
confUNSAFE_GROUP_WRITES has been set to
true. If TRue,
confUNSAFE_GROUP_WRITES causes Sendmail to log a
warning message whenever mail is handled by a
.forward or :include: file
that is group- or world-writable. Furthermore, if such a
.forward or :include: file
contains any address pointing to an unsafe file, such as an
executable, the message being processed will be bounced and logged
accordingly.

This is an extremely useful feature for SMTP shell servers, for the
obvious reason that a world- or group-writable
.forward file carries a high risk of being
altered by some malicious local user and therefore
shouldn't be trusted.
confUNSAFE_GROUP_WRITES isn't as
meaningful for SMTP gateways, however, on which there
aren't ordinary end users to worry about.



There are other security-related definitions, but
they're all pertinent to SMTP AUTH, which is covered
later in the chapter.

9.4.6. Configuring Sendmail to Run Semichrooted


As mentioned earlier in the chapter,
Sendmail doesn't
lend itself very well to chrooting, partly as a symptom of its
monolithic architecture (one executable does everything). However,
the configuration directive confSAFE_FILE_ENV can
be used to tell Sendmail to chroot itself when writing files.

This occasional chroot approach makes sense for Sendmail.
We're probably most worried about file writes, and
creating a safe file environment is a lot simpler than building a
chroot jail that contains copies of every
directory, file, executable, and device needed for a complex
application like Sendmail to run fully chrooted.

Example 9-2 shows the commands (only three!) needed
to create a safe file environment.

Example 9-2. Creating a chroot jail


bash$ mkdir -p /var/mailjail/var/spool/mqueue
bash$ chown -R 8:12 /var/mailjail*
bash$ chmod -R 1755 /var/mailjail/var/spool/mqueue

9.4.6.1 Feature directives and databases


Features in sendmail.mc are syntactically
similar to definitions (although they impact
sendmail.cf differently). Many of these features
refer to external database files to store various types of
mail-handling information. These database files, stored in binary
format, allow Sendmail to rapidly retrieve externally maintained data
such as user aliases and mail-routing rules.

Several Unix database file formats are supported by Sendmail. Most
prepackaged versions of Sendmail support the newer
hash or
btree
database formats. The older
dbm format
may or may not be an option, too, depending on whether your version
of Sendmail was compiled with it.

You can find out which formats are supported on your system by
invoking the
makemap command
with its -l flag (Example 9-3).

Example 9-3. Determining supported database formats


bash-# makemap -l
hash
btree Unless, for some reason, you share databases with hosts running older
versions of Sendmail, I recommend sticking to
hash.

Let's look at some features pertinent to security:

FEATURE(`mailertable',` hash|dbm|btree [-o] /path/mailertable. db')dnl


The
mailertable feature causes
sendmail to reference the file
/etc/mail/mailertable.db when determining how to
route incoming mail. This feature thus adds to the modularity of
Sendmail's configuration.

The comma and everything that follows it is called the map
definition, and it's used to specify the
file format and path of the map being defined. If your map definition
includes the -o
("optional") flag, Sendmail will
check for mailertable.db but not require it. If
the map-definition portion of this statement (the comma and
everything after it) is omitted, it defaults to `hash
/etc/mail/ mailertable.db
' We'll look at syntax and examples of the
mailertable itself in the section titled
"Configuring Sendmail's Delivery
Rules."

FEATURE(`access_db',` hash|dbm|btree [-o] /path/access.db')dnl


This is another modularizing feature. Creating an
access database provides a convenient way
to maintain a list of both allowed and explicitly denied relaying
hosts and domains. (See
FEATURE(`mailertable'...) for
a description of valid database types and of the
-o ("optional")
flag). If the map definition portion of this statement is omitted, it
defaults to `hash /etc/mail/access.db' As with mailertable, we'll
cover access syntax and examples in
"Configuring Sendmail's Delivery
Rules."

FEATURE(`virtusertable',` hash|dbm|btree [-o] /path/virtusertable.db')dnl


The virtual user table, or
virtusertable,
is yet another separate configuration file for
sendmail that can be maintained separately from
sendmail.cf. This one determines how virtual
domains are handled. The simplest definition of virtual domains is
"email addresses hosted by the server, but with
different domain names from the one in which the
server's FQDN resides." (See
FEATURE(`mailertable'...) for
a description of valid database types and of the
-o ("optional")
flag). If the map-definition portion of this statement is omitted, it
defaults to `hash /etc/mail/ virtusertable.db' virtusertable, too, is covered in
"Configuring Sendmail's Delivery
Rules."
FEATURE(`use_cw_file')dnl



If listed, this feature causes sendmail to use
the file /etc/mail/local-host-names to determine
valid local namesi.e., names that, if used to the right of the
"@" in an email address, will cause
that mail to be delivered locally. This is part of
Sendmail's anti-spam-relaying functionality.


FEATURE(`smrsh', ` /path/to/smrsh')dnl


Like confUNSAFE_GROUP_WRITES, the
Sendmail Restricted Shell
(smrsh) protects your server from unpredictable
local users and is therefore of more use on SMTP shell servers than
on SMTP gateways. smrsh restricts which programs
your users may execute from their .forward files
to those that reside in (or are pointed to by symbolic links in)
smrsh's directory, usually
/usr/lib/sendmail.d/bin/.


FEATURE(`dnsbl', ` blackhole.list.provider')dnl


This feature uses a special DNS lookup to check all
senders' hostnames against a
"black hole list" of
known sources of UCE. If omitted, the name of the
blackhole.list.provider defaults to
blackholes.mail-abuse.org. Note that this is a
subscription-based service: mail-abuse.org
charges a yearly fee for nonpersonal use. See http://mail-abuse.com/services/mds-rbll
for more information.


FEATURE(`blacklist_recipients')dnl



This feature checks recipient addresses of incoming mail against the
access database to block mail to selected usernames (e.g.,
lp).


FEATURE(`nouucp')dnl



This directive completely disables UUCP support in Sendmail. This is
a good safety measure, assuming you don't share mail
via the old UUCP protocol.



9.4.6.2 Masquerading


Masquerading
is the rewriting of From: fields in SMTP headers
to make mail originating from one host appear to originate from
another. If multiple hosts on your network send mail but only one can
receive it, you need masquerading so replies can be sent back to mail
sent by nonreceiving hosts. It's also useful for
aesthetic reasons e.g., if you want all the mail from your
domain to have From: fields that use the form
user@domain rather than

MASQUERADE_AS( host.or.domain.name)dnl



This macro lets you specify what you want to appear after the
"@" in your
From addresses. For example, if I specify
MASQUERADE_AS(tubby.tubascoundrels.
org)dnl, mail handled by my server will seem to
originate from the host tubby.tubascoundrels.org
regardless of my server's hostname or even its
domain name (depending on other macros).

If I specify MASQUERADE_AS(tubascoundrels.org)dnl,
my From addresses will be rewritten to show only
the domain name tubascoundrels.org, not the full
hostname of the host on which the message actually
originatede.g., domain.name)dnl



By default, mail originating on the Sendmail server (i.e.,
From addresses containing hostnames listed in
/etc/mail/local-host-names) will be masqueraded.
If mail from other hosts is handled by this host
and that mail is to be masqueraded as well, each fully qualified
hostname needs to be listed in a MASQUERADE_DOMAIN
directive. Continuing my previous example, if the SMTP relay
tubby.tubascoundrels.org domain also handles
outbound email from weird-al.polkatistas.org,
the relay's sendmail.mc file
will need to include the directive
MASQUERADE_DOMAIN(weird-al.polkatistas.org)dnl for
both hosts' mail to be masqueraded.


MASQUERADE_DOMAIN_FILE(` /path/filename')dnl



If you have a lot of hosts/domains to masquerade, you may wish to
specify them in a separate text file (one domain name per line). The
MASQUERADE_DOMAIN_FILE
directive lets you name such a file, conventionally
/etc/mail/domains (not to be confused with
/etc/mail/domaintable).


FEATURE(`masquerade_entire_domain')dnl


The
feature
masquerade_entire_domain causes
MASQUERADE_DOMAIN to be interpreted as an entire
domain rather than a hostname.


FEATURE(`masquerade_envelope')dnl



This feature causes sender addresses to be masqueraded not only in
the From: header field but also in the SMTP
envelope.


EXPOSED_USER( username)dnl


EXPOSED_USER
specifies a username for whom the From address
should not be masqueraded. root is a popular
candidate for this, since email from root often
contains alerts and warnings; if you receive such an alert or
warning, you generally want to know which host sent it.



These are the most important sendmail.mc
settings for security purposes. There are many other nonsecurity
settings, however. For more information, see the
README.cf or cf.README.gz
file I alluded to earlier in this section.

9.4.6.3 Applying your new configuration


To compile your macro-configuration file into
sendmail.cf, use this
command:

bash-# m4 /etc/mail/sendmail.mc > /etc/sendmail.cf If your macro-configuration file's name
isn't sendmail.mc, substitute
it with linux.mc or whatever yours is called.
Sendmail expects its configuration file to be named
sendmail.cf,
however, and it looks for it in /etc, so that
part of the command is the same, regardless of your distribution or
even your version of Sendmail.

After each time you change
sendmail.mc/sendmail.cf, you need to restart
sendmail. The easiest way to do this is with its
startup script /etc/init.d/sendmail, e.g.:

bash-# /etc/init.d/sendmail restart

9.4.7. Configuring Sendmail's Maps and Other Files


Generating sendmail.cf was the complicated part,
but you're not done yet. Now you need to tell
Sendmail what the legitimate local hostnames are; what to do with
incoming mail; which users, networks, and domains may use your SMTP
gateway to relay mail with nonlocal destinations; and what aliases
refer to what users. These settings can be specified in the text
files and maps in /etc/mail.

9.4.7.1 local-host-names


If you've set the feature
use_cw_file in sendmail.mc,
Sendmail will use the file /etc/
mail/local-host-names, a text file containing hostnames,
listed one per line.

Sendmail refers to /etc/mail/local-host-names in
determining whether messages should be delivered locallyi.e.,
to a user on the SMTP gateway system itself. If Sendmail incorrectly
determines a given address to be nonlocal, it may forward the message
back out, resulting in a loop.

Suppose our sample SMTP gateway receives email not only for the
domain polkatistas.org (the domain on which its
own FQDN resides) but also for
tubascoundrels.net. If our
gateway's hostname is mail, its
local-host-names file might look like Example 9-4.

Example 9-4. /etc/mail/local-host-names


localhost
localhost.localdomain
polkatistas.org
mail.polkatistas.org
tubascoundrels.net
mail.tubascoundrels.net Note that
local-host-names is a flat text file: unlike
mailertable, aliases,
access, and most other files to which Sendmail
refers on an ongoing basis, local-host-names
should not be converted to a map (database) format.

9.4.7.2 Configuring the mailertable


If you defined the feature mailertable, you now
must edit that file in order to define delivery rules. This is an
important feature: the mailertable lets you
define with considerable granularity which types of email may be
relayed (based on destination address) and how.

mailertable has a simple syntax that is
described in the same file that documents
sendmail.mc (README.cf or
cf.README.gz, depending on your distribution).
In a nutshell, each line in mailertable contains
two parts: a destination identifier and an action. The destination
identifier matches destination addresses or parts thereof; the action
tells sendmail what to do with messages whose
destinations match the identifier.

If the identifier begins with a
".", all email destination
addresses ending in the text following the dot will match. Otherwise,
everything following the "@" sign
in a destination address must be identical to the identifier. The
email address Example 9-5 shows a sample
/etc/mail/mailertable file on an
SMTP gateway, with three typical
actions.

Example 9-5. A simple mailertable


fake.polkatistas.org local:postmaster
.polkatistas.org smtp:%2
polkatistas.org smtp:internalmail.polkatistas.org
. smtp:internalmail.polkatistas.org In line one of Example 9-5, Sendmail is instructed
to send mail addressed to any user on the host
"fake" (which may not even exist)
to the local user postmaster. In line two,
Sendmail is told to route mail addressed to all other hosts on the
polkatistas.org domain directly to those
respective hosts via SMTP ("%2" is
parsed as "everything after the @ sign,
verbatim": i.e., it tells Sendmail to act as a dumb
relay for these destinations).

This technique is useful if your network has multiple internal mail
servers or if you want to send mail directly to certain internal
servers from the outside. If, on the other hand, you wish to forward
all inbound mail to a single internal mail hub (whose own
mailertable may contain dumb-relay entries), you
could substitute smtp:%2 with
smtp:internalmail.polkatistas.org.

Line three of Example 9-5 tells Sendmail to route
all mail addressed to the destination
polkatistas.orge.g.,
leading dot in line two matches destinations in which
polkatistas.org is preceded by a host and/or
subdomain namee.g.,
frankie.milwaukeeans.polkatista.org or
fileserver.polkatista.org.

Without the leading period, only destinations containing the
specified string but nothing more will match.
Suppose Sendmail is evaluating the address
Example 9-5:
this address won't match line one since its
destination isn't
fake.polkatistas.org, nor will it match
.polkatistas.org because
there's no host or subdomain name between the
"@" sign and
"polkatistas.org". It will,
however, match line three.

Finally, line four of Example 9-5 has as its
destination identifier a lone ".".
This translates to "none of the
above": it matches any nonlocal destination that
matches none of the lines preceding it. In line four,
we're telling Sendmail that the default action for
nonlocal destinations is to relay such messages to the internal mail
server via SMTP.

Any transport referred to in mailertable must be
defined as a legitimate mailer via a corresponding MAILER() directive at or near the end of
sendmail.mc. The transport
"local" is a special case; by
default, this refers to the local sendmail
daemon, but it's more efficient to use a proper MDA
such as procmail. Use the sendmail.mc
feature local_procmail, described
earlier in the "Feature directives"
section, to set this. (Don't forget to include a
MAILER( ) directive
for procmail!) MAILER
directives are described in README.cf.

Each time you create or edit mailertable, you
must convert it into a map (database) file. The traditional way to
make maps is with the command makemap. For
example, if you're using hash databases (as defined
in your FEATURE(`mailertable'.
..) directive), you could convert
mailertable to a map file like this:

bash-# makemap hash /etc/mail/mailertable.db < /etc/mail/mailertable In recent versions of Sendmail, there's another way
to do this, facilitated by a Makefile
automatically placed in /etc/mail when you
installed Sendmail. To use it, simply change your working directory
to /etc/mail, and execute this command:

bash-# make mailertable

9.4.7.3 Configuring the access database


Next we need to define which hosts and
networks (domains) may relay messages through our server. We can do
this by editing /etc/mail/access. Its syntax is
simple: each line contains a source name or address, paired with an
action (again, see README.cf or its equivalent
on your distribution for details). The action can
be RELAY, REJECT,
DISCARD, OK, or
ERROR. In practice, the most useful of these is
RELAY. Since by default relaying is rejected,
REJECT and DISCARD are useful
only when defining exceptions to other RELAY rules
(the list is parsed top to bottom, so be sure to list any exceptions
near the top).

Example 9-6 shows a simple access file.

Example 9-6. Simple access file


localhost.localdomain RELAY
localhost RELAY
127.0.0.1 RELAY
192.168 RELAY Notice the absence of real hostnames in Example 9-6.
In this example, the SMTP gateway performs only outbound relays:
inbound mail must be addressed to a local email address, and outbound
relays must originate from hosts whose IP addresses begin with the
octets "192.168" (obviously a
non-Internet-routable network). I like this technique of using IP
addresses because firewalls can prevent IP-address spoofing but not
forged From: addresses in email. Your needs may
be different.

As with mailertable,
access must be converted to a map file before
Sendmail will see your changes. You can do this by executing the
command make access from within
/etc/mail, or with the following:

bash-# makemap hash /etc/mail/access.db < /etc/mail/access The access database has been made somewhat
obsolete by Sendmail's support for SMTP AUTH. If you
decide to restrict relaying by requiring authentication, you can omit
the access database or leave it empty; see the
section "Sendmail and SMTP AUTH" to
learn how.

9.4.7.4 Configuring virtusers


The virtusers
database is useful when multiple (virtual) domains are served by a
single SMTP host. Its syntax is very similar to that of
aliases: each line contains an address or
address mask on the left and a corresponding destination address on
the right. If the address on the left is in the format
username@host.name, it will be interpreted
literally; if no username is specified (e.g.,
@host.name), it will
be interpreted as "any user at
host.name." Any hostname
or FQDN specified as part of an address/address mask must be listed
in local-host-names.

The destination address may be the name of a local mailbox (i.e., a
local username) or it can be a complete email address on an external
host.

In Example 9-7, we have a sample
virtusertable table for a Sendmail server
responsible for three domains.

Example 9-7. Sample virtusertable


postmaster@tubascoundrels.net root
@polkatistas.org polkawrangler
@lederhosendudes.net %1@anniefauxfanny.edu Mail addressed to address matched by this line's address
mask.") Like mailertable and
access
,
virtusertable
must be converted to a map file before Sendmail can use it. You can
execute the command make virtusertable from within
/etc/mail, or, if you prefer the long way,
enter:

bash-# makemap hash /etc/mail/virtusertable.db < /etc/mail/virtusertable

9.4.7.5 Defining aliases


There's just one more file you may wish to tweak:
aliases. While most systems store
aliases
and aliases.db in
/etc/mail, some (notably Red Hat) keep them in
/etc for historical reasons.

aliases contains a map of email aliases. Example 9-8 lists part of a sample
aliases list.

Example 9-8. Excerpt from /etc/aliases


postmaster: root
root: mick
michael: mick@visi.com
mailstooges: mick, larry, curly As you can see, aliases is fairly
self-explanatory: each line starts with an alias (something we expect
to see to the left of the "@" sign
in an email address) followed by a colon and ends with a local
username (mailbox name), another alias, or an external email address.
You can map multiple comma-delimited accounts to a single alias to
create mailing lists: this is the case with the
last entry in Example 9-8,
mailstooges.

Note that you can "cascade" aliases
as in Example 9-8; just be sure not to create any
loops, as in Example 9-9.

Example 9-9. An alias loop


postmaster: root
root: postmaster On an SMTP gateway, you probably
won't want to do very much with the
aliases database other than to tweak its entries
for postmaster, hostmaster,
root, and other infrastructure-related entries.
Rather than handling ordinary users' aliases, a
gateway should route messages based on destination hostnames and
domains (i.e., via mailertable and
virtusers) and leave alias-username translations
to the hosts to which it relays (i.e., the internal mail server,
unless for some reason the internal mail server lacks the ability to
do so).

After each edit of
aliases, you must
convert it to a map file. Unlike with access,
there's only one method to do so, and it involves
neither makemap nor make.
To generate a new aliases.db file, simply enter
the command newaliases without any flags or
arguments.


9.4.8. Sendmail and SMTP AUTH


The security controls I've
covered so far are all important: they're things
that should be enabled and configured on any publicly accessible
Sendmail server. But modern versions of Sendmail have two important
features that take Sendmail security even further: authentication and
encryption. Let's start with authentication.

SMTP AUTH, described in RFC 2554
(ftp://ftp.isi.edu/in-notes/rfc2554.txt), is a
badly needed extension to the SMTP protocol: it describes a flexible
authentication mechanism that can be used to authenticate relaying.
SMTP AUTH allows a password shared by two hosts (or stored by one
host for its local users) to be used to validate email senders.

Naturally, it's both unfeasible and
counterproductive to authenticate all SMTP
transactions, notably those involving mail addressed to or sent by
users who verifiably reside on your local system or name domain. But
authentication is extremely useful in two different SMTP-relaying
contexts, which I'll call
"server-server" and
"client-server." In
server-server relaying, a user sends mail to Server A, Server A
authenticates to Server B and relays the mail through it, and Server
B delivers the mail to its remote destination (Figure 9-1). Typically, Server A is an internal mail
server, and Server B is a DMZed SMTP gateway.


Figure 9-1. Server-to-server relaying


The second context for SMTP AUTH, one that is probably more widely
used, is client-server SMTP relaying, in which remote users
authenticate back to their "home"
SMTP gateway to send (relay) their outgoing mail (Figure 9-2). This is a handy way to let users move
between your internal network and external sites without
reconfiguring their email-client software.


Figure 9-2. Client-server SMTP relaying


If you're running an SMTP server that receives mail
relayed from other domains, you probably want to use SMTP AUTH:
it's an important defense against
Unsolicited Commercial Email, the
perpetrators of which rely heavily on open SMTP relays.

Depending on which authentication mechanism you choose, it may make
sense to encrypt your SMTP AUTH transactions via
Sendmail's TLS features. TLS stands for
Transport Layer
Security, which is the IETF's standard for and
successor to Netscape Communications' versatile and
ubiquitous SSL (Secure Sockets Layer) v3 protocol. Like HTTP, SMTP
sessions even between unauthenticated hosts can be transparently
encrypted using this protocol. Also, as with HTTP, it appears that
SMTP users tend to use TLS/SSL in this way rather than leveraging the
powerful digital-certificate-based authentication mechanisms
supported by TLS and SSL.

This isn't too surprising: one of the ugly realities
of modern IS security is that
Public Key Infrastructure (PKI)
technologies are complicated, unwieldy, and difficult to
maintain.[2] By combining digital
certificates (used as strong but unverified encryption keys) with
other, simpler authentication mechanisms such as SASL, many people
feel they get "the best of both
worlds." [2] But that hasn't prevented
me from delving into it a bit in this book, in Chapter 5.


We'll cover Sendmail's TLS features
in more depth later in this chapter.

9.4.8.1 Versions of Sendmail that support SMTP AUTH


SMTP AUTH support in Sendmail was introduced with Sendmail v8.10. As
mentioned earlier in the chapter, current versions of Red Hat,
Fedora, Debian, and SUSE Linux all ship with versions of Sendmail
that support SMTP AUTH.

If you don't use one of these distributions and
yours lacks an SMTP AUTH-enabled Sendmail package, you may need to
download
the latest Sendmail source code from http://www.sendmail.org and compile it
yourself. Before you build, however, be sure to read Claus
Aßmann's article "SMTP
AUTH in sendmail 8.10-8.12" (http://www.sendmail.org/~ca/email/authl),
which contains instructions on how to compile SMTP AUTH support into
Sendmailby default, Sendmail builds without it.

9.4.8.2 Obtaining Cyrus SASL


Sendmail actually
can't authenticate anything directly, even if it has
SMTP AUTH support compiled in. Rather, it depends on Carnegie Mellon
University's Simple Authentication and
Security Layer (SASL) package, which
authenticates against its own database or against an OS mechanism
such as PAM.

SASL can of course be obtained from CMU (at
ftp://ftp.andrew.cmu.edu/pub/cyrus- mail/).
However, it makes more sense to use your Linux
distribution's binary package, because if you
install a binary package of Sendmail that supports SMTP AUTH, the
SASL package must satisfy dependencies in Sendmail.

In Red Hat and Fedora, the RPM package you need is called
cyrus-sasl, but note that the version included
with Fedora Core 1 lacks LDAP support. This isn't a
problem if you intend to configure SASL to authenticate off a local
user database or PAM, but if you intend to use SASL for LDAP
authentication, I recommend you use the RPMs provided by Simon Matter
at
http://www.invoca.ch/pub/packages/cyrus-sasl/fc-1/.

SUSE's SASL package is also called
cyrus-sasl, and as with Fedora Core 1,
SUSE's cyrus-sasl lacks LDAP
support. With SUSE, however, I haven't found any
third-party SASL RPMs that do have LDAP support. Therefore, when I
need to use SASL for LDAP authentication under SUSE, I configure SASL
to use PAM, which I'll show how to do later in the
chapter when we get to Cyrus-IMAP.

Debian 3.0 ("Woody") includes SASL
packageslibsasl7,
libsasl7-modules, sasl-bin,
etc.but these are for an old version of SASL that is good for
little besides SASL-database authentication. The latter is the SMTP
AUTH usage I'm about to describe, but if you plan to
use SASL for LDAP authentication, I recommend you use Henrique
Holschuh's much more current deb packages, available
at http://people.debian.org/~hmh.

9.4.8.3 Configuring SASL for server-server authentication


SASL is a general-purpose authentication service that can either use
its own authentication database for authenticating SASL-aware
applications or can serve as a conduit between applications and other
authentication mechanisms such as PAM and LDAP.

If you want your Sendmail server to
authenticate other servers, it's easiest to
configure SASL to use its own authentication database,
/etc/sasldb. Sendmail can use this configuration
of SASL in sophisticated
challenge-response
mechanisms such as
CRAM-MD5
and
DIGEST-MD5
in which no secret data (i.e., passwords) is exchanged over the
network. It can also use /etc/sasldb in the much
less secure PLAIN method in which the password
is exchanged over the
networkunencrypted!but the PLAIN
method isn't appropriate unless
you're also using TLS, described later in this
chapter.

Besides its compatibility with Sendmail's
CRAM-MD5 and DIGEST-MD5
mechanisms, the other advantage of /etc/sasldb
is that it provides an alternative set of authentication credentials
besides your system- and user-account passwords. It makes sense to
avoid using actual login credentials for automated network
transactions such as server-server SMTP relaying.

Let's configure SASL for the server-server relay
scenario, then. This takes only two steps. First, we create a small,
one-line configuration file telling SASL how Sendmail authentication
should be handled. This file,
/usr/lib/sasl/Sendmail.conf, only needs to
define the variable
pwcheck_method. Possible methods include
sasldb (authenticate using
/etc/sasldb),
pam (use the operating
system's PAM
logon mechanism), and
kerberos_v4
(use the local Kerberos infrastructure,
assuming there is one).

Example 9-10 shows a SASL
Sendmail.conf file for a Sendmail server that
authenticates relays from other servers via
/etc/sasldb.

Example 9-10. /usr/lib/sasl/Sendmail.conf with sasldb authentication


pwcheck_method: sasldb The second step is to create and populate
/etc/sasldb with at least one user account. Do
this with the following command:

saslpasswd username This account should not use any username or
password in /etc/passwd. Since no one will have
to type the password in our server-to-server transaction,
there's no reason for it to be short or simple.
Example 9-11 shows a sample password-creation session
(with the password shown for illustrative purposesit
isn't echoed back to the screen in a real
saslpasswd session).

Example 9-11. An example saslpasswd session


bash-# saslpasswd maildroid
Password: Ch1mp? ,03fuzz fl0ppi
Again (for verification): Ch1mp? ,03fuzz fl0ppi Remember that password (or write it down in a safe place):
you'll use it to configure any Sendmail hosts that
need to relay mail to the one on which you created the account.
(We'll discuss how to do so shortly.) Note that if this is the first time we've run
saslpasswd, this command automatically creates
/etc/sasldb. Subsequent invocations of
saslpasswd will append to the database and not
overwrite it.

We can see the fruit of our saslpasswd labors by
entering, without flags or arguments, the command
sasldblistusers (Example 9-12).

Example 9-12. Using sasldblistusers


bash-# sasldblistusers
user: maildroid realm: dmzmail.polkatistas.org mech: PLAIN
user: maildroid realm: dmzmail.polkatistas.org mech: CRAM-MD5
user: maildroid realm: dmzmail.polkatistas.org mech: DIGEST-MD5 If for any reason you wish to delete an account
you've created in /etc/sasldb,
you can do so with saslpasswd's
-d flag, i.e.:

saslpasswd -d username Once /usr/lib/Sendmail.conf and
/etc/sasldb are ready, we can configure Sendmail
for authentication. If you're doing so as you read
this (and it's a server-server relay scenario), skip
to "Configuring Sendmail for server-server
authentication."

9.4.8.4 Configuring SASL for client-server authentication


If your Sendmail server needs to
authenticate individual users (e.g., "road
warrior" remote users) instead of other servers,
SASL configuration is much simpler. All we need to do is create a
/usr/lib/sasl/Sendmail.conf file that sets
pwcheck_method to pam (Example 9-13).

Example 9-13. A /usr/lib/sasl/Sendmail.conf file for client-server authentication


pwcheck_method: pam And that's it! Since SASL will use the existing
local PAM mechanism present on all Linux systems to authenticate
prospective relays, there's no need to create
/etc/sasldb.

Once /usr/lib/Sendmail.conf and
/etc/sasldb are ready, we must configure
Sendmail for authentication. If you're doing so as
you read this (and yours is a client-server relay scenario), skip to
"Configuring Sendmail for client-server
authentication."


Your distribution's SASL package may support other
authentication methods besides those described in this chapter (if
so, those methods may require additional RPM or deb
packagese.g., cyrus-sasl-md5). Although
one or more of these other methods may be a viable option for
authenticating your remote users, pam is the most
convenient method on most Linux systems, which is why
I'm focusing on that method here.

9.4.8.5 Configuring Sendmail for server-server authentication


There are two files to
edit to prepare our Sendmail server to authenticate other servers for
relaying. The first, predictably, is
/etc/mail/sendmail.mc, in which we must
configure the variable confAUTH_MECHANISMS and the
macro TRUST_AUTH_MECH. Both of these accept as
their definition any combination of CRAM-MD5,
DIGEST-MD5, PLAIN,
LOGIN, GSSAPI, or
KERBEROS_V4.

confAUTH_MECHANISMS is used to define which of
these authentication methods you want Sendmail to support as either a
server or a client. trUST_AUTH_MECH, on the other
hand, defines which authentication methods your Sendmail server will
accept from prospective relay clients (e.g., other servers). This is
usually but not necessarily a subset of the methods listed in
confAUTH_MECHANISMS.


If you list any mechanisms in trUST_AUTH_MECH that
are not listed in confAUTH_MECHANISMS, the
extraneous mechanisms in trUST_AUTH_MECH will fail
when attempted by clients. For clarity and
predictability's sake, I recommend that your
trUST_AUTH_MECH macro contain only mechanisms also
listed in confAUTH_MECHANISMS.

Example 9-14 shows part of an SMTP AUTH-enabled
sendmail.mc file.

Example 9-14. SMTP AUTH settings in server's sendmail.mc


TRUST_AUTH_MECH(`CRAM-MD5 DIGEST-MD5')dnl
define(`confAUTH_MECHANISMS', `CRAM-MD5 DIGEST-MD5')dnl For sasldb-based server-server authentication, I
recommend the CRAM-MD5 and
DIGEST-MD5 methods since, as
I mentioned earlier, both methods use challenge-response sessions in
which the password is used as a hash key. These methods are vastly
preferable over actually transmitting the password, as in the
PLAIN and LOGIN mechanisms.

As with any changes you make to sendmail.mc, you
should afterward regenerate sendmail.cf via the
command m4 /etc/mail/sendmail.mc >
/etc/sendmail.cf
and then restart
sendmail.


Where Does access Fit into SMTP AUTH and STARTTLS?


The access database and
SMTP AUTH both control which hosts may relay mail through our
Sendmail server. If you wish to authenticate all
relays, simply delete /etc/mail/access.db and/or
the FEATURE directive in sendmail.mc
that first enabled it, and then configure SASL and the
authentication settings in sendmail.mc described
earlier in this chapter.

If, on the other hand, you want certain hosts to relay mail without
authenticating first, add them to access (and
regenerate access.db) and configure SASL and the
authentication settings in sendmail.mc.

When one host attempts to relay through another, these steps occur in
sequence:

The "client" (relaying) host may
begin with the command STARTTLS to initiate an
encrypted TLS session. If both hosts are configured to use TLS
certificate-based authentication and that authentication succeeds,
the server allows the relay.

If no STARTTLS command was
issued or if the STARTTLS
TRansaction didn't use TLS
authentication, the "client"
(relaying) host may submit an AUTH command to try
to authenticate itself to the server. If the server supports SMTP
AUTH and the authentication succeeds, the server allows the relay.

If authentication fails or if the client host
doesn't attempt to authenticate, the
client's name and IP address are compared against
/etc/mail/access.db (if it exists). If
access.db doesn't exist or if
the client host doesn't match it, the relay is
denied.

Okay, that's the
"server" side of our server-server
transaction. This host is now ready to accept relays from other,
authenticated servers. Now we need to configure at least one
"client" system that transfers mail
through the first one.

If your client host needs only to relay mail, and not to accept
relays from other hosts, it doesn't need the
TRUST_AUTH_MECH set. It instead needs
confAUTH_MECHANISMS and
confDEF_AUTH_INFO. Be careful what you set in
confAUTH_MECHANISMS: if none of the mechanisms you
specify are supported in the other host's
TRUST_AUTH_MECH and
confAUTH_MECHANISMS directives, relaying will
fail. Also, note that your system will attempt its supported
mechanisms in the order in which they're listed.

Example 9-15 shows a relaying
Sendmail host's
confAUTH_MECHANISMS directive.

Example 9-15. SMTP AUTH settings in a relay's sendmail.mc


define(`confAUTH_MECHANISMS', `CRAM-MD5 DIGEST-MD5 LOGIN PLAIN')dnl
define(`confDEF_AUTH_INFO', `/etc/mail/default-auth-info')dnl confDEF_AUTH_INFO
specifies the location of the
authentication credentials you want your host to present to its mail
servers. This file is usually /etc/mail/default-
auth-info, and it's an ASCII text file
with the following four-line format:

authorization_identity # (i.e., username)
authentication_identity # (usually identical to username)
secret # (password created on other host with saslpasswd)
realm # (usually the FQDN of the other host) Example 9-16 shows the
/etc/mail/default-auth-info file on
dmzmail.polkatistas.org.

Example 9-16. A sample /etc/mail/default-auth-info file


maildroid
maildroid
Ch1mp? ,03fuzz fl0ppi
dmzmail.polkatistas.org Needless to say, since
/etc/mail/default-auth-info contains your relay
password in cleartext, you must protect this
file the best you can. Be sure to change its permissions mode to 600
and its owner to root.

Again, regenerate sendmail.cf and restart
sendmail. You're done! Now
whenever this host needs to relay mail through the server we
configured earlier, it will first attempt to authenticate itself as
maildroid using the CRAM-MD5
method.

9.4.8.6 Configuring Sendmail for client-server authentication


If you need to configure
your Sendmail server to authenticate relays from remote users using
MUA software (i.e., to handle those users'
"outbound" mail),
there's not much you need to do: simply set
confAUTH_MECHANISMS and
TRUST_AUTH_MECH, this time making sure that each
includes the LOGIN and PLAIN
methods.

Example 9-17 shows part of such a
server's sendmail.mc file.

Example 9-17. Part of sendmail.mc on server authenticating remote users via PAM


TRUST_AUTH_MECH(`CRAM-MD5 DIGEST-MD5 LOGIN PLAIN')dnl
define(`confAUTH_MECHANISMS', `CRAM-MD5 DIGEST-MD5 LOGIN PLAIN')dnl The client-server SMTP relay authentication scenario
I'm describing here is applicable mainly to
non-Linux clients. Although this book is about Linux, such scenarios
are very common, even when the SMTP server itself runs Linux.


If your remote users do in fact use Linux, their outbound email
should probably be delivered not by their MUA but by their local
sendmail process (although some of the newer
Linux MUAs such as GNOME's
balsa do support SMTP). We've
already covered how to configure Sendmail as an SMTP AUTH client; the
specifics are the same whether this client runs Sendmail as a daemon
(i.e., the client is a server itself) or whether it runs Sendmail
only as needed to deliver outbound mail.

On the client side, each user will need to configure his MUA with his
username and password from the Sendmail server; this is usually in a
section entitled "SMTP server
settings,"
"Sending," etc.

But there's one small problem with this (besides the
fact that your public SMTP server probably shouldn't
have ordinary user accounts, which is an architectural problem): the
LOGIN and PLAIN methods send
passwords over the network in cleartext. That's bad,
right?

Right. For this reason, TLS encryption really should be used any time
you use these methods. Luckily, many popular POP3 and IMAP
applications support TLS (SSL): among them are Evolution and MS
Outlook Express.

9.4.9. Sendmail and STARTTLS


Beginning
with Version 8.11, Sendmail supports the Extended SMTP command
STARTTLS (per RFC 2487,
ftp://ftp.isi.edu/in-notes/rfc2487.txt). When
this command is issued at the beginning of an ESMTP session, it
initiates an encrypted TLS tunnel that protects the rest of the
session from eavesdropping.

Sendmail lets you authenticate TLS tunnels with either SASL (SMTP
AUTH) or TLS-style X.509 certificate-based authentication. The
TLS/SASL combination is my focus here.

Due to the logistics of distributing and maintaining
X.509 certificates, many people who
use STARTTLS prefer using
SASL to authenticate their TLS tunnels instead of
TLS's own X.509 authentication scheme. For more
information on this and other uses of STARTTLS in
Sendmail, see Claus Aßmann's
article "SMTP STARTTLS in sendmail/Secure
Switch" (http://www.sendmail.org/~ca/email/starttlsl).

9.4.9.1 Sendmail support for STARTTLS


Sendmail support for STARTTLS began with Sendmail
8.11. If you use a current version of Red Hat, Fedora, SUSE, or
Debian Linux, you're in luck: the standard Sendmail
packages for all four distributions now support
STARTTLS.

In addition to a STARTTLS-enabled binary of
Sendmail 8.11 or 8.12, you'll need a TLS or SSL
package, if you plan to create and sign your own certificates: I
recommend OpenSSL. The binary packages for OpenSSL on RedHat, SUSE,
and Debian are all titled simply openssl, and
current versions of all three distributions should provide a
recent-enough version of OpenSSL to work properly with Sendmail.

9.4.9.2 Getting keys and certificates


If you're new to
PKI, digital certificates, or
public-key cryptography, a good
starting point is the RSA Crypto FAQ, available at http://www.rsasecurity.com/rsalabs/node.asp?id=2152;
so is Bruce Schneier's excellent
book, Applied Cryptography (Wiley).

Suffice it to say that TLS and SSL use X.509 digital certificates, a
type of public-key cryptography in which one's
public key is formatted to include a certain amount of identification
information (besides just your key ID and the public key itself),
including the digital signature of a "Certificate
Authority" (CA) that vouches for the authenticity of
the certificate. If you want an SMTP server to communicate with other
SMTP servers using TLS, it needs a digital certificate, including a
separate private key, and you need the certificate to have been
signed by some CA.

If your organization uses PKI in some capacity and you already have
either a CA of your own or a relationship with some external CA
(e.g., Verisign or Thawte), you can create your certificate locally
but will need to have your CA sign it. If you only intend to use SSL
for Sendmail, however, you'll probably want to be
your own CA. Being a CA for such limited purposes amounts to
generating a CA certificate and using it to sign your other
certificates.

Chapter 5 contains step-by-step instructions on
how to set up a CA using the excellent and free OpenSSL, and how to
create and sign X.509 certificates. See "How to
become a small-time CA" and
"Generating and signing
certificates" in Chapter 5.

For what follows here, you'll need a copy of your
CA's certificate (usually called
cacert.pem), a signed server certificate for
your SMTP host (called newcert_signed.pem in
Chapter 5 and in subsequent examples), and the
certificate's corresponding private key (called
newcert_key.pem in Chapter 5 and here). Note that contrary to my advice
in Chapter 5, the following examples will
assume you created your private key without specifying a passphrase
(using OpenSSL's --nodes flag).
This is strictly for brevity's sake; I still urge
you not to use a passphrase-free server
certificate without carefully weighing the risks.

9.4.9.3 Configuring Sendmail to use TLS


Now you've created
your sitewide CA certificate (or obtained
a copy of it if someone else controls the CA), created a new server
certificate, and signed the server certificate (or gotten it signed)
with the CA key. All that's left to preparing
Sendmail is putting things where it can find them and telling it
where they are.

The logical place to put Sendmail's copies of these
certificates is in /etc/mail/certs: create this
directory if it doesn't already exist, and make sure
it's owned by root and its mode
is set to drwx------. Copy your CA certificate
(but not its private key) cacert.pem, in
the previous examplesinto
/etc/mail/certs. Copy your server certificate
there, too, along with its corresponding private key (which are shown
as newcert_key.pem and
newcert_signed.pem, respectively, in subsequent
examples).

Make sure that all files in /etc/mail/certs are
set to mode 0600 (-rw-------); otherwise, Sendmail
will refuse to use them and TLS will not work. Example 9-18 shows a long listing of our sample
/etc/mail/certs directory.

Example 9-18. A sample /etc/mail/certs directory listing


dmzmail:/etc/mail/certs # ls -l
total 30
drwxr-x--- 2 root root 272 Feb 16 20:39 .
drwxr-xr-x 4 root root 1293 Feb 16 20:38 ..
-rw------- 1 root root 1367 Feb 16 18:55 cacert.pem
-rw------- 1 root root 2254 Feb 16 20:36 newcert_key.pem
-rw------- 1 root root 3777 Feb 16 20:32 newcert_signed.pem Now just direct Sendmail's attention to these files,
and you'll be ready to go.

A combination of the following sendmail.mc
directives, all of them variable definitions, achieves basic
server-side TLS configuration:

CERT_DIR



Designates Sendmail's certificate directory.


confCACERT_PATH



Designates where Sendmail should look for a CA certificate (usually
the same value as CERT_DIR).


confCACERT



Contains the full path of the CA certificate.


confSERVER_CERT



Contains the full path of the server certificate.


confSERVER_KEY



Contains the full path of the server key (in our examples, this key
is contained in the unsigned version of the server key).


confCLIENT_CERT



If your Sendmail server acts as a client to other SMTP servers in TLS
sessions (i.e., relays mail through other TLS-enabled SMTP servers),
this directive tells Sendmail the full path of its client
certificate. May be the same file as the server certificate.


confCLIENT_KEY



If your Sendmail server acts as a client to other SMTP servers in TLS
sessions (i.e., relays mail through other TLS-enabled SMTP servers),
this directive tells Sendmail which client key to use. May be the
same file as the server key.



Example 9-19 lists these directives on our sample
Sendmail server dmzmail.polkatistas.org, which
is set up to be both a TLS server and a client.

Example 9-19. Sample TLS directives for sendmail.mc


define(`CERT_DIR', `/etc/mail/certs')dnl
define(`confCACERT_PATH', `CERT_DIR')dnl
define(`confCACERT', `CERT_DIR/cacert.pem')dnl
define(`confSERVER_CERT', `CERT_DIR/newcert_signed.pem')dnl
define(`confSERVER_KEY', `CERT_DIR/newcert_key.pem')dnl
define(`confCLIENT_CERT', `CERT_DIR/newcert_signed.pem')dnl
define(`confCLIENT_KEY', `CERT_DIR/newcert_key.pem')dnl After you set these directives, regenerate
sendmail.cf, and restart
sendmail, your server will accept encrypted SMTP
sessions via the STARTTLS command.


/ 94