Getting Started with Sendmail - 1.8 Building a sendmail Configuration
( Page 11 of 13 )
sendmail configurations are written using m4 macros. The configuration must be processed by m4 to produce the sendmail.cf configuration file that is read by sendmail.Solution
Change to the configuration directory.
Create the m4 master configuration file. For this example, we name the master configuration file sendmail.mc.
Build the sendmail.cf file, copy it to the standard directory, and restart the sendmail daemon:
# ./Build sendmail.cf
rm -f sendmail.cf
/usr/bin/m4 ../m4/cf.m4 sendmail.mc > sendmail.cf || ( rm -f sendmail.cf && exit 1 )
chmod 444 sendmail.cf
# cp /etc/mail/sendmail.cf /etc/mail/sendmail.cf.bak
# cp sendmail.cf /etc/mail/sendmail.cf
# kill -HUP `head -1 /var/run/sendmail.pid`
Notice, in this example, that sendmail is restarted with a HUP signal. This assumes that sendmail is already running with some current configuration, which is a good assumption for the majority of recipes in this book. If, however, sendmail has just been installed, is not running, and has not been previously configured, use Build install-cf to properly install both the sendmail.cf file and the submit.cf file. See the “Building and installing sendmail.cf” section of the following discussion for an example of the Build install-cf command.Discussion
New sendmail configurations are generally built inside the cf/cf directory. Of course, cf/cf is a relative path, so where this directory is located can vary from system to system. For example, the Red Hat RPM places the configuration files in /usr/share/ sendmail-cf/cf.
If you’re using the sendmail distribution, the cf/cf directory is relative to where you installed the distribution. All of the examples in this book assume you’re using the sendmail 8.12.9 distribution and that you installed it in /usr/local/src. Given these assumptions, the following cd command would put you in the correct directory:
Next, create a master configuration file and make any necessary edits to that file. You can create a configuration file from scratch, start with a generic configuration provided by the sendmail developers, or start with a configuration provided by your vendor. Typing in your own configuration file from scratch is easy because sendmail master configuration files are very short. However, the sendmail developers provide a full set of generic and prototype files that are generally a good place to start.
The examples in this book are modifications to the generic-linux.mc configuration file that comes with the sendmail distribution. Therefore, we copy the generic-linux.mc file, which is the best match for our sample Linux system, to sendmail.mc, which we use as a working file. The generic-linux.mc file contains the following lines:
# Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
# All rights reserved.
# Copyright (c) 1983 Eric P. Allman. All rights reserved.
# Copyright (c) 1988, 1993
# The Regents of the University of California. All rights reserved.
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
# This is a generic configuration file for Linux.
# It has support for local and SMTP mail only. If you want to
# customize it, copy it to a name appropriate for your environment
# and do the modifications there.
VERSIONID(`$Id: ch01,v 1.22 2003/12/03 15:32:48 jhawks Exp chodacki $')
The divert(-1) command starts a section of comments that ends with a divert(0) command. Therefore, only the last five lines of the generic file are active lines—the rest of the file consists of comments.
The VERSIONID macro specifies version information that is formatted in any way you choose. If you use a version control system, you should probably format the information to be compatible with that system. In any case, you should change this information when you edit the file to indicate when the file was changed and by whom.
The OSTYPE macro loads the configuration required for the operating system. In this case, the file being loaded is /ostype/linux.m4 as you would expect with the generic Linux configuration. We will return to the linux.m4 file shortly to look at its contents.
The DOMAIN macro loads a configuration file designed specifically for your domain. The generic-linux.mc file is a sample file, and the domain/generic.m4 file that it loads with the DOMAIN macro is also a sample file. Although it is not specifically designed for your domain, the generic.m4 file is designed to be harmless. The contents of the domain/generic.m4 file are covered later.
If you do create a custom domain file, note that there is an interesting side effect when all of the configuration changes happen in the domain file and the master configuration file is unchanged. Rebuilding the sendmail.cf file with the Build script may generate the following error:
# ./Build sendmail.cf
make: `sendmail.cf' is up to date.
Build does not check for changes in the domain file. It sees that sendmail.mc is unchanged since the last build and it refuses to create a new sendmail.cf file. Bypass this problem by removing the old sendmail.cf file, by running touch sendmail.mc before running Build, or by using m4 instead of Build to rebuild the sendmail.cf file.
The last two macros in the generic-linux.mc file are MAILER macros. The first MAILER macro loads mailer/local.m4, which defines the following mailers:
The local mailer delivers mail to user accounts located on this system.
The prog mailer is used by sendmail to route mail to other processes running on the local system.
Both the local and prog mailers are used in most sendmail configurations.
The second MAILER macro loads mailer/smtp.m4, which defines these mailers:
The Extended SMTP (ESMTP) mailer handles the standard TCP/IP mail protocol, including complex message bodies and MIME content types. This is the default mailer used by sendmail for SMTP mail.
The relay mailer is used to relay SMTP mail through another mail host. Relaying and mail relay hosts are used in Chapter 3.
The smtp mailer handles only old-fashioned, 7-bit ASCII SMTP mail. sendmail only uses this mailer when specially configured to do so; for example, if directed to do so by an entry in the mailertable database. The mailertable is used in recipes in Chapter 5.
The smtp8 mailer is designed to work with remote systems that can handle 8-bit mail but do not understand the standard ESMTP protocol. sendmail only uses this mailer when specially configured to do so; for example, if it is directed to do so by an entry in the mailertable database.
The dsmtp mailer allows the destination host to retrieve mail queued on the mail server. Normally, mail is “pushed” from the source to the destination; the source initiates the connection. This mailer allows the destination host to “pull” mail from the source when it is ready to receive mail by using the optional ETRN SMTP command. sendmail only uses this mailer when specially configured to do so.
The two MAILER macros add the essential mailers to the configuration. The DOMAIN macro, which loads the domain/generic.m4 file, and the OSTYPE macro, which loads the ostype/linux.m4 file, also add settings to the configuration. Examine the generic.m4 and linux.m4 files to see exactly what those settings are.The linux.m4 ﬁle
Every master configuration file contains an OSTYPE macro.*To fully understand a configuration, you must know exactly what parameters are set by this file. This book uses Linux as a sample operating system and linux.m4 as a sample ostype file. You, however, should examine the ostype file specific to your operating systems before using the recipes that follow in later chapters.
After an opening block of comments, the linux.m4 file contains the following active lines:
VERSIONID(`$Id: ch01,v 1.22 2003/12/03 15:32:48 jhawks Exp chodacki $')
We have already discussed VERSIONID, so there is no need to go over it again.
The define command defines the path to the directory where certain executables, particularly the sendmail Restricted Shell (smrsh), are stored. The default for confEBINDIR is /usr/libexec. This define sets it to /usr/sbin, which is correct for Linux systems.
Notice that different single quote marks are used to open and close a quoted string in an m4 command. The open quote mark is`and the close quote mark is'. These quote marks are only required when the string contains a blank, a special character, or a keyword. However, the quote marks are frequently used, and when they are used, the quotes must appear exactly as shown.
The ifdef command is a built-in m4 command. It contains three comma-separated fields:
- First, the name of the variable being tested, which is PROCMAIL_MAILER_PATH in this example.
- Second, the action taken if the variable has been set. In this case, no action is taken because the second field is empty, as indicated by the two commas in a row.
- Third, the action taken if the variable has not been set. In the linux.m4 file, the define command that sets PROCMAIL_MAILER_PATH to /usr/bin/procmail is executed only if the variable has not been set previously. PROCMAIL_MAILER_PATH is not set anywhere else in this configuration, so this define executes and sets the variable.
The last line in the linux.m4 file is a FEATURE macro that adds the local_procmail feature to the configuration. The local_procmail feature causes sendmail to use procmail as the local mailer. procmail is a program with very powerful mail filtering features. procmail is used in Chapter 6.The generic.m4 ﬁle
After the OSTYPE macro adds the linux.m4 file to the configuration, the DOMAIN macro adds the domain/generic.m4 file. It contains the following active lines:
VERSIONID(`$Id: ch01,v 1.22 2003/12/03 15:32:48 jhawks Exp chodacki $')
We know what the VERSIONID macro does, so there is no need to cover it again.
The first define command sets a value for the confFORWARD_PATH variable, which tells sendmail where to search for .forward files. The confFORWARD_PATH variable is discussed in more detail in the Introduction to Chapter 2 and in Recipe 10.8.
The second define command sets the value of the confMAX_HEADERS_LENGTH variable. In turn, this m4 variable sets the value for the sendmail.cf MaxHeadersLength option.
This value is the maximum number of header bytes sendmail will allow for a message. The define sets this value to 32,768, which is the default used when no value is defined.
The first FEATURE macro enables the redirect feature. This is a useful feature that can be used to return a message to the sender telling him the correct address of a recipient whose address has changed. The redirect feature is used in Recipe 2.8, where it is explained in detail.
The second FEATURE macro enables the use_cw_file feature. This feature causes sendmail to load class $=w from the file local-host-names. When and how to use this feature are covered in Recipe 2.1
Finally, the EXPOSED_USER macro is used to add the username root to class $=E. Values in class $=E are exempted from masquerading when masquerading is used to hide hostnames or usernames. The EXPOSED_USER macro is used repeatedly in Chapter 4.
The generic-linux.mc file, the linux.m4 file, and the generic.m4 domain file are combined to create a configuration that:
- Sets the confBINDIR directory path to /usr/sbin
- Sets the path of procmail to /usr/bin/procmail
- Uses procmail as the local mailer
- Defines a search path for .forward files
- Sets the maximum length of the headers on a message to 32,768 bytes
- Enables the redirect feature
- Loads class $=w from the local-host-names file
- Exempts the root user from masquerading
- Defines the complete set of local and SMTP mailers
Because the generic-linux.mc file incorporates both the linux.m4 file and the generic.m4 file, all of the configuration settings just listed have been made part of the sendmail.mc file simply by copying the generic-linux.m4 file. It is this sendmail. mc file that is the basic configuration modified in subsequent recipes to create custom configurations.Building and installing sendmail.cf
Run Build to create the sendmail.cf file from the sendmail.mc file. The Build script is easy to use. Provide the name of the output file you want to create as an argument on the Build command line. The script replaces the .cf extension of the output file with the extension .mc and uses the macro configuration file with that name to create the output file. Thus, putting sendmail.cf on the Build command line means that sendmail.mc is used to create sendmail.cf.
Despite the simplicity of Build, many administrators never use it to build a sendmail configuration because the m4 command line used to build a sendmail configuration is also very simple:$ m4 ../m4/cf.m4 sendmail.mc > sendmail.cf
For the average sendmail administrator, the Build script doesn’t offer any critical advantages. For most of us, deciding to use Build or m4 is primarily a matter of personal preference. It is even possible to invoke the Makefile directly with a basic make command. In this book, we use both Build and m4 to build the sendmail configuration file. Use whichever method you prefer.
The Build script makes it simple for the people who maintain the sendmail distribution to build a .cf file for each .mc file in the cf/cf directory with a single Build all command. If you need to build multiple configurations, it is possible to edit the Makefile, changing the $OTHER variable so that it contains the names of all of the configurations you wish to build, and to then use Build other to create all of those configurations at one time. However, most administrators do not have enough different configurations to bother with this.
After building the new sendmail.cf file, copy that file to the location where sendmail expects to find its configuration file. On our sample Red Hat system, that location is /etc/mail/sendmail.cf. In most cases, this is simply done with a cp command. However, it can also be done with Build, as follows:
# cd cf/cf
# ./Build install-cf
../../devtools/bin/install.sh -c -o root -g bin -m 0444 sendmail.cf /etc/mail/
../../devtools/bin/install.sh -c -o root -g bin -m 0444 submit.cf /etc/mail/submit.cf
The Build install-cf command used above installs two configuration files: the sendmail.cf file that is the primary focus of this book and a second file named submit.cf. This file doesn’t exist unless you create it, but a full submit.cf is delivered with the sendmail distribution. The submit.cf file is a special configuration used when sendmail is invoked by a user from the command line to submit a piece of mail. sendmail.cf is the configuration file used by the sendmail daemon. The Build install-cf command is generally used when a new sendmail distribution is first installed to ensure that both the sendmail.cf and submit.cf files are installed. Other than the initial installation, however, there is generally no need to copy both files at the same time because it is not usually necessary to create a new submit.cf file when you create a new sendmail.cf file.
Once the configuration is installed, start sendmail to force it to read the new configuration. In this recipe’s Solution section, sendmail is restarted by sending it the HUP signal with a kill command. This method of restarting sendmail uses standard sendmail signal processing that is available on any system, which makes the kill command technique vendor neutral. Many readers will be familiar with embedding a cat command inside a kill command to retrieve the process ID stored in a PID file. An interesting aspect of the kill command used to restart sendmail is the manner in which the sendmail process ID is retrieved from the sendmail.pid file. Here is the example again:# kill -HUP `head -1 /var/run/sendmail.pid`
Using cat instead of head in this command would not work because sendmail writes a multiline PID file. A cat of /var/run/sendmail.pid on our sample system shows this:
# cat /var/run/sendmail.pid
/usr/sbin/sendmail -bd -q15m
The content of this file is of more than just passing interest to someone planning to restart sendmail with a HUP signal. The first line is the process ID you expect to find in a PID file. The second line of this file is the command that was used to start sendmail. The command must contain the full pathname of the sendmail program in order for the HUP signal to successfully restart sendmail. If the second line of this file shows a partial (or relative) pathname, HUP terminates the currently running sendmail, but it does not start a new copy of sendmail. In effect, sending a HUP signal to sendmail, when the current version of sendmail was not executed using its full pathname, kills sendmail, which, of course, is not what you intended. To be safe, always start sendmail using the full pathname.
Of course, the HUP signal is only used to restart sendmail, which implies that sendmail is already running. The first time sendmail is installed on a system, it is started from the command line using a sendmail command. Here is an example:# /usr/sbin/sendmail -bd -q15m
# /usr/sbin/sendmail –L sm-msp –Ac –q15m
The -bd option used on the first command line causes sendmail to run as a daemon and listen for incoming mail on ports 25 and 587. This first command creates the sendmail daemon that reads the sendmail.cf configuration file and runs in the traditional role of a mail transfer agent (MTA). The second command starts sendmail as a mail submission program. The -Ac option on this command line directs sendmail to read the submit.cf configuration file. The -L option tells this copy of sendmail to use the name sm-msp when it logs messages. Without the--L option, both copies of sendmail would log messages using the name sendmail making it difficult to determine which copy of sendmail logged the message. The -q15m option on both command lines direct each copy of sendmail to process its mail queue every 15 minutes. See Chapter 9 for more information on mail queues.
Some systems provide their own tools for starting daemons. For example, a Red Hat system using an RPM version of sendmail can start sendmail with the service command:
# service sendmail start
Starting sendmail: [ OK]
Regardless of how sendmail is started or restarted, when the daemon starts, it reads in the configuration file /etc/mail/sendmail.cf, which now contains the new configuration.
This recipe is the basic configuration recipe upon which most of the recipes in this book are built. Subsequent chapters describe solutions to specific problems. These solutions are often shown in the context of this basic recipe. You will need to take those solutions and place them in the basic configuration that you build for your server. We use a basic foundation recipe for subsequent solutions for two reasons:
- First, covering the basic configuration here eliminates the need to repeat this long description over and over again for every recipe, which, in turn, allows us to focus on the unique aspects of those recipes. We explain the basic recipe once and then assume you understand the basic configuration statements as we move forward. Recipes naturally have lots of repetition; this reduces some of it.
- Second, the basic recipe provides a consistent reference point for subsequent recipes. By creating a baseline configuration that you can use as a starting point for most recipes in this book, we ensure that you can duplicate our test results on your system.
The sendmail book covers the VERSIONID macro in section 18.104.22.168, the OSTYPE macro in section 22.214.171.124, the DOMAIN macro in 126.96.36.199, and the MAILER macro in section 188.8.131.52. All of the m4 macros and configuration commands are covered in the cf/README file delivered with the sendmail distribution.