This document describes how to build recent versions of sendmail. The current version is 8.8.5 at the time of writing, which is newer than the one that comes with MkLinux DR2.
This document also discusses how to create /etc/sendmail.cf, the configuration file that controls how sendmail behaves.
Although written for use with MkLinux, much of the document applies to other UNIX-like systems as well. Most of the differences for other systems tend to be in the pathnames specifying where sendmail and its related files are installed.
Commands that are shown with a "%" prompt may be executed as an ordinary user. Commands that are shown with a "#" prompt should be executed as root.
This document provides a cookbook procedure you can follow that should help you get sendmail working properly. However, it's a good idea to get some general background on how sendmail works if you don't know much about it. Information about sendmail is available in files within the source distribution and from external sources.
Within the distribution, it's worth taking a look at the following files:
For information outside the distribution, try the following:
Currently, sendmail is at version 8.8.5. Information on obtaining the distribution is available at the sendmail Web site. After you get the distribution, unpack it and change directory into its src directory:
% zcat sendmail.8.8.5.tar.gz | tar xf -
% cd sendmail-8.8.5/src
The usual build process involves running the makesendmail script, which creates a subdirectory, populates it with a Makefile and links to the source files, then compiles the object files there. As of version 8.8.3, MkLinux support is included in the sendmail distribution. If you have an earlier release, you can download a Makefile and put it in the src/Makefiles directory. [download Makefile.Linux.ppc]
Then run makesendmail in the src subdirectory:
% sh makesendmail
makesendmail creates a directory for compiling the distribution (obj.Linux.1.2.13.ppc for the current MkLinux distribution, or obj.Linux.2.0.21-osfmach3.ppc for the beta 2.0 MkLinux server), and builds an executable sendmail there.
If the build dies with error messages about not being able to find symbols that look like __res_xxx, you may need to link in the resolver library explicitly. Change into the obj.Linux.1.2.13.ppc directory, edit the Makefile to add -lresolv to the LIBS value, and run make again.
After the build completes, you can install sendmail by running this command:
# sh makesendmail install
This should install sendmail in the /usr/sbin directory. The permissions should look like this:
% ls -l /usr/sbin/sendmail
-r-sr-sr-x 1 root mail 698220 Oct 24 18:36 /usr/sbin/sendmail
MkLinux as distributed has inetd listen on the SMTP port and runs rsmtp when an incoming mail connection is seen. To use sendmail, you must disable rsmtp and arrange for sendmail to start up at system boot time. If you don't do this, you won't be able to use sendmail for incoming connections. [Instructions]
Occasionally you may need to kill sendmail if it's running and restart it manually. You do this, for instance, if you change any of the files that sendmail uses, to cause it to reread those files.
To kill sendmail, do this:
# ps -ax | grep sendmail
308 ? S 0:00 sendmail: accepting connections on port 25
# kill 308
To start sendmail manually, run a command such as this:
# /usr/sbin/sendmail -bd -q30m
The -bd option tells sendmail to run in server (daemon) mode and -q30m tells it to examine the queue directory for unprocessed mail every 30 minutes. You can vary the -q option to suit your preferences. For instance, -q1h causes a queue check every 60 minutes (1 hour).
sendmail reads the configuration file /etc/sendmail.cf when it starts up, and /etc/sendmail.cf in turn references other files such as /etc/sendmail.cw. To reconfigure how sendmail processes mail, you modify one or more of these files.
As you troubleshoot sendmail operation, look in /var/log/maillog, since that's where sendmail writes error messages.
If you can't even send mail to yourself and get "local configuration" errors or "mail loops back to itself" errors, it may be simply that your system doesn't know its own name. The proper fix for this is to get name service working, but until you do that, you may be able to get mail working by editing /etc/sendmail.cw so that sendmail knows what machine it's running on. /etc/sendmail.cw contains the host names that should be considered "local". In other words, this is the set of host values for which addresses of the form user@host should be delivered to user on the local machine. Suppose my MkLinux machine is named boa.snake.net. Then I can edit /etc/sendmail.cw to look like this:
localhost
boa
boa.snake.net
Normally, sendmail should understand all these names to mean the local host, and thus it may not actually be necessary to have each of these lines in /etc/sendmail.cw. However, I've run into problems without them in cases where a name server isn't running, and it doesn't hurt anything to have them there.
After editing /etc/sendmail.cw, kill and restart sendmail to see if mail delivery works better.
You may also want to modify /etc/sendmail.cf. It's a good idea to save the original before you change it, in case you decide that the original suits your needs after all or you just want to compare it with new configuration files that you generate. To save the original, run this command:
# cp /etc/sendmail.cf /etc/sendmail.cf.orig
To modify /etc/sendmail.cf, you can either edit it directly by hand, or generate a new one by writing an m4 description file and running m4. (m4 is a macro processor that reads your description file and some other presupplied files and generates the configuration file.) Which avenue should you pursue?
Writing an m4 description file is easier, and I'll describe the process shortly below. One look at /etc/sendmail.cf should quickly convince you that you don't want to mess with it by hand. However, if you're willing to try, you can learn a lot about how /etc/sendmail.cf works by tweaking (a copy of) it and running sendmail in test mode:
# cp /etc/sendmail.cf /etc/sendmail.cf.test
# vi /etc/sendmail.cf.test
# /usr/sbin/sendmail -bt -C /etc/sendmail.cf.test
If you do decide to try modifying the configuration file manually, you'll need additional information. Consult section 5 of the Installation/Operation guide in the sendmail distribution, the bat book, or the "Explosion in a Punctuation Factory" article. These will help you understand the configuration file's contents and how to run sendmail in test mode (using the -bt option).
Writing a Description File -- General Procedure
This section discusses how to write an m4 description file and generate a sendmail configuration file from it. You should use this information in conjunction with the cf/README file, which is a reference describing how sendmail's m4 files work.
The general procedure for creating a new /etc/sendmail.cf from an m4 description file goes something like this:
If your description file is named config.mc, the command to generate a configuration file config.cf is:
% m4 ../m4/cf.m4 config.mc > config.cf
To send a test message, first create a short file containing the message (so you don't have to type it in repeatedly):
To: yourself
From: yourself
Subject: test
<-- leave a blank line
This is a test.
Then send the message like this:
# /usr/sbin/sendmail -t -C config.cf < msg
To run sendmail in test mode with the new configuration file, use this command:
% /usr/sbin/sendmail -bt -C config.cf
If the configuration file seems to do what you want, install it like this:
# cp config.cf /etc/sendmail.cf
# chmod 444 /etc/sendmail.cf
Then kill and restart sendmail to cause it to reread the newly-installed file.
Writing a Description File -- First Try
This section describes how to construct a generic sendmail configuration file for use with MkLinux. ("Generic" in the sense that I believe it's probably similar to whatever description file was used to construct the /etc/sendmail.cf file that comes with the MkLinux distribution.)
To write an m4 description file, change into the cf/cf directory. Then create a file called mklinux1.mc that looks like what you see below:
OSTYPE(mklinux)
FEATURE(redirect)
FEATURE(use_cw_file)
MAILER(local)
MAILER(smtp)
Alternatively, download mklinux1.mc and install it in the cf/cf directory.
The OSTYPE(mklinux) line specifies the type of system for which you want to construct a configuration file. When m4 sees the system type of xxx, it looks for a file xxx.m4 in the cf/ostype directory. Thus, for a system type of mklinux, m4 looks for a file mklinux.m4. The mklinux.m4 file specifies where some of the files and directories are that sendmail uses under MkLinux, and tells it to use procmail for local delivery. As of version 8.8.3, the sendmail distribution includes a mklinux.m4 file. If you have an earlier release, you can create the file yourself. It should look like this:
ifdef(`STATUS_FILE',,
`define(`STATUS_FILE', /var/log/sendmail.st)')
ifdef(`PROCMAIL_MAILER_PATH',,
define(`PROCMAIL_MAILER_PATH', `/usr/bin/procmail'))
FEATURE(local_procmail)
Alternatively, download mklinux.m4 and install it in the cf/ostype directory.
The other lines in the description file mklinux1.mc have the following meanings:
FEATURE(redirect)
This line is used to handle mail that comes in for users who no longer have an account on the local machine but do have a forwarding address. To use this feature, you need to create an alias for each such user. (Run man aliases for information about mail aliases.) For example, if elijah no longer has a local account, but has a new address elijah@new.host at which he can be reached, add a line to /etc/aliases that looks like this:
elijah: elijah@new.host.REDIRECT
Then rebuild the aliases database using either of the following commands (they are equivalent):
# newaliases
# /usr/sbin/sendmail -bi
Now when mail comes in for elijah, sendmail will reject it but send back a "551 User has moved; please try <elijah@new.host>" message to the connecting mailer.
FEATURE(use_cw_file)
This line tells sendmail to consult the file /etc/sendmail.cw to find out what host names should be considered "local". For boa, I can use this /etc/sendmail.cw file:
localhost
boa
boa.snake.net
MAILER(local)
MAILER(smtp)
These lines are required; they generate definitions for the local and network mailers.
After you create mklinux1.mc and (if necessary) mklinux.m4, generate a configuration file by running this command in the cf/cf directory:
% m4 ../m4/cf.m4 mklinux1.mc > mklinux1.cf
You can test the mklinux1.cf file by sending test mail, or by running sendmail in test mode:
# /usr/sbin/sendmail -t -C mklinux1.cf < msg
% /usr/sbin/sendmail -bt -C mklinux1.cf
To install the configuration file, run the following commands:
# cp mklinux1.cf /etc/sendmail.cf
# chmod 444 /etc/sendmail.cf
Then kill and restart sendmail.
Writing a Description File -- Second Try
You may find mklinux1.cf insufficient for your purposes. If so, you write a different description file. In this section, I show the one I use, as an example of how to tweak the description file when a stock version doesn't quite do the job.
I wanted to make two primary modifications to mail handling:
To accomplish these objectives on boa.snake.net, I use the description file shown below, which I'll call mklinux2.mc:
OSTYPE(mklinux)
FEATURE(redirect)
FEATURE(use_cw_file)
FEATURE(nouucp)
FEATURE(always_add_domain)
MASQUERADE_AS(snake.net)
FEATURE(allmasquerade)
FEATURE(masquerade_envelope)
MAILER(local)
MAILER(smtp)
I'll describe only those lines that differ from the generic description file.
FEATURE(nouucp)
This line turns off UUCP support.
FEATURE(always_add_domain)
This line tells sendmail to add a host and domain name even to local addresses. By itself, this line causes mail to user to show up as user@host.snake.net. Combined with masquerading, the host name part is hidden, leaving just user@snake.net.
MASQUERADE_AS(snake.net)
FEATURE(allmasquerade)
FEATURE(masquerade_envelope)
EXPOSED_USER(root)
These lines act together to help produce a more uniform mail addressing structure for hosts in the snake.net domain.
The MASQUERADE_AS(snake.net) line causes sender (From:) addresses to be written as user@snake.net rather than as user@host.snake.net. (You may notice that mail from root is not subject to this.)
The FEATURE(allmasquerade) line does the same for recipient (To:) addresses. (Note that this can be dangerous unless you follow the aliasing instructions below.)
The FEATURE(masquerade_envelope) line does the same for addresses in the message envelope. (In effect, this masquerades the From line for messages in UNIX mbox format.)
To generate mklinux2.cf from mklinux2.mc, run this command in the cf/cf directory:
% m4 ../m4/cf.m4 mklinux2.mc > mklinux2.cf
You can test the mklinux2.cf file by sending test mail, or by running sendmail in test mode:
# /usr/sbin/sendmail -t -C mklinux2.cf < msg
% /usr/sbin/sendmail -bt -C mklinux2.cf
To install the file, run the following commands:
# cp mklinux2.cf /etc/sendmail.cf
# chmod 444 /etc/sendmail.cf
Then kill and restart sendmail.
To make the kind of masquerading done by mklinux2.cf work properly, some additional setup is needed:
First, an MX record for snake.net must be advertised as part of the DNS information for the snake.net domain. If boa is advertised as the mail exchanger, then when a host wants to deliver a message to user@snake.net, it discovers that boa.snake.net accepts such mail and sends the message to boa.
Second, since boa is supposed to know that it should try to handle mail for user@snake.net, the name snake.net should be added to /etc/sendmail.cw. Otherwise you'll get "mail loops back to itself" errors. With the change, /etc/sendmail.cw looks like this:
localhost
boa
boa.snake.net
snake.net
Third, hosts within the snake.net domain must be able to figure out which particular host a given user lives on. In other words, they must each have a consistent notion of the user namespace. (If this is not true, then the configuration machinery generated by the allmasquerade line in the description file may end up causing mail delivery failures or loops.) Reliable within-domain delivery can be accomplished in different ways. Two possibilities are:
define(`LOCAL_RELAY', boa.snake.net)
This tells sendmail on those hosts to relay to boa
all mail for addresses that look local but for which the user
part does not correspond to a known user.
This way only boa must know where each user lives.
There are trade-offs to these approaches. It can be hard to keep alias files up to date on multiple machines. But each host then is able to relay mail to any user in one hop. Relaying is simpler to set up on the non-relay hosts. But messages may take two hops to reach the recipient (first to the relay host, then to the user's host), so you may generate more network traffic.
What happens if you deliberately send mail to a snake.net host other than the one on which a particular user lives? For example, suppose ian lives on cobra but I send a message to ian@pit-viper.snake.net? In this case, pit-viper accepts the mail and then attempts to deliver it. The way this is done depends on the method for routing within-domain mail:
Here are the files referenced at various points in this document that you can download:
Makefile.Linux.ppc and mklinux.m4 are included in the sendmail distribution as of release 8.8.3; you don't need to download them if you have that distribution or newer.
24 June 1997
19 November 1996
2 November 1996