Sendmail is a Mail Transport Agent (MTA). It routes, modifies, and delivers mail message across heterogeneous mail systems. With a history somewhat parallel to that of mailing list software, Sendmail has a "permanent beta" version called Sendmail X that is intended as an upgrade/replacement for the stable Sendmail 8.x series; however, much as Mailman has largely supplanted Majordomo, several MTAs have partially eclipsed Sendmail. The chief such new MTA is Postfix, but Qmail and Exim are also widely used. Nonetheless, Sendmail still remains, at least by a narrow margin, the most widely used MTA on Linux systems. As of September 16, 2005, the latest stable release of Sendmail was 8.13.5.
Not just one book, but many books, have been written on Sendmail. See Resources for a list of available books. The most comprehensive of these is Sendmail, Third Edition (O'Reilly, 2002) by Bryan Costales with Eric Allman. At 1,232 pages, this book covers quite a lot more than this tutorial can touch on.
While Sendmail in principle supports a number of mail transport protocols such as UUCP, by far the most widely used is Simple Mail Transport Protocol (SMTP), which here includes Extended SMTP (ESMTP) for enhanced MIME encoded message bodies. At heart, mail that is not forwarded to other SMTP hosts is delivered to the local system by putting messages in local files. Local Mail User Agents (MUAs) read messages that Sendmail (or another MTA) puts in local files (and often also fetch mail using POP3 or IMAP), but generally call on Sendmail to deliver outgoing messages. Some MUAs, however, directly communicate with SMTP servers (such as Sendmail instances, local or remote) rather than placing messages in the Sendmail queue for later processing. Usually the Sendmail queue is in /var/spool/mqueue/.
The first thing to do is obtain a copy of the current Sendmail software from sendmail.org (see Resources for a link), for example, sendmail.8.13.5.tar.gz. Unpack it as usual. Unlike many applications that use the
make; make install pattern, building Sendmail is performed with
sh Build. After the initial build,
cd to the cf/cf/ subdirectory; copy a suitable *.mc file as sendmail.mc; customize sendmail.mc; and run the following to generate a sendmail.cf file:
$ m4 ../m4/cf.m4 sendmail.mc > sendmail.cf
You may also use the shortcut
sh Build sendmail.cf. This may seem mysterious, but both these commands generate an actual Sendmail configuration from a more readable format using the M4 macro processor. Actual sendmail.cf files, though editable ASCII, are quite cryptic and should only be modified minimally by hand.
Finally, copy the sendmail binary from a location that will be something like obj.Linux.2.6.10-5-386.i686/sendmail/sendmail to its final location (back up an old one if it exists), typically /usr/sbin/, and copy your sendmail.cf file to /etc/mail/sendmail.cf. You can also do the latter in the cf/cf/ subdirectory with
sh Build install-cf. You will probably need to
sudo to obtain file permissions for the relevant directories.
A number of utilities come with Sendmail: makemap, mailstats, etc. Each corresponding directory has a README and can be installed by running
sh Build install from the subdirectory.
The main complexity, and the main function, of Sendmail is in its sendmail.cf file. This configuration file contains some settings for the Sendmail environment, but principally it contains patterns for addresses to rewrite and/or deliver by certain mechanisms.
Two rewrite mechanism that may be configured are the
virtusertable, which let you map local users to and from external addresses. For either mapping, you first create an aliases file as plain text. For example:
Listing 2. Outbound mappings
david email@example.com root firstname.lastname@example.org email@example.com firstname.lastname@example.org
Or, for incoming mail mapped to local accounts:
Listing 3. Inbound mappings
email@example.com david firstname.lastname@example.org david email@example.com david @mail.gnosis.cx %firstname.lastname@example.org email@example.com owner%3 firstname.lastname@example.org error:5.7.0:550 Address invalid
To compile these aliases, use the
$ makemap dbm /etc/mail/virtusertable < inbound
$ makemap hash /etc/mail/genericstable < outbound
Enabling use of these maps can be configured using M4 macros in sendmail.cf (or in whatever configuration file you use).
Listing 4. Enabling mappings in sendmail.cf
DOMAIN(gnosis.cx)dnl FEATURE(`virtusertable', `dbm /etc/mail/virtusertable')dnl FEATURE(`genericstable', `hash /etc/mail/genericstable')dnl GENERICS_DOMAIN_FILE(`/etc/mail/generics-domains')dnl
A number of things are going on here. The
DOMAIN macro indicates that a file like cf/domain/gnosis.cx.m4 is used for additional macros. The
FEATURE macros enable use of the
GENERICS_DOMAIN_FILE macro defines the domains that qualify for remapping for names in
Rewriting will follow all the rules indicated. In test mode (
sendmail -bt), you can examine the rewriting that is performed for specific addresses. For example, using
genericstable, mail to the local user "david" will be delivered to email@example.com externally. Assuming
localhost is defined in /etc/mail/generics-domains, mail to david@localhost will go to the same place.
In the other direction, mail coming in for firstname.lastname@example.org will be rewritten and delivered to local user "david." Multiple domains can be manipulated by Sendmail at the same time, so email@example.com will also be delivered locally.
The full power comes in some of the wildcard symbols. Any mail sent to mail.gnosis.cx that is not specifically directed to a local user will be forwarded to the same username at external-host.com. But that's a simple pattern. More interestingly, the
%3 can be used to expand multiple extra name information, so firstname.lastname@example.org and email@example.com will be delivered to local users "owner-foo" and "owner-bar," respectively (unless they undergo further rewriting). These local users might be mailing list processing systems or other automated message handlers. As a special case, you can raise an error for a given address rather than rewrite it further.
What we have looked at so far really just scratches the surface of the rewriting rules you can add to Sendmail, but they give you an initial feel. Buy one of the large books on the topic to learn more details.
Sendmail can run in a number of modes. The most common mode is as a daemon that stays in the background and periodically process its queue. For example, running:
$ /usr/sbin/sendmail -bd -q10m
tells Sendmail to run as a daemon and check its queue every ten minutes. You can also run Sendmail a single time to process the queue at once, but not daemonize:
$ /usr/sbin/sendmail -q
As mentioned above, Sendmail has a test mode to examine address rewriting rules. For example (taken from the Linux Network Administrators Guide; see Resources for a link):
Listing 5. Sendmail test mode
$ /usr/sbin/sendmail -bt ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> > 3,0 firstname.lastname@example.org rewrite: ruleset 3 input: isaac @ vstout . vbrew . com rewrite: ruleset 96 input: isaac < @ vstout . vbrew . com > rewrite: ruleset 96 returns: isaac < @ vstout . vbrew . com . > rewrite: ruleset 3 returns: isaac < @ vstout . vbrew . com . > rewrite: ruleset 0 input: isaac < @ vstout . vbrew . com . > rewrite: ruleset 199 input: isaac < @ vstout . vbrew . com . > rewrite: ruleset 199 returns: isaac < @ vstout . vbrew . com . > rewrite: ruleset 98 input: isaac < @ vstout . vbrew . com . > rewrite: ruleset 98 returns: isaac < @ vstout . vbrew . com . > rewrite: ruleset 198 input: isaac < @ vstout . vbrew . com . > rewrite: ruleset 198 returns: $# local $: isaac rewrite: ruleset 0 returns: $# local $: isaac