The sendmail configuration file is sendmail.cf.[112] It contains most of the sendmail configuration, including the information required to route mail between the user mail programs and the mail delivery programs. The sendmail.cf file has three main functions:
It defines the sendmail environment.
It rewrites addresses into the appropriate syntax for the receiving mailer.
It maps addresses into the instructions necessary to deliver the mail.
Several commands are necessary to perform all of these functions. Macro definitions and option commands define the environment. Rewrite rules rewrite email addresses. Mailer definitions define the instructions necessary to deliver the mail. The terse syntax of these commands makes most system administrators reluctant to read a sendmail.cf file, let alone write one! Fortunately, you can avoid writing your own sendmail.cf file, as we’ll see next.
There is never any good reason to write a sendmail.cf file from scratch. Sample configuration files are delivered with most systems’ software. Some system administrators use the sendmail.cf configuration file that comes with the system and make small modifications to it to handle site-specific configuration requirements. We cover this approach to sendmail configuration later in this chapter.
Most system administrators prefer to use the m4
source files to build a
sendmail.cf file. Building the configuration with
m4
is recommended by the sendmail
developers and is the easiest way to build and maintain a
configuration. Some systems, however, do not ship with the m4
source files, and even when m4
source files come with a system, they are
adequate only if used with the sendmail executable that comes with
that system. If you update sendmail, use the m4
source files that are compatible with the
updated version of sendmail. If you want to use m4
or the latest version of sendmail,
download the sendmail source code distribution from http://www.sendmail.org. See
Appendix E for an example of
installing the sendmail distribution.
The sendmail cf/cf directory contains several sample configuration files. Several of these are generic files preconfigured for different operating systems. The cf/cf directory in the sendmail.8.11.3 directory contains generic configurations for BSD, Solaris, SunOS, HP Unix, Ultrix, OSF1, and Next Step. The directory also contains a few prototype files designed to be easily modified and used for other operating systems. We will modify the tcpproto.mc file, which is for systems that have direct TCP/IP network connections and no direct UUCP connections, to run on our Linux system.
The prototype files that come with the sendmail tar
are not “ready to run.” They must be
edited and then processed by the m4
macro processor to produce the actual
configuration files. For example, the
tcpproto.mc file contains the following macros:
divert(0)dnl VERSIONID(`$Id: ch10.xml,v 1.9 2004/09/22 19:24:26 marti Exp $') OSTYPE(`unknown') FEATURE(`nouucp', `reject') MAILER(`local') MAILER(`smtp')
These macros are not sendmail commands; they are input for the
m4
macro processor. The few lines
shown above are the active lines in the
tcpproto.mc file. They are preceded by a
section of comments, not shown here, that is discarded by m4
because it follows a divert(-1)
command, which diverts the
output to the “bit bucket.” This section of the file begins with a
divert(0)
command, which means
these commands should be processed and that the results should be
directed to standard output.
The dnl
command that appears at the end of the divert(0)
line is used to prevent unwanted
lines from appearing in the output file. dnl
deletes everything up to the next
newline. It affects the appearance, but not the function, of the
output file. dnl
can appear at
the end of any macro command. It can also be used at the beginning
of a line. When it is, the line is treated as a comment.
The VERSIONID macro is used for version control. Usually the value passed in the macro call is a version number in RCS (Release Control System) or SCCS (Source Code Control System) format. This macro is optional, and we can just ignore it.
The OSTYPE macro defines operating system-specific
information for the configuration. The
cf/ostype directory contains almost 50
predefined operating system macro files. The OSTYPE macro is
required and the value passed in the OSTYPE macro call must match
the name of one of the files in the directory. Examples of values
are bsd4.4
, solaris8
, and linux
.
The FEATURE macro defines optional features to be included
in the sendmail.cf file. The nouucp
feature in the example shown says
that UUCP addresses are not used on this system. The argument
reject
says that local addresses
that use the UUCP bang syntax (i.e., contain an !
in the local part) will be rejected.
Recall that in the previous section we identified
tcpproto.mc as the prototype file for systems
that have no UUCP connections. Another prototype file would have
different FEATURE values.
The prototype file ends with the mailer macros. These must be the last macros in the input file. The example shown above specifies the local mailer macro and the SMTP mailer macro.
The MAILER(local) macro includes the local mailer that delivers local mail between users of the system and the prog mailer that sends mail files to programs running on the system. All the generic macro configuration files include the MAILER(local) macro because the local and prog mailers provide essential local mail delivery services.
The MAILER(smtp) macro includes all of the mailers needed to send SMTP mail over a TCP/IP network. The mailers included in this set are:
This mailer can handle traditional 7-bit ASCII SMTP mail. It is outmoded because most modern mail networks handle a variety of data types.
This mailer supports Extended SMTP (ESMTP). It understands the ESMTP protocol extensions and it can deal with the complex message bodies and enhanced data types of MIME mail. This is the default mailer used for SMTP mail.
This mailer sends 8-bit data to the remote server, even if the remote server does not indicate that it can support 8-bit data. Normally, a server that supports 8-bit data also supports ESMTP and thus can advertise its support for 8-bit data in the response to the EHLO command. (See Chapter 3 for a description of the SMTP protocol and the EHLO command.) It is possible, however, to have a connection to a remote server that can support 8-bit data but does not support ESMTP. In that rare circumstance, this mailer is available for use.
This mailer allows the destination system to retrieve mail queued on the server. Normally, the source system sends mail to the destination in what might be called a “push” model, where the source pushes mail out to the destination. On demand, SMTP allows the destination to “pull” mail down from the mail server when it is ready to receive the mail. This mailer implements the ETRN command that permits on-demand delivery. (The ETRN protocol command is described in RFC 1985.)
This mailer is used when SMTP mail must be relayed through another mail server. Several different mail relay hosts can be defined.
Every server that is connected to or communicates with the Internet uses the MAILER(smtp) set of mailers, and most systems on isolated networks use these mailers because they use TCP/IP on their enterprise network. Despite the fact that the vast majority of sendmail systems require these mailers, installing them is not the default. To support SMTP mail, you must have the MAILER(smtp) macro in your configuration, which is why it is included in the prototype file.
In addition to these two important sets of mailers, there are nine other sets of mailers available with the MAILER command, all of which are covered in Appendix E. Most of them are of very little interest for an average configuration. The two sets of mailers included in the tcpproto.mc configuration are the only ones that most administrators ever use.
To create a sample sendmail.cf from the
tcpproto.mc prototype file, copy the prototype
file to a work file. Edit the work file to change the OSTYPE line
from unknown
to the correct value
for your operating system, e.g., solaris8
or linux
. In the example we use sed
to change unknown
to linux
. We store the result in a file we
call linux.mc:
# sed 's/unknown/linux/' < tcpproto.mc > linux.mc
Then enter the m4
command:
# m4 ../m4/cf.m4 linux.mc > sendmail.cf
The sendmail.cf file output by the
m4
command is in the correct
format to be read by the sendmail program. With the exception of how
UUCP addresses are handled, the output file produced above is
similar to the sample generic-linux.cf
configuration file delivered with the sendmail distribution.
OSTYPE is not the only thing in the macro file that can be modified to create a custom configuration. There are a large number of configuration options, all of which are explained in Appendix E. As an example we modify a few options to create a custom configuration that converts user@host email addresses originating from our computer into firstname.lastname@domain. To do this, we create two new configuration files: a macro file with specific values for the domain that we name wrotethebook.com.m4, and a modified macro control file, linux.mc, that calls the new wrotethebook.com.m4 file.
We create the new macro file wrotethebook.com.m4 and place it in the cf/domain directory. The new file contains the following:
$ cat domain/wrotethebook.com.m4
MASQUERADE_AS(wrotethebook.com)
FEATURE(masquerade_envelope)
FEATURE(genericstable)
These lines say that we want to hide the real hostname and
display the name wrotethebook.com in its place
in outbound email addresses. Also, we want to do this on “envelope”
addresses as well as message header addresses. The first two lines
handle the conversion of the host part of the outbound email
address. The last line says that we will use the generic address conversion database, which converts login usernames to any value
we wish to convert the user part of the outbound address. We must
build the database by creating a text file with the data we want and
processing that file through the makemap
command that comes with
sendmail.
The format of the database can be very simple:
dan Dan.Scribner tyler Tyler.McCafferty pat Pat.Stover willy Bill.Wright craig Craig.Hunt
Each line in the file has two fields: the first field is the
key, which is the login name, and the second field is the user’s
real first and last names separated by a dot. Fields are separated
by spaces. Using this database, a query for dan
will return the value Dan.Scribner
. A small database such as
this one can be easily built by hand. On a system with a large
number of existing user accounts, you may want to automate this
process by extracting the user’s login name and first and last names
from the /etc/passwd file. The gcos
field of the
/etc/passwd file often contains the user’s real
name.[113]
Once the data is in a text file, convert it to a database with
the makemap
command. The makemap
command is included in the sendmail distribution. The
syntax of the makemap
command
is:
makemap
type name
makemap
reads the standard
input and writes the database out to a file it creates using the
value provided by name
as the filename.
The type
field identifies the database
type. The most commonly supported database types for sendmail are
dbm
, btree
, and hash
.[114] All of these types can be made with the makemap
command.
Assume that the data shown above has been put in a file named realnames. The following command converts that file to a database:
# makemap hash genericstable < realnames
makemap
reads the text file
and produces a database file called
genericstable . The database maps login names to real names, e.g.,
the key willy
returns the value
Bill.Wright
.
Now that we have created the database, we create a new
sendmail configuration file to use it. All of the m4
macros related to using the database
are in the wrotethebook.com.m4 file. We need to
include that file in the configuration. To do that, add a DOMAIN(wrotethebook.com)
line to the macro
control file (linux.mc) and then process the
linux.mc through m4
. The following grep
command shows what the macros in the
file look like after the change:
# grep '^[A-Z]' linux.mc VERSIONID(`$Id: ch10.xml,v 1.9 2004/09/22 19:24:26 marti Exp $') OSTYPE(`linux') DOMAIN(`wrotethebook.com') FEATURE(`nouucp', `reject') MAILER(`local') MAILER(`smtp') # m4 ../m4/cf.m4 linux.mc > sendmail.cf
Use a prototype mc file as the starting
point of your configuration if you install sendmail from the
tar
file. To use the latest
version of sendmail you must build a compatible
sendmail.cf file using the m4
macros. Don’t attempt to use an old
sendmail.cf file with a new version of
sendmail; you’ll just cause yourself grief. As you can see from the
sample above, m4
configuration
files are very short and can be constructed from only a few macros.
Use m4
to build a fresh
configuration every time you upgrade sendmail.
Conversely, you should not use a
sendmail.cf file created from the prototype
files found in the sendmail distribution with an old version of
sendmail. Features in these files require that you run a compatible
version of sendmail, which means it is necessary to recompile
sendmail to use the new configuration file.[115] This is not something every system administrator will
choose to do, because some systems don’t have the correct libraries;
others don’t even have a C compiler! If you choose not to recompile
sendmail, you can use the sample sendmail.cf
file provided with your system as a starting point. However, if you
have major changes planned for your configuration, it is probably
easier to recompile sendmail and build a new configuration with
m4
than it is to make major
changes directly to the sendmail.cf.
In the next part of this chapter, we use one of the sample
sendmail.cf files provided with
Linux. The specific file we start with is generic-linux.cf found in the cf/cf directory of the sendmail
distribution. All of the things we discuss in the remainder of the
chapter apply equally well to sendmail.cf files that are produced by
m4
. The structure of a
sendmail.cf file, the commands that it
contains, and the tools used to debug it are universal.
Most sendmail.cf files have more or less the same structure because most are
built from the standard m4
macros.
Therefore, the files provided with your system probably are similar to
the ones used in our examples. Some systems use a different structure,
but the functions of the sections described here will be found
somewhere in most sendmail.cf files.
The Linux file, generic-linux.cf, is our example of sendmail.cf file structure. The section labels from the sample file are used here to provide an overview of the sendmail.cf structure. These sections will be described in greater detail when we modify a sample configuration. The sections are:
Defines the information that is specific to the individual host. In the generic-linux.cf file, Local Information defines the hostname, the names of any mail relay hosts, and the mail domain. It also contains the name that sendmail uses to identify itself when it returns error messages, the message that sendmail displays during an SMTP login, and the version number of the sendmail.cf file. (Increase the version number each time you modify the configuration.) This section is usually customized during configuration.
Defines the sendmail options. This section usually requires no modifications.
Defines the various message precedence values used by sendmail. This section is not modified.
Defines the users who are trusted to override the sender address when they are sending mail. This section is not modified. Adding users to this list is a potential security problem.
Defines the format of the headers that sendmail inserts into mail. This section is not modified.
Defines the rules used to rewrite mail addresses. Rewriting Rules contains the general rules called by sendmail or other rewrite rules. This section is not modified during the initial sendmail configuration. Rewrite rules are usually modified only to correct a problem or to add a new service.
Defines the instructions used by sendmail to invoke the mail delivery programs. The specific rewrite rules associated with each individual mailer are also defined in this section. The mailer definitions are usually not modified. However, the rewrite rules associated with the mailers are sometimes modified to correct a problem or to add a new service.
The section labels in the sample file delivered with your system may be different from these. However, the structure of your sample file is probably similar to the structure discussed above in these ways:
The information that is customized for each host is probably at the beginning of the file.
Similar types of commands (option commands, header commands, etc.) are usually grouped together.
The bulk of the file consists of rewrite rules.
The last part of the file probably contains mailer definitions intermixed with the rewrite rules that are associated with the individual mailers.
Look at the comments in your sendmail.cf file. Sometimes these comments provide valuable insight into the file structure and the things that are necessary to configure a system.
It’s important to realize how little of sendmail.cf needs to be modified for a typical system. If you pick the right sample file to work from, you may need to modify only a few lines in the first section. From this perspective, sendmail configuration appears to be a trivial task. So why are system administrators intimidated by it? It is largely because of the difficult syntax of the sendmail.cf configuration language.
[112] The default location for the configuration file prior to sendmail 8.11 was the /etc directory. Now the default is /etc/mail, but the file is often placed in other directories, such as /usr/lib.
[113] See Appendix E for a sample script that builds the realnames database from /etc/passwd.
[114] On Solaris systems, NIS maps and NIS+ tables are built with standard commands that come with the operating system. The syntax for using those maps within sendmail is different (see Table 10-3).
[115] See Appendix E for information about compiling sendmail.