Chapter 10. Securing sendmail

Introduction

Security is essential. Security is so important that it is touched upon many times in this book. In fact, several earlier chapters are really about security, such as Chapter 7 and Chapter 8. But even the chapters on relaying and spam control are really chapters about security because theft of service is just as big of a security problem for sendmail as system and data integrity.

A sendmail server requires all of the security precautions used on any networked system, and then some. By its very nature, a sendmail server must accept connections and data from unknown remote hosts, while many other network servers offer their services to a limited set of clients. The system running sendmail must be secured against attack, and the sendmail service must be secured against exploitation. General system security is beyond the scope of this book. For that, use a good security reference, such as Practical UNIX and Internet Security, by Simson Garfinkel and Gene Spafford (O’Reilly), or Computer Security Basics, by Debbie Russell and G.T. Gangemi (O’Reilly). This book focuses on only those things that are specific to sendmail security.

sendmail’s file and directory permissions are one area of general system security that is specific to sendmail. All of the directories used for sendmail’s administrative files should only be writable by the TrustedUser (usually root), and all of the parents of those directories back to the root should only be writable by root—none of those directories should have group or world write permissions. The file permissions used by sendmail are defined by confTEMP_FILE_MODE and confQUEUE_FILE_MODE. Don’t change these permissions. sendmail comes with these permission set as tight as possible.

Despite a spotty security reputation, out-of-the-box sendmail uses tight security settings. Take care not to compromise security when configuring sendmail. Some configuration changes reduce security, as explained in Introduction to Chapter 3. For example, the confDONT_BLAME_SENDMAIL define accepts more than 40 arguments that relax sendmail’s normally strict security.

On occasion, a sendmail administrator is forced to relax security in order to gain flexibility. Many of the recipes in this chapter take the opposite tack—increasing security even at the cost of flexibility. You won’t see any DontBlameSendmail options used. You will see restrictions of the files sendmail can write and the SMTP commands the server will support—all done to increase security.

Don’t undertake these security recipes lightly. Increasing security at the cost of utility and flexibility should be done only after careful study. Be sure that the cure is not worse than the disease. All sites can benefit from keeping sendmail software updated as described in Recipe 10.3 and Recipe 10.4. Most sites can benefit from limiting the number of systems that accept inbound mail from the network, as described in Recipe 10.1 and Recipe 10.2. Many may benefit from using smrsh, as covered in Recipe 10.6. But some of the recipes in this chapter provide more security than the average site needs, particularly when you consider that the enhanced security comes at the cost of utility. These recipes are not suggesting that you should do such things as disable delivery to files or disable the VRFY command; they are telling you how to do these things if you decide that it is necessary for your system. For most sites, sendmail’s standard security is more than adequate.

10.1. Limiting the Number of sendmail Servers

Problem

Because every network service that accepts inbound connections is a potential target of security attacks, you want to limit the number of systems running a sendmail listener to reduce security vulnerability and maintenance.

Solution

Select a limited number of hosts to act as mail exchangers and mail relay hosts for your enterprise. Configure the selected systems as described in Chapter 2 and in Chapter 3. The other sendmail systems should be configured as described here.

Make a backup copy of the submit.mc file:

# cd /usr/local/src/sendmail-8.12.9/cf/cf
# cp submit.mc submit.mc.original

Edit the submit.mc file. Add the MASQUERADE_AS macro to the configuration so that replies to mail sent by the local host will go to a server that has an active SMTP port, and add the name of the mail relay host to the msp FEATURE command. Here are the active lines in the submit.mc file from the sendmail 8.12.9 distribution after the changes have been made:

VERSIONID(`submit.mc modified for recipe 10.1')
define(`confCF_VERSION', `Submit')
define(`__OSTYPE_  _',`')dnl dirty hack to keep proto.m4 from complaining
define(`_USE_DECNET_SYNTAX_', `1')dnl support DECnet
define(`confTIME_ZONE', `USE_TZ')
define(`confDONT_INIT_GROUPS', `True')dnl
MASQUERADE_AS(`chef.wrotethebook.com')
FEATURE(`msp', `chef.wrotethebook.com')

Rebuild the submit.cf file and restart the MSP daemon. Here is an example from our sample Linux system:

# ./Build submit.cf
Using M4=/usr/bin/m4
rm -f submit.cf
/usr/bin/m4 ../m4/cf.m4 submit.mc > submit.cf || ( rm -f submit.cf && exit 1 )
chmod 444 submit.cf
# cp submit.cf /etc/mail/submit.cf
# kill -HUP `head -1 /var/spool/clientmqueue/sm-client.pid`

Edit the system startup script. Change the command that starts the sendmail daemon by removing the -bd flag. For example, change this:

/usr/sbin/sendmail -bd -q15m

to this:

/usr/sbin/sendmail -q15m

Terminate the currently running daemon and rerun sendmail without the -bd flag:

# kill -TERM `head -1 /var/run/sendmail.pid`
# /usr/sbin/sendmail -q15m

Discussion

Most Unix startup configurations start the sendmail daemon as both an SMTP listener and a queue processor. The listener function, which is requested by the -bd command-line flag, binds sendmail to TCP ports where it listens for inbound mail.[1] The -bd option is only needed if the system collects inbound mail. Most Unix workstations do not need to collect inbound mail. A central server can collect and hold the mail for a large number of workstations, and users on the workstations can retrieve the mail using tools such as POP and IMAP.

Limiting the SMTP listener to servers provides some security advantages. As Introduction points out, SMTP servers are targets for attack because they accept connections and data from unknown hosts via the SMTP port. Intruders scan networks looking for systems that respond to SMTP connections and target their attacks against those systems. Running an SMTP listener on a system means that the system becomes a possible target. Mail servers must run the SMTP listener, but on other systems, the listener is an unnecessary risk. Controlling the SMTP ports at the firewall and limiting the number of systems listening to those ports provides defense in depth. If an administrator fails to disable the ports on a host, the firewall should stop an attack. If the firewall fails, limiting the number of systems listening to the SMTP ports limits the number of targets.

Limiting the number of systems that run the SMTP listener not only reduces risk, it also reduces the security administrator’s workload. Recipe 10.3 and Recipe 10.4 are good examples of this. They discuss applying fixes to sendmail to thwart an attack that comes through the SMTP port. Every system that accepts inbound SMTP connections is vulnerable to this attack. If only servers listen on that port, only servers are critically in need of the security maintenance necessary to fix this vulnerability. A site with thousands of desktop workstations might have only a handful of valid sendmail servers. Fixing a few servers is much easier than fixing thousands of desktops. Not only that, the skill level of the server administrators is generally high. Most of those administrators can handle the fix by themselves. Desktop users, on the other hand, require much more support. If anyone fails to correctly apply a critical security fix, the entire network remains in danger. Reducing the number of systems that require a critical fix is clearly a security and maintenance win.

This recipe describes changes to the submit.cf configuration. submit.cf is a special configuration used by sendmail when it acts as a mail submission program (MSP). The MSP configuration is an option available for systems running sendmail Version 8.12 and higher. When the submit.mc change is made and sendmail is restarted without the -bd flag, it is not necessary to update the sendmail.cf configuration. Recipe 10.2 shows an alternative to this recipe that changes the sendmail.cf configuration instead of the submit.cf configuration.

When a recipient replies to a message received from a system configured with this recipe, the reply must go to the server because replies sent directly to the workstation fail when the workstation does not have a listener on an SMTP port. Replies can be routed to the server with MX records, with masquerading on the workstation, or with masquerading on the server when all outbound mail is relayed through the server, as it is in this recipe’s submit.mc configuration. Masquerading on the workstation is used here because it makes a simpler example and all configuration changes can be made in one file.

The msp feature in the submit.mc file configures sendmail as a mail submission program. By default, the MSP sends mail to the MTA by connecting to an SMTP port at 127.0.0.1—the local host address. In that case, the local host must be running an SMTP listener in order to send outbound mail. Adding a hostname to the msp FEATURE command causes the MSP to connect to the SMTP port on the specified host. This means that the client does not need a listener to send outbound mail because outbound mail goes directly from the MSP to the MTA on the specified host. In this recipe, the hostname chef.wrotethebook.com is added to the FEATURE(`msp') command. Therefore, all outbound mail is sent to chef.wrotethebook.com for delivery. chef must be configured to accept this mail, as described in Chapter 2 and Chapter 3.

After creating the new configuration, edit the system startup files to ensure that they do not start an SMTP listener when the system reboots. The currently running version of sendmail must be terminated to end the current listener. Finally, run sendmail from the command line with the -q flag but without the -bd flag to start a queue runner that will drain the queue.

See Also

Recipe 10.10 provides an additional example of the submit.mc configuration. Chapter 1 describes how the MSP configuration is initially created during the installation of the sendmail source code distribution. Recipe 10.2 discusses an alternative solution that does not require changes to the submit.mc configuration; evaluate Recipe 10.2 before implementing this recipe. Chapters Chapter 2, Chapter 3, and Chapter 4 provide related recipes for clients sending outbound mail through servers and for configuring those servers to accept that mail. The sendmail book covers the msp feature in Section 4.8.27 and the MASQUERADE_AS macro in Section 4.4.2.

10.2. Limiting the Number of Network Accessible Servers

Problem

Accepting SMTP connections from the network makes a system a potential target of network-based security attacks. Special configuration is required to prevent the sendmail daemon from accepting inbound email connections from the network.

Solution

Select a limited number of hosts to act as mail exchangers and mail relay hosts for your enterprise. Configure the selected systems as described in Chapter 2 and Chapter 3. The other sendmail systems should be configured as described here.

Add the no_default_msa feature to the sendmail configuration to prevent sendmail from creating a default MSA configuration. Then add DAEMON_OPTIONS macros to create your own configuration that limits inbound mail connections to the loopback address. Finally, add the MASQUERADE_AS macro to the configuration so that replies to mail sent by the local host will go to a server that has an active SMTP port. Here are sample lines that could be added to the sendmail configuration:

dnl Don't create a default MSA configuration
FEATURE(`no_default_msa')
dnl Limit the MSA to the loopback address
DAEMON_OPTIONS(`Name=MSA, Port=587, Addr=127.0.0.1, M=E')
dnl Limit the MTA to the 127.0.0.1 interface
DAEMON_OPTIONS(`Name=MTA, Addr=127.0.0.1')
dnl Make sure replies go to the mail host
MASQUERADE_AS(`chef.wrotethebook.com')

Following the example in Recipe 1.8, rebuild and reinstall sendmail.cf, then restart sendmail.

Discussion

The DAEMON_OPTIONS macro sets values for the sendmail.cf DaemonPortOptions statements. A basic sendmail configuration has two DaemonPortOptions statements—one for the MTA mode of the sendmail daemon and one for the MSA mode. A grep shows this:

# grep 'DaemonPortOptions' generic-linux.cf
O DaemonPortOptions=Name=MTA
O DaemonPortOptions=Port=587, Name=MSA, M=E

Both port 25, used by the MTA, and port 587, used by the MSA, are accessible from the network, and thus are potentially vulnerable to network attacks. This book contains many examples of connecting to port 25. Here is one to illustrate the network accessibility of port 587:

$ telnet chef 587
Trying 192.168.0.8...
Connected to chef.
Escape character is '^]'.
220 chef.wrotethebook.com ESMTP Sendmail 8.12.9/8.12.4; Mon, 29 Sep 2003 10:45:59 -
0400
HELO rodent
250 chef.wrotethebook.com Hello rodent.wrotethebook.com [192.168.0.3], pleased to 
meet you
MAIL From:<[email protected]>
250 2.1.0 <[email protected]>... Sender ok
RCPT To:<[email protected]>
250 2.1.5 <[email protected]>... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Subject: 587 test

               .
250 2.0.0 h8TEjxrm001514 Message accepted for delivery
QUIT
221 2.0.0 chef.wrotethebook.com closing connection
Connection closed by foreign host.

The default Addr value used by DaemonPortOptions is INADDR_ANY, which means that the daemon accepts connections from any address. Identifying a specific address with the Addr value limits incoming connection to that specific address. Thus, setting Addr=127.0.0.1 means that only connections from the local host that come through the loopback interface will be accepted, which eliminates any inbound connections from the network. Rerunning the previous telnet test after completing this recipe shows that network connections are no longer allowed:

$ telnet chef 587
Trying 192.168.0.8...
telnet: connect to address 192.168.0.8: Connection refused
$ telnet chef 25
Trying 192.168.0.8...
telnet: connect to address 192.168.0.8: Connection refused

These tests show that network connections are not accepted on either port 25 or port 587. However, mail can still be sent from the local host.

Note that the no_default_msa feature must be used before you can change the DaemonPortOptions settings of the MSA. The FEATURE macro must precede the DAEMON_OPTIONS macro in the configuration. This feature is not required when you are changing only MTA values.

Recipe 10.1 is an alternative to this recipe; it prevents sendmail from accepting SMTP connections from the network. In fact, that recipe prevents sendmail from accepting any SMTP connections—even from the local host. Recipe 10.1 provides slightly more security than this recipe because even someone with login access to the local host cannot attack sendmail through the SMTP ports. However, Recipe 10.1 is more complex and difficult to implement than this recipe. Here, all changes take place in the sendmail configuration file; Recipe 10.1 requires changes to the sendmail configuration and to the system startup files. Thus, the increased security of Recipe 10.1 comes at the cost of increased complexity.

See Also

Recipe 7.8 covers the syntax of the DAEMON_OPTIONS macro and provides another example of its use. Recipe 10.1 discusses an alternative solution that changes the submit.mc configuration to accomplish a similar goal. Recipe 10.1 should be evaluated before implementing this recipe. Chapter 4 covers the MASQUERADE_AS macro. The sendmail book covers the DAEMON_OPTIONS macro in Section 24.9.24, the no_default_msa feature in Section 4.8.30, and the MASQUERADE_AS macro in Section 4.4.2.

10.3. Updating to Close Security Holes

Problem

You must close known sendmail security holes that intruders are exploiting.

Solution

Subscribe to the sendmail-announce mailing list to receive notification of important security updates by sending mail to [email protected] that contains the following line:

subscribe sendmail-announce

Download the sendmail source code distribution to fix any known security problems. Detailed instructions for downloading the sendmail distribution are found in Recipe 1.1.

Restore, recompile, and reinstall sendmail as described in Recipe Recipe 1.2.

Discussion

Failure to fix known security problems is the single biggest security threat to all systems. Intruders frequently exploit known security holes to crash systems or gain access—even root access. Subscribing to sendmail-announce lets you know if there are sendmail security fixes that affect your system. Downloading, compiling, and installing the new version of sendmail is a security priority.

See Also

Recipe 1.1 and Recipe 1.2 cover downloading, compiling, and installing sendmail. Recipe 1.3 to Recipe 1.7 provide additional examples of recompiling sendmail. Chapter 2 of the sendmail book provides extensive details on installing an updated version of sendmail.

10.4. Patching to Close Security Holes

Problem

You need to apply patches to close known sendmail security holes.

Solution

Subscribe to the sendmail-announce mailing list to receive notification of important security patches by sending mail to [email protected] that contains the following line:

subscribe sendmail-announce

Download the patch from ftp.sendmail.org or from www.sendmail.org. Use the patch command to apply a security patch to the sendmail source code.

Recompile and reinstall sendmail, as described in Recipe 1.2, using the patched source code.

Restart sendmail. For example:

# kill -HUP `head -1 /var/run/sendmail.pid`

Discussion

Fixing a problem with a source code patch is very similar to installing a completely new sendmail source code distribution. In both cases:

  • You download source code from sendmail.org. In one case, it is a large tar file, and in the other, it is a small patch file, but in both cases the download is essentially the same.

  • You download a signature file to verify the source code.

  • You use gpg or pgp to verify the downloaded source file.

  • You recompile, reinstall, and restart sendmail.

The biggest differences between the two approaches to closing a security hole are:

  • In one case, you use tar to create a completely new source tree.

  • In the other case, you use patch to change files in an existing source tree.

The approach you use depends on your personal preferences and the nature of the sendmail currently installed on your system. If you use a version of sendmail provided by a vendor that has some special features, patching may be a way to fix a security problem while retaining those features. Of course there is no guarantee. If the vendor has extensively modified the sendmail source, the patch may not work.

If you really are dependent on a vendor supplied version of sendmail, the best approach is to go directly to the vendor for the security fix. For example, for a Red Hat Linux system, you can obtain critical security fixes directly from the Red Hat web site. Figure 10-1 shows a web page at redhat.com that points to the RPM files containing a sendmail security fix.

sendmail fixes available from Red Hat
Figure 10-1. sendmail fixes available from Red Hat

This chapter, like the rest of this book, uses the sendmail source code distribution instead of a vendor’s copy of sendmail. In particular, sendmail 8.12.9 is used throughout this book because it was the latest version of sendmail available when the bulk of this book was written. The following example shows sendmail 8.12.9 being patched to fix a critical security problem.

Fixes for the sendmail source code distribution can be obtained directly from sendmail.org. This example begins by downloading the patch from the pub/sendmail directory on ftp.sendmail.org. The source code patch file is parse8.359.2.8 and the signature file for the patch file is parse8.359.2.8 .sig:

# ftp ftp.sendmail.org
Connected to ftp.sendmail.org (209.246.26.22).
220 services.sendmail.org FTP server (Version 6.00LS) ready.
Name (ftp.sendmail.org:WIN): anonymous
331 Guest login ok, send your email address as password.
Password: [email protected]
230 Guest login ok, access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd pub/sendmail
250 CWD command successful.
ftp> get parse8.359.2.8
local: parse8.359.2.8 remote: parse8.359.2.8
227 Entering Passive Mode (209,246,26,22,196,166)
150 Opening BINARY mode data connection for 'parse8.359.2.8' (346 bytes).
226 Transfer complete.
346 bytes received in 0.000351 secs (9.6e+02 Kbytes/sec)
ftp> get parse8.359.2.8.sig
local: parse8.359.2.8.sig remote: parse8.359.2.8.sig
227 Entering Passive Mode (209,246,26,22,196,171)
150 Opening BINARY mode data connection for 'parse8.359.2.8.sig' (152 bytes).
226 Transfer complete.
152 bytes received in 0.000672 secs (2.2e+02 Kbytes/sec)
ftp> quit
221 Goodbye.

Verify the patch using the signature file downloaded from sendmail.org:

# gpg --verify parse8.359.2.8.sig parse8.359.2.8
gpg: Signature made Thu 18 Sep 2003 10:17:20 AM EDT using RSA key ID 396F0789
gpg: Good signature from "Sendmail Signing Key/2003 <[email protected]>"
gpg: checking the trustdb
gpg: checking at depth 0 signed=1 ot(-/q/n/m/f/u)=0/0/0/0/0/1
gpg: checking at depth 1 signed=0 ot(-/q/n/m/f/u)=1/0/0/0/0/

To verify the signature, you must have previously downloaded the PGP keys from sendmail.org and added those keys to your key ring. Downloading the PGP keys and adding them to the key ring is shown in Recipe 1.1.

Apply the source code patch:[2]

# cd /usr/local/src/sendmail-8.12.9/sendmail
# patch < /usr/local/src/patches/parse8.359.2.8
patching file parseaddr.c

After the source code is patched, it must be recompiled and reinstalled, as described in Recipe 1.2. Then the sendmail daemon must be restarted to ensure that it is using the patched software.

Installing a completely new sendmail distribution is an alternative to patching the old one. The same fix installed by patching sendmail 8.12.9 could have been made by installing sendmail 8.12.10.

See Also

Recipe 10.3 provides an alternative way to fix a security hole.

10.5. Disabling Delivery to Programs

Problem

By default, sendmail allows mail to be addressed to programs. Special configuration is required if you wish to disable this feature.

Solution

Check the flags set for the mailers used in the sendmail.cf configuration file. Here is an example of using grep and awk to display the mailer flags:

# grep '^M' sendmail.cf | awk '{ print $1 $3 }'
Mlocal,F=lsDFMAw5:/|@qSPfhn9,
Mprog,F=lsDFMoqeu9,
Msmtp,F=mDFMuX,
Mesmtp,F=mDFMuXa,
Msmtp8,F=mDFMuX8,
Mdsmtp,F=mDFMuXa%,
Mrelay,F=mDFMuXa8,
Mcyrus,F=lsDFMnPqAh5@/:|,
Mcyrusbb,F=lsDFMnPu,

Add a MODIFY_MAILER_FLAGS macro to the sendmail configuration to remove the | flag for each mailer that has that flag set. Given the listing of flags shown above, this system has the | flag set for both the local mailer and the cyrus mailer. To remove the | flag from these two mailers, add the following lines to the sendmail configuration:

dnl Remove the | flag with the cyrus mailer
MODIFY_MAILER_FLAGS(`CYRUS', `-|')
dnl Remove the | flag from the local mailer
MODIFY_MAILER_FLAGS(`LOCAL', `-|')

As described in Recipe 1.8, rebuild and reinstall sendmail.cf, and then restart sendmail.

Discussion

In certain circumstances, sendmail will deliver mail to a program when the email address begins with a vertical bar. sendmail only delivers to a program when the mailer used for that delivery has a | in the flags defined by the mailer’s F parameter. Disable delivery to programs by removing the | flag from all sendmail.cf mailer definitions.

Flags can be added to or removed from a mailer definition using the MODIFY_MAILER_FLAGS macro. To add a flag to a mailer specify the flag with a plus sign (+). To remove a flag use a minus sign (-) with the flag. The MODIFY_MAILER_FLAGS macros used in Recipe 10.5.2 remove the | flag from the local and the cyrus mailers because the flag on the macro command line is preceded by a minus sign. To replace the flags of a mailer, list the new flags without plus or minus signs. For example:

dnl Define new flags for the local mailer
MODIFY_MAILER_FLAGS(`LOCAL', `lsDFMAw5:/@qSPfhn9')

Note that this MODIFY_MAILER_FLAGS line has the same impact as the second one used in Recipe 10.5.2 because the new set of flags contains all of the flags from the default configuration except the | flag. -| was used in Recipe 10.5.2 because it shows more clearly exactly what is being modified, and it is less prone to a typographical error than is the full list of flags.

Most commonly, mail is sent to programs from the aliases database or the user’s .forward file. If your intention is to prevent users from forwarding mail to programs, eliminating the | flag from sendmail mailers may not be enough. sendmail is often not the most powerful tool at a user’s disposal. If users can login to the system providing mail service, they have the full power of a shell at their disposal. If the system uses procmail as the local mailer, as Linux does, users have full access to the power of procmail simply by creating a .procmailrc file. (Recipe 10.8 shows how to override the local_procmail feature on a Linux system.) Before you eliminate a sendmail feature or reset a mailer flag that may make sendmail less flexible and less powerful, evaluate the true security impact of the change.

See Also

Recipe 10.7 shows another example of using MODIFY_MAILER_FLAGS to disable a sendmail feature. Recipe 10.6 shows an alternative to completely eliminating delivery to programs. The sendmail book covers MODIFY_MAILER_FLAGS in Section 20.5.6.1.

10.6. Controlling Delivery to Programs

Problem

Special configuration is needed to control which programs are started by the prog mailer.

Solution

Check the smrsh manpage for the location of the smrsh execution directory, which is usually either /etc/smrsh or /usr/adm/sm.bin. (The Discussion section shows how the smrsh program can be checked for the execution directory path.) If the smrsh program directory does not already exist, create the appropriate directory, making sure that it is owned by root and only writable by root. Here is an example:

# mkdir /usr/adm/sm.bin
# chmod 751 /usr/adm/sm.bin

To make a program accessible via the prog mailer, create a symbolic link for the program in the smrsh execution directory. Here is an example of creating links to the vacation and slocal programs:

# cd /usr/adm/sm.bin
# ln -s /usr/local/bin/vacation
# ln -s /usr/lib/nmh/slocal

Add the smrsh feature to the sendmail configuration to use smrsh, the Sendmail Restricted Shell, as the binary for the prog mailer. Here is an example of the required FEATURE macro:

dnl Use smrsh as the prog mailer
FEATURE(`smrsh')

Build the sendmail.cf configuration file, copy it to /etc/mail/sendmail.cf, and restart sendmail, as described in Recipe 1.8.

Discussion

sendmail uses the prog mailer to deliver mail to a recipient address that begins with the pipe character. The P parameter of the prog mailer definition defines the path to the prog mailer program and the A parameter defines the command used to run the mailer. With the default sendmail configuration, the P parameter is P=/bin/sh and the A parameter is A=sh -c $u. $u is a sendmail macro that contains the email address of the user to which the mail is being delivered. For example, given the following .forward file:

"|/usr/lib/nmh/slocal -user reba"

the command executed for the prog mailer would be:

 /bin/sh -c "/usr/lib/nmh/slocal -user reba"

When the -c option is used with /bin/sh, shell commands are read from the string that follows -c. In this case, sendmail causes the shell to execute a program named slocal. sendmail attaches its output to the standard input of the shell and prints out the mail message, which, in the example, sends the mail message to the slocal program. sendmail also attaches the standard output and standard error of the shell to its input.

The shell will execute any command passed to it. The potential security risks of executing any command that follows the pipe character in a recipient address are obvious. Using the Sendmail Restricted Shell (smrsh) for the prog mailer instead of /bin/sh limits the commands that can be executed, thus enhancing security. smrsh enforces the following restrictions:

  • Only a few built-in shell commands—exec, exit, and echo—work; most do not.

  • Standard I/O redirection is not allowed.

  • Most of the special characters used by the shell—carriage return, newline, <, >, ;, $, (, and )—are not allowed.

  • Most importantly, only those programs that you choose to make available to smrsh through its special program directory are available to the user. On a system running smrsh, mail addressed to programs not listed in the smrsh execution directory is rejected with the error “unavailable for sendmail programs.”

The default path for the smrsh program directory is /usr/adm/sm.bin. Vendors often change the path. For example, the Red Hat sendmail RPM distribution defines the path as /etc/smrsh. To find out where your version of sendmail puts the smrsh program directory, check the manpage or look inside the smrsh program, using the following commands:

# grep '^Mprog' /etc/mail/sendmail.cf
Mprog,          P=/usr/sbin/smrsh, F=lsDFMoqeu9, S=EnvFromL/HdrFromL, 
               R=EnvToL/HdrToL, D=$z:/, 
# strings /usr/bin/smrsh | grep '^/'
/lib/ld-linux.so.2
/usr/adm/sm.bin
/bin:/usr/bin:/usr/ucb
/bin/sh

The first grep command prints out the first line of the prog mailer definition from the sendmail.cf file. The P parameter of the prog mailer definition tells us where sendmail expects to find the smrsh program. We use the value from the P parameter to point the strings command to the correct program. The strings command displays all of the literal strings found in the smrsh executable. We pass its output through grep to select only those strings that are pathnames. Because we know that the default path for the smrsh program directory is /usr/adm/sm.bin, it is easy to pick the program directory path out of this list.

To force smrsh to use some other directory as its program directory, recompile smrsh. The # define CMDDIR line in the smrsh.c source file points to the program directory. Compile smrsh with the -DSMRSH_CMDDIR compile option to specify a different directory path. This can be done by adding a command, such as the following, to the devtools/Site/site.config.m4 file:

APPENDDEF(`conf_smrsh_ENVDEF', `-DSMRSH_CMDDIR="/etc/smrsh/"')

Most administrators decide to create the program directory where smrsh expects to find it instead of recompiling smrsh to change the default path. When working with the sendmail tarball, creating your own /usr/adm/sm.bin directory is both easier and better than recompiling smrsh with compile options or modified source code; this is true for three reasons. First, most system administrators find the mkdir command easier to work with than the cc command or C source code. Second, this is the standard directory where most Unix administrators expect to find the smrsh programs. Third, the smrsh manpage that comes with the sendmail tarball tells readers that the programs are located in the /usr/adm/sm.bin directory. (If you change the directory, you should also change the manpage.) When using the sendmail distribution provided by a vendor, use the vendor’s default directory. When using the sendmail tarball, use /usr/adm/sm.bin.

Populate the directory with the programs that are trusted to be accessible through the prog mailer. Programs are added to the smrsh program directory in two ways:

  1. The program is moved to the directory.

  2. A symbolic link is placed in the directory pointing to the program.

Recipe 10.6.2 uses symbolic links. This is the most popular way to add programs to the smrsh program directory. It is slightly less secure than actually moving programs to the directory because both the smrsh program directory and the other directories in which the programs actually reside must be secured against unauthorized changes. The more things there are to secure, the more likely a security mistake will be made. However, the risk is small, so most administrators prefer using symbolic links.

Take care when adding programs to the smrsh execution directory. Poorly written programs are popular targets for attackers. Additionally, do not add programs that can be used to launch other programs. Shells, such as /bin/sh, and programs, such as procmail, which can be directed by the user to start other programs, defeat the purpose of smrsh and thus do not belong in the smrsh execution directory.[3] Every program is a potential hole for an intruder to exploit. Choose them carefully.

In Recipe 10.6.2 two symbolic links are added to the smrsh program directory. On our sample system, these links allow access to:

  • The vacation program—a program that automatically responds to mail when the user is out of the office for an extended period.

  • The slocal program—a mail filtering program.

Users can then create .forward files that use these programs. For example, Kathy could define the following .forward file when she goes on vacation:

kathy, "|/usr/local/bin/vacation kathy"

smrsh strips the initial pathname off of the program to which mail is being forwarded. Thus, when /usr/local/bin/vacation is the program name in the recipient address, smrsh strips the program name down to vacation and looks for a file of that name in the smrsh program directory.

See Also

Recipe 10.5 describes how to completely disable delivery to programs. The sendmail book covers the smrsh program in Section 5.8.

10.7. Disabling Delivery to Files

Problem

Special configuration is required to block delivery directly to a file or device.

Solution

Check the flags set for the mailers used in the sendmail.cf configuration file. Here is an example of using grep and awk to display the mailer flags:

# grep '^M' sendmail.cf | awk '{ print $1 $3 }'
Mlocal,F=lsDFMAw5:/|@qSPfhn9,
Mprog,F=lsDFMoqeu9,
Msmtp,F=mDFMuX,
Mesmtp,F=mDFMuXa,
Msmtp8,F=mDFMuX8,
Mdsmtp,F=mDFMuXa%,
Mrelay,F=mDFMuXa8,
Mcyrus,F=lsDFMnPqAh5@/:|,
Mcyrusbb,F=lsDFMnPu,

Add a MODIFY_MAILER_FLAGS macro to the sendmail configuration to remove the / flag for each mailer that has that flag set. Given the listing of flags just shown, this system has the / flag set for both the local mailer and the cyrus mailer. To remove the / flag from these two mailers, add the following lines to the sendmail configuration:

dnl Remove the / flag with the cyrus mailer
MODIFY_MAILER_FLAGS(`CYRUS', `-/')
dnl Remove the / flag from the local mailer
MODIFY_MAILER_FLAGS(`LOCAL', `-/')

Rebuild and reinstall sendmail.cf, and then restart sendmail. See Recipe 1.8 for an example of these steps.

Discussion

Every user who has a valid login shell is allowed to send mail to files or programs. This makes sense because anyone who has a login shell on the mail host already has greater access to the system than that which is granted via the prog mailer, particularly if smrsh is used for the prog mailer. Care should be taken to ensure that no user ID is given a login shell unless it is really needed. Controlling login access is clearly more important for security than anything that can be done in the sendmail configuration.

Additionally, as Recipe 10.4.3 of Recipe 10.5 points out, other sendmail features can give users the ability to run programs or write to files independent of which mailer flags are set. For example, using procmail as the local mailer gives the user access to all of the power of procmail, including the ability to write files.[4] Before you implement this recipe, make sure it is necessary, and make sure it will work in your environment. That said, removing the / flag from all sendmail.cf mailer definitions will disable delivery to files because sendmail only delivers to files and devices when the mailer used for that delivery has the / flag set.

At this writing, only the local mailer and the cyrus mailer have this flag set by default, and most configurations don’t use the cyrus mailer. Therefore, for most configurations, only the local mailer can deliver to files, and removing the / from the flags for the local mailer definition would completely disable this feature.

Use the MODIFY_MAILER_FLAGS macro to remove, add, or change mailer flags. Recipe 10.5 covers the syntax of the MODIFY_MAILER_FLAGS macro in some detail.

See Also

Recipe 10.5 shows another example of using MODIFY_MAILER_FLAGS to disable a sendmail feature. The sendmail book covers MODIFY_MAILER_FLAGS in Section 20.5.6.1.

10.8. Bypassing User .forward Files

Problem

You want to control which users are allowed to define their own .forward files.

Solution

Create a directory that will list all users who are allowed to use their own .forward files:

# cd /etc/mail
# mkdir forward
# chmod 751 forward

Grant users the right to use their own .forward files by adding symbolic links to the /etc/mail/forward directory that point to the users’ .forward files. For example, assume that the sendmail administrator trusts craig, alana, and david to build safe .forward files. The administrator can “activate” their files with the following commands:

# cd /etc/mail/forward
# ln -s /home/craig/.forward craig
# ln -s /home/alana/.forward alana
# ln -s /home/david/.forward david

Add a confFORWARD_PATH define to the sendmail configuration that points to the directory created above. Here is an example:

dnl Use a special ForwardPath
define(`confFORWARD_PATH', `/etc/mail/forward/$u')

Build the new configuration file, copy it to /etc/mail/sendmail.cf, and restart sendmail, as described in Recipe 1.8.

Discussion

Security is improved when users are given only those privileges that they can use effectively. Many users have no interest in using the .forward file. A few lack the skill to create a safe and effective file. Only a subset of users want, need, and know how to use the .forward file. This recipe takes the approach of blocking access to every user’s .forward file and then, on an exception basis, granting access to the .forward file to individual users who can effectively use it.

The first step is to build a directory that is only writable by root, and to populate that directory with links to the .forward files of users who are allowed to use .forward files. In the example, the directory is named /etc/mail/forward. Each symbolic link is given the username of a user allowed to use a .forward file.

The sendmail configuration is modified so that sendmail looks for the .forward file in the /etc/mail/forward directory. In this recipe, the path defined for the ForwardPath option is /etc/mail/forward/$u, where $u returns the local recipient’s username. Therefore, if $u returns craig, sendmail looks for a file named /etc/mail/forward/craig. If it finds a file with that name, sendmail uses that file as the .forward file.

Any user can create a .forward file, but the file they create is ignored unless the system administrator adds a symbolic link for the user to the /etc/mail/forward directory. Recipe 10.7.2 shows the administrator adding symbolic links for craig, alana, and david. In this example, only those three users are allowed to use a .forward file.

Overriding the local_procmail feature

Most of the examples in this book were created on a Red Hat Linux system. Linux systems use procmail as the local mailer. When procmail is the local mailer, a user can forward to any address they wish without creating a .forward file. All they need to do is create a .procmailrc file to forward the mail. There is no point in implementing this recipe on a system that uses procmail as the local mailer.

If you’re positive that you want to use this recipe on a Linux system, you need to make additional configuration changes. Linux uses procmail as the local mailer because the local_procmail feature is specified in the linux.m4 file loaded by the OSTYPE macro. Override the configuration changes made by the FEATURE(local_procmail) command by adding the following three lines to your sendmail configuration after the OSTYPE macro and before the MAILER(local) line:

undefine(`LOCAL_MAILER_PATH')
undefine(`LOCAL_MAILER_FLAGS')
undefine(`LOCAL_MAILER_ARGS')

These three lines undefine the local mailer path, flags, and arguments defined by the local_procmail feature. These lines cause sendmail to use /bin/mail as the local mailer, and they set the correct flags and arguments for /bin/mail. This recipe can be implemented on a system using /bin/mail with no problems.

See Also

Aliasing and the role of the .forward file are covered in Chapter 2. The sendmail book covers the confFORWARD_PATH macro in Section 24.9.48, the LOCAL_MAILER_PATH define in Section 20.5.11.1, the LOCAL_MAILER_FLAGS define in Section 20.5.6.2, the LOCAL_MAILER_ARGS define in Section 20.5.2.1, and the local_procmail feature in Section 4.8.21.

10.9. Controlling Delivery to Files

Problem

You want to limit the files and devices to which sendmail writes mail messages.

Solution

Create a directory to contain all of the files to which users can deliver mail. In this example, we create a directory for this purpose that we name /var/mail/archives:

# cd /var/mail
# mkdir archives
# chmod 700 archives

Add a confSAFE_FILE_ENV define to the sendmail configuration to point the SafeFileEnvironment option to the newly created directory. The following provides an example of the confSAFE_FILE_ENV define:

dnl Limit delivery to files to the /var/mail/archives directory
define(`confSAFE_FILE_ENV', `/var/mail/archives')

Build the configuration, copy it to /etc/mail/sendmail.cf, and restart sendmail, as described in Recipe 1.8.

Discussion

Recipe 2.11 shows examples of users writing to files via their .forward files. When the delivery address for a piece of mail contains a / and no @ host part, sendmail assumes that the address is the name of a file and appends the mail message to that file. By default, sendmail will append the mail to any device or file that does not have execute permissions set.

Specify the SafeFileEnvironment option to tell sendmail that it should only append to ordinary files or /dev/null. To limit the ordinary files sendmail may write, add a path to the confSAFE_FILE_ENV define. When a path is used, sendmail only writes to files located in that path. This recipe limits this form of mail delivery to either /dev/null or to nonexecutable, ordinary files located in the /var/mail/archives path.

See Also

Recipe 10.8 shows how delivery to files can be completely disabled. Delivery to files normally takes place through aliases defined in the aliases database or the user’s .forward file. For more information on the aliases database and the .forward file, see Chapter 2. The sendmail book covers delivery to files in sections 10.8.2.8, 12.2.2, and 24.9.95.

10.10. Running sendmail Non-Set-User-ID root

Problem

You wish to reduce the amount of time that sendmail runs as a root process.

Solution

Upgrade to the latest release of sendmail 8.12. Create an entry for the user smmsp in the /etc/passwd file and an entry for the group smmsp in the /etc/group file. Install and compile the new sendmail distribution as described in Recipe 1.2.

Discussion

sendmail runs as a daemon or an interactive process. As a daemon, sendmail is used to listen on network ports or to periodically check the mail queue. sendmail can also be launched as an interactive process by a user’s mail program or by the user from the command line to submit a message to the message transmission agent (MTA). A daemon that binds a listener to a privileged network port must run as root, but many of sendmail’s other duties can be done without root privileges. In particular, when sendmail is used as a message submission program (MSP) launched by a user to send mail to the MTA, it does not need root privilege. Recipe 1.2 describes a configuration that ensures that sendmail has root privilege only when necessary.

The decision to run the sendmail program as set-user-ID root must be taken early in the installation process. Beginning with sendmail 8.12, the default is to run the sendmail program as set-group-ID smmsp, as a simple ls command shows:

$ ls -l /usr/sbin/sendmail
-r-xr-sr-x    1 root     smmsp      615263 Jan 24 16:13 /usr/sbin/sendmail

To force sendmail to install the sendmail program as set-user-ID root, which would reduce security, run Build install-set-user-id instead of Build install during the initial installation of the sendmail distribution. Of course, we don’t recommend this.

The set-group-ID smmsp configuration is a definite security improvement over earlier versions of sendmail because users no longer use a set-user-ID root program to send mail. Instead, the sendmail process launched by the user from the command line retains the user’s UID. The GID of the process is set to smmsp in order to allow the process to queue mail in the case of a delivery failure.

In earlier versions of sendmail, the program always ran set-user-ID root. However, sendmail must run as root only when it is run as a daemon listening for inbound mail. root privilege is not necessary for sending outbound mail.

It is necessary, however, to create a separate mail queue that is owned by the user smmsp for those times when sendmail is running as a non-root process. That queue, named /var/spool/clientmqueue, is created by the Build install command during the installation of the sendmail distribution, as this snippet of messages from an installation shows:

You must have setup a new user smmsp and a new group smmsp
as explained in sendmail/SECURITY.
mkdir -p /var/spool/clientmqueue
chown smmsp /var/spool/clientmqueue
chgrp smmsp /var/spool/clientmqueue
chmod 0770 /var/spool/clientmqueue
install -c -o root -g smmsp -m 2555 sendmail /usr/sbin

In addition to its own queue, MSP sendmail has its own configuration file. That file is always called submit.cf and is built from the submit.mc file. The submit.mc file delivered with the sendmail 8.12.9 distribution contains the following lines:

VERSIONID(`$Id: ch10.xml,v 1.6 2004/01/05 18:48:33 chodacki Exp $')
define(`confCF_VERSION', `Submit')
define(`_OSTYPE  _',`')dnl dirty hack to keep proto.m4 from complaining
define(`_USE_DECNET_SYNTAX_', `1')dnl support DECnet
define(`confTIME_ZONE', `USE_TZ')
define(`confDONT_INIT_GROUPS', `True')
dnl
dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:::1]
FEATURE(`msp', `[127.0.0.1]')

The VERSIONID macro defines version information for the .mc file. The confCF_VERSION define specifies version information for the .cf file. By default, the .cf file version information, which is stored in the $Z macro, matches the sendmail version number. In this example, that would be 8.12.9. The confCF_VERSION define adds the string “Submit” to that information, as this grep shows:

# grep '^DZ' submit.cf
DZ8.12.9/Submit

The next two lines define internal proto.m4 variables in ways that are designed to trick the system into doing something a little out of the ordinary. The first defines the _OSTYPE_ variable. Normally this variable is defined by the OSTYPE macro. If this variable does not exist, the error “No system type defined (use OSTYPE macro)” is displayed and the m4 process terminates. Setting the variable directly tricks the system into continuing on without an OSTYPE macro.

The _USE_DECNET_SYNTAX_ define allows DECnet style node ::user addressing. Normally, this variable is set to 1 by the DECNET_RELAY macro when a DECnet relay host is defined. The submit.cf file does not define a DECnet relay host. All mail is sent by the relay mailer to the host defined in the ${MTAHost} macro. The _USE_DECNET_SYNTAX_ define is required in order to support DECnet syntax without a DECnet relay host.

confTIME_ZONE defines the way in which sendmail should determine the local time zone. Because the MSP configuration does not run as root, it can safely determine the local time zone from the TZ environment variable. Thus, the confTIME_ZONE define is set to USE_TZ in the submit.mc file used for the MSP configuration.

The last define is confDONT_INIT_GROUPS. In the submit.cf file it sets the DontInitGroups option to True. This setting prevents sendmail from changing its UID and GID when performing certain tasks, such as running a mail delivery agent. Because the MSP configuration is supposed to run as user smmsp and not supposed to use any special privileges, it makes sense to include this define in the configuration.

After two comment lines, the last command in the configuration enables the msp feature, which is the heart of the configuration. The msp feature creates the configuration that makes this a message submission program. The argument passed to the msp feature is the hostname or IP address of the MTA to which the MSP should send the mail. The argument is stored in the submit.cf macro ${MTAHost}.

In the submit.mc file delivered with sendmail 8.12.9, the msp argument is [127.0.0.1], which is the loopback address for the local host on all IPv4 systems. Square brackets are always placed around a numeric address; when placed around a hostname, they prevent sendmail from looking up the MX records for that hostname. [127.0.0.1] is the default value for ${MTAHost}, so this argument is not really needed on the msp command line. The reason it is used in the submit.mc file provided with 8.12.9 is as an example for administrators who might need to change the ${MTAHost} value. Recipe 10.1 provides an example of changing the ${MTAHost} value to enhance system security.

Only minimal edits should be made to the submit.mc file. Good examples of appropriate edits are the changes made by Red Hat and those shown in Recipe 10.1. Red Hat modifies the submit.mc file to put the sm-client.pid file into the /var/run directory instead of into the /var/spool/clientmqueue directory, where it is placed by default. Recipe 10.1 shows an example of how the submit.mc file is modified on a system that does not run an SMTP listener. It is the only recipe in this text that modifies submit.cf; every other recipe applies to sendmail.cf.

The default submit.cf file sets the RunAsUser option to smmsp. It is the RunAsUser option that tells sendmail to run as something other than root. This option predates the submit.cf configuration and was originally created for use on some firewall bastion hosts that run sendmail as a non-root process. However, the submit.cf configuration is the most effective use of this option that I have seen. Don’t confuse the RunAsUser option with the DefaultUser option—they are incompatible. RunAsUser defines the user ID used instead of root. DefaultUser defines the user ID used in addition to root when a copy of sendmail that has root privileges gives up those privileges. DefaultUser is covered in Recipe 10.11.

See Also

Chapter 1 covers the installation of sendmail, including the creation of the smmsp user and group IDs. Recipe 10.1 provides a realistic example of editing the submit.mc configuration. The sendmail book covers the MSP configuration in Section 2.6.2, the msp feature in Section 4.8.27, confCF_VERSION in 21.9.100, confTIME_ZONE in 24.9.110, confDONT_INIT_GROUPS in 24.9.38, ${MTAHost} in 21.9.67, RunAsUser in 24.9.94, and DefaultUser in 24.9.29.

10.11. Setting a Safe Default User ID

Problem

sendmail requires its own user ID for when it is not running as root.

Solution

Check the /etc/passwd, /etc/shadow, and /etc/group files to see if your system has entries for the user mailnull and the group mailnull.[5] If you find mailnull entries in these files, you’re done. Otherwise, add mailnull to /etc/passwd using UID and GID values that are available on your system. On our sample system, we used the following entry:

mailnull:x:65533:65533:Sendmail DefaultUser:/var/spool/mqueue:/bin/false

Next, add mailnull to the /etc/group file, as in this example:

mailnull:x:65533:

And, if you use the /etc/shadow file, add a mailnull entry to that file. Here is an example that is compatible with the shadow file used on Red Hat Linux systems:

mailnull:!!:11530:0:99999:7:::

Discussion

When sendmail is running with root privileges, the DefaultUser option identifies the user ID and group ID that sendmail uses when it gives up root privileges. This is the UID and GID used to do such things as run mailers and other external commands. When DefaultUser is not explicitly defined in the configuration, four possible default values are available. The order in which these defaults are used is:

  1. If the user mailnull is defined in the /etc/passwd file, the user ID and group ID assigned to mailnull are used.

  2. If mailnull is not defined and the user sendmail is defined in the /etc/passwd file, the user ID and group ID assigned to the user sendmail are used.

  3. If neither mailnull nor sendmail is defined in /etc/passwd and the user daemon is defined, the user ID and group ID assigned to daemon are used.

  4. If neither mailnull, nor sendmail, nor daemon is defined in the /etc/passwd file, 1 is used as the user ID and 1 is used as the group ID.

Use confDEF_USER_ID in the m4 master configuration file to override these default values. The master configuration file delivered with Red Hat Linux 8.0 provides an example of how the confDEF_USER_ID command is used. It contains the following:

define(`confDEF_USER_ID',`8:12')

This define command sets the user ID to 8 and the group ID to 12 for the DefaultUser option. These values are associated with the username mail and the groupname mail found in the /etc/passwd and /etc/group files delivered with the Red Hat Linux 8.0 system. The Red Hat configuration uses numeric UID and GID values for the confDEF_USER_ID define. However, string values are also acceptable. The following command sets exactly the same values for the Red Hat system:

define(`confDEF_USER_ID',`mail:mail')

This would also work:

define(`confDEF_USER_ID',`mail')

This works because, when the GID field is empty and the UID is a string value, the GID value defined in the /etc/passwd entry for the specified username is used. It is also possible to define the GID value separately using confDEF_GROUP_ID. However, confDEF_GROUP_ID has been deprecated and should not be used.

Given all of these options for setting the DefaultUser value, it is interesting to note that not one of them is used here. Instead, we opted to use the default mailnull user ID. There are two advantages to doing so:

  • First, using the default mailnull user ID can be done without any sendmail configuration changes.

  • Second, mailnull is the default value that most sendmail administrators expect to find.

In fact, many Unix systems come with an entry for the user mailnull already in the /etc/passwd file. If that is the case on your system, there is no need to implement this recipe because your system is already using the DefaultUser option. A simple grep shows the mailnull entries from the /etc/passwd file and the /etc/shadow file, if they exist:

# grep mailnull /etc/passwd
mailnull:x:47:47::/var/spool/mqueue:/dev/null
# grep mailnull /etc/shadow
mailnull:!!:11267:0:99999:7:::

Some Unix systems don’t provide /etc/passwd and /etc/group entries for the DefaultUser option, so you will need to add them yourself. If you do add a mailnull user account, there are three characteristics of that account that you need to be aware of:

  • mailnull must not have an associated password. The mailnull user created in this recipe does not have a valid password in either the /etc/passwd file or the /etc/shadow file.

  • mailnull must not have a valid login shell. In this recipe, mailnull is given /bin/false as its login shell in the /etc/passwd file.

  • mailnull must not own any files.

These three requirements help prevent the account from being exploited to gain unauthorized access.

See Also

Recipe 10.10 covers the RunAsUser option—an incompatible option that is sometimes confused with the DefaultUser option. For information on the /etc/passwd, /etc/shadow, and /etc/group files see a good system administration text, such as Essential System Administration, Third Edition, by Æleen Frisch (O’Reilly). The sendmail book covers the DefaultUser option in Section 10.8.2.1 and Section 24.9.29.

10.12. Defining Trusted Users

Problem

System changes, such as installing a new mail delivery program, may require adding names to the list of users who can override the sender address.

Solution

Carefully determine if there is really a need for additional trusted users. Only when absolutely necessary, add a confTRUSTED_USERS define to the sendmail configuration, such as the one shown below:

dnl Add a user to the list of trusted users
define(`confTRUSTED_USERS', `bin')

Rebuild the configuration, copy it to /etc/mail/sendmail.cf, and restart sendmail. See Recipe 1.8.

Discussion

The users identified in the sendmail.cf file by T commands are allowed to override the sender address, and they are allowed to rebuild the aliases database. Limit the users identified by T commands to only those UIDs needed for important mail delivery programs that actually use the sendmail command with the -f switch to deliver mail. The rmail program is a good example. It runs using uucp as its UID. Mail delivered by rmail would appear to come from the user uucp if it did not use the -f switch to change the sender address to the address of the person who really sent the mail. For this reason, uucp is included in the default sendmail configuration as one of the trusted users, as this grep shows:

# grep '^T' generic-linux.cf
Troot
Tdaemon
Tuucp

The confTRUSTED_USERS define does not override the trusted users list found in the default configuration—it adds to it. A grep of this recipe’s configuration file shows this:

# grep '^T' sendmail.cf
Troot
Tdaemon
Tuucp
Tbin

The confTRUSTED_USERS define identifies those users that are allowed:

  • To use sendmail’s -f command-line switch to override the sender address.

  • To use the -bi option to rebuild the aliases file.

  • To use an alternative queue directory without an X-Authentication-Warning.

  • To change the syslog label without generating a warning.

Using confTRUSTED_USERS reduces security by adding to the list of users granted a special privilege. Avoid using it except when it is required to get a mail delivery program running. We do not recommend adding bin to the trusted users list—exactly the opposite is true.

Use care when entering the confTRUSTED_USERS define. confTRUSTED_USER, without an “S” on the end, is a different security setting; see Recipe 10.13 for information about confTRUSTED_USER.

See Also

The sendmail book discusses trusted users in Section 10.8.1.1.

10.13. Identifying the sendmail Administrator

Problem

You want to avoid having administrators login as root to manage sendmail files.

Solution

Select or create a user account, other than root, that will be used to manage sendmail. Change file and directory ownership in order to give the selected account ownership of and access to all of the files necessary to maintain sendmail, without providing access to unneeded files. This can be simplified by keeping the sendmail configuration files in a limited number of directories. For example, on the sample system, operational files are kept in /etc/mail and development files are kept in /usr/local/src/sendmail-8.12.9.

Add a confTRUSTED_USER define to the sendmail configuration to identify the sendmail administrator. Here is an example using mailman as the user account name:

dnl The mail administration account is mailman
define(`confTRUSTED_USER', `mailman')

Build and install sendmail.cf, and then restart sendmail as shown in Recipe 1.8.

Discussion

The TrustedUser option identifies the user that owns sendmail’s administrative files, such as the database files. TrustedUser defaults to root. Override the default value with the confTRUSTED_USER define. For example, the confTRUSTED_USER define in Recipe 10.13.2 sets TrustedUser to mailman.

Once a TrustedUser is defined, the TrustedUser is given ownership of files that might be maintained by the sendmail administrator. On most systems, this means changing the ownership of the sendmail development directory, the /etc/mail directory, and the files inside these directories to the TrustedUser.[6]

The file permissions in the development directory are properly set by the sendmail source code tar file. The /etc/mail file permissions are more sensitive, but they should already be properly set by the vendor on any system running sendmail. If you’re not sure about the permissions set for your /etc/mail directory, see Table 10-1.

Table 10-1. Permissions for selected /etc/mail files

File

Mode

aliases

0640

aliases.db

0640

aliases.dir

0640

aliases.pag

0640

helpfile

0444

sendmail.cf

0640

statistics

0600

The permissions for the /etc/mail directory are set to 755. Database source file permissions are set to 640.[7] Database permissions are set to 640, as are permissions on the .cf files. Permission on the helpfile are set to 444. Execute permissions are not granted to anyone, on any file. sendmail files that fall outside of the /etc/mail directory—on some systems this might be /etc/sendmail.cf and /etc/aliases—should also be owned by the TrustedUser and assigned permissions similar to those used for files in the /etc/mail directory. If the m4 master configuration file contains the confCONTROL_SOCKET_NAME define, the socket file must be owned by the TrustedUser and set to mode 600. The directory containing the socket file should be owned by root or the TrustedUser and set to mode 700. The TrustedUser does not own the mail queue or the mail spool directories—those are still owned by the root user.

The root user, which is the default value for TrustedUser, is at least as secure as any other user ID. Changing the TrustedUser does not improve file security. It does, however, make it possible to maintain sendmail databases without using root privileges.

Recipe 10.11 covers the DefaultUser option. The DefaultUser executes commands, such as mailers, but does not own files. The TrustedUser owns files but does not execute commands from within sendmail. This division of labor improves security.

See Also

See Recipe 10.12 for information on confTRUSTED_USERS, with an “S”, which is a define that is sometimes confused with confTRUSTED_USER. The sendmail book covers confTRUSTED_USER in Section 10.8.2.3 and Section 24.9.112, recommended file permissions in Section 10.5.4, and the confCONTROL_SOCKET_NAME define in Section 24.9.23.

10.14. Limiting the SMTP Command Set

Problem

You want to disable certain SMTP commands.

Solution

Add the confPRIVACY_FLAGS define to the sendmail configuration to set PrivacyOptions that disable unwanted, optional SMTP commands. This sample define disables the EXPN, VRFY, VERB, and ETRN commands:

dnl Disable EXPN, VRFY, VERB and ETRN
define(`confPRIVACY_FLAGS', `noexpn,novrfy,noverb,noetrn')

Build the sendmail.cf file, copy it to /etc/mail/sendmail.cf, and restart sendmail, as described in Recipe 1.8.

Discussion

The confPRIVACY_FLAGS define sets PrivacyOptions flags in the sendmail.cf file. One of the things that these flags can do is disable unwanted, optional SMTP commands. By default, sendmail supports the full array of SMTP commands, as this simple test shows:

# sendmail -bs -Cgeneric-linux.cf
220 chef.wrotethebook.com ESMTP Sendmail 8.12.9/8.12.9; Mon, 10 Mar 2003 14:39:47 -0500
EHLO localhost
250-chef.wrotethebook.com Hello root@localhost, pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-EXPN
250-VERB
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH DIGEST-MD5 CRAM-MD5
250-DELIVERBY
250 HELP
EXPN <admin>
250-2.1.5 <[email protected]>
250-2.1.5 <[email protected]>
250 2.1.5 <[email protected]>
VRFY <alana>
250 2.1.5 Alana Henson <[email protected]>
QUIT
221 2.0.0 chef.wrotethebook.com closing connection

In response to the EHLO command, the SMTP server lists the SMTP extensions it supports, including optional commands. Some of these commands, VRFY, EXPN, and VERB, provide information that a security-conscious site might not wish to provide:

  • The VERB command places the SMTP protocol exchange into verbose mode, which provides debugging help but might also reveal information about your site that you would rather not advertise.

  • The VRFY command verifies an email address and provides additional information about the user at that address. In the example just shown, the system provides the user’s real name and the user’s full email address.

  • The EXPN command expands a mailing list and displays the email address of each member of the list, as the test above shows. Intruders and spammers might collect this information and use it against your system.

After reconfiguring sendmail with the confPRIVACY_FLAGS define shown in Recipe 10.14.2, rerunning the test produces very different results:

# sendmail -bs
220 chef.wrotethebook.com ESMTP Sendmail 8.12.9/8.12.9; Mon, 10 Mar 2003 14:47:35 -0500
EHLO localhost
250-chef.wrotethebook.com Hello root@localhost, pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-AUTH DIGEST-MD5 CRAM-MD5
250-DELIVERBY
250 HELP
EXPN <admin>
502 5.7.0 Sorry, we do not allow this operation
VRFY <alana>
252 2.5.2 Cannot VRFY user; try RCPT to attempt delivery (or try finger)
QUIT
221 2.0.0 chef.wrotethebook.com closing connection

Now the server advertises a smaller set of features, and returns errors when the EXPN and VRFY commands are entered.

In addition to the noexpn, novrfy, and noverb flags, the sample define in Recipe 10.14.2 uses the noetrn flag. In the first test, the system advertised the ETRN command. After this recipe is applied, the server no longer advertises or supports that command. ETRN is used by remote systems to cause the server to run the queue. ETRN is an important command for supporting dial-in clients that need to have the queue run while they are online. Our sample system does not support dial-in SMTP clients, so we have disabled the ETRN command to prevent remote sites from forcing the server to run the queue.

The noexpn, novrfy, and noverb flags could all have been set using the goaway flag. The goaway flag sets several flags at once. In addition to the noexpn, novrfy, and noverb flags, the goaway flag sets:

authwarnings

authwarnings tells sendmail to insert X-Authentication-Warnings: headers into the mail whenever it suspects that the message is not authentic. authwarnings is the default PrivacyOptions flag used when the sendmail.cf file is built by m4. If the system administrator directly edits the sendmail.cf file and inserts a PrivacyOptions statement that has no flags set, public becomes the default. public tells sendmail that it should not do any special security checks or SMTP syntax checks.

nobodyreturn

The nobodyreturn flag tells sendmail not to return the original message body when it bounces a message, even if the return is specifically requested with the RET=FULL DSN extension on the MAIL From: SMTP command. noreceipts is a related flag that is not used by goaway. noreceipts causes sendmail to ignore the NOTIFY=SUCCESS DSN extension of the RCPT To: command and to ignore Return-Receipt-To: headers. When noreceipts is used, sendmail does not advertise or support DSN. For this reason, goaway does not set noreceipts, and it is not recommended that you use it either. nobodyreturn only affects the RET=FULL DSN extension; the other DSN features are still available.

needmailhelo, needvrfyhelo, and needexpnhelo

These three flags cause sendmail to require a valid HELO/EHLO command from the client before accepting certain other commands. needmailhelo, needvrfyhelo, and needexpnhelo are used and discussed in Recipe 10.15.

The goaway flag does not set the noetrn flag used in this recipe, nor does it set the public and noreceipts flags described above. Additionally, it does not set the restrictexpand, restrictmailq, and restrictqrun flags. noetrn and noreceipts are not used because they disable features that are, in certain circumstances, very useful. The goaway flag does not use public because it lessens security. restrictexpand, restrictmailq, and restrictqrun are not used because those flags affect who can use certain options on the sendmail command line; they do not affect the SMTP protocol or security interactions with remote systems that are the target of the goaway flag.[8] goaway is a good choice for enhanced sendmail security. However, this recipe shows that individual flags can also be selected to create a custom security configuration.

Even more custom control is available through creating custom rulesets. The rulesets check_vrfy, check_expn, and check_etrn can be used to define custom controls for the VRFY, EXPN, and ETRN commands, respectively. This recipe disables these commands completely.

See Also

Recipe 10.15 and Recipe 10.16 provide related material. The sendmail book covers the PrivacyOptions in Section 24.9.80.

10.15. Requiring a Valid HELO

Problem

You do not want to accept mail from a host that does not first provide a HELO/EHLO command.

Solution

Require the HELO command by adding a confPRIVACY_FLAGS define to the sendmail configuration. Here is an example of the define:

dnl Don't accept mail without a HELO
define(`confPRIVACY_FLAGS', `needmailhelo')

Rebuild the configuration, copy it to /etc/mail/sendmail.cf, and restart sendmail, as shown in Recipe 1.8.

Discussion

By default, sendmail accepts incoming mail even if the remote host does not identify itself with an SMTP HELO or EHLO command, as the following test shows:

# sendmail -bs -Cgeneric-linux.cf
220 chef.wrotethebook.com ESMTP Sendmail 8.12.9/8.12.9; Mon, 10 Mar 2003 13:16:30 -0500
MAIL From:<[email protected]>
250 2.1.0 <[email protected]>... Sender ok
RCPT To:<[email protected]>
250 2.1.5 <[email protected]>... Recipient ok
QUIT
221 2.0.0 chef.wrotethebook.com closing connection

Adding the needmailhelo flag to the PrivacyOptions requires sendmail to receive a HELO or EHLO command before it will accept inbound mail. Rerunning the test with the configuration created by this recipe shows the effect of this flag:

# sendmail -bs
220 chef.wrotethebook.com ESMTP Sendmail 8.12.9/8.12.9; Mon, 10 Mar 2003 13:17:45 -0500
MAIL From:<[email protected]>
503 5.0.0 Polite people say HELO first
QUIT
221 2.0.0 chef.wrotethebook.com closing connection

Attempting to start the mail transfer without first issuing a HELO/EHLO command causes an error.

Two related PrivacyOptions flags are needvrfyhelo and needexpnhelo. With these flags the VRFY and EXPN commands, respectively, are rejected unless sendmail has received a HELO/EHLO command. needvrfyhelo and needexpnhelo provide very limited security benefits. From a security perspective, it is best just to disable EXPN and VRFY as described in Recipe 10.14.

See Also

Recipe 10.14 provides another example of using PrivacyOptions. The sendmail book covers the needmailhelo flag in Section 24.9.80.6, the needvrfyhelo flag in Section 24.9.80.7, and the needexpnhelo in Section 24.9.80.5.

10.16. Restricting Command-Line Options

Problem

You want to limit which users can run the sendmail program with the -q, -bp, -v, and -bv options.

Solution

Add the confPRIVACY_FLAGS define to the sendmail configuration. Set the restrictexpand, restrictmailq and restrictqrun flags, as in this example:

dnl Limit use of expand, mailq and qrun flags
define(`confPRIVACY_FLAGS', `restrictexpand,restrictmailq,restrictqrun')

Rebuild and install sendmail.cf, then restart sendmail as shown in Recipe 1.8.

Discussion

The PrivacyOptions flags restrictexpand, restrictmailq, and restrictqrun add to the restrictions on who can use certain sendmail command-line options. The flags and the options they affect are:

restrictexpand

The restrictexpand flag limits the -bv and -v command-line options to root and the TrustedUser. The -bv option verifies an email address. In the process, it performs aliasing on the address and displays the result. The -v option puts the sendmail program into verbose mode, which displays additional information about the delivery process. Use restrictexpand to prevent nonprivileged users from discovering information about how mail is delivered to other users on the system.

restrictmailq

When the restrictmailq flag is set, only members of the group that owns the queue directory can examine the contents of the queue by running sendmail with the -bp option or by running mailq. mailq and sendmail -bp are synonymous. Both of these commands print the contents of the queue.

restrictqrun

The queue is processed whenever the sendmail program is executed with the -q option. The restrictqrun flag tells sendmail that it should only process the queue if the sendmail -q command was run by the root user or the queue directory owner.

Most of the PrivacyOptions flags—those discussed in Recipe 10.14 and Recipe 10.15—impact how sendmail interacts with remote systems. Those flags are used by sendmail when it is run as a daemon. The three flags used in this recipe affect sendmail when it is run from the command line. Because the default for sendmail 8.12 is to no longer run sendmail as set-user-ID root, these flags are most useful with earlier versions of sendmail.

See Also

Recipe 10.14 and Recipe 10.15 provide other examples of using PrivacyOptions. The sendmail book covers restrictexpand in Section 24.9.80.13, the restrictmailq flag in Section 24.9.80.14, and restrictqrun in Section 24.9.80.15.

10.17. Denying DoS Attacks

Problem

You want to limit the possibility that a denial-of-service (DoS) attack aimed at sendmail will cripple other services offered by the sendmail server.

Solution

Add confCONNECTION_RATE_THROTTLE and confMAX_DAEMON_CHILDREN defines to the sendmail configuration to set limits on how fast sendmail accepts mail connections and how many concurrent connections are accepted. Here are examples:

dnl Accept up to 10 connections per second
define(`confCONNECTION_RATE_THROTTLE', `10')
dnl Allow no more than 200 concurrent connections
define(`confMAX_DAEMON_CHILDREN', `200')

Following the guidance in Recipe 1.8, build the sendmail.cf file, copy it to /etc/mail/sendmail.cf, and restart sendmail.

Discussion

A denial-of-service (DoS) attack can overwhelm a server and effectively block useful inbound and outbound mail. For example, a mail-bombing attack delivers so much mail so rapidly to a single target that the target system is unable to keep up with the workload. Worse yet, sendmail can becomes so busy handling the attack, it takes all of the system’s resources and thus prevents other useful services from running. This recipe uses two configuration commands that lessen the impact that a DoS attack aimed at sendmail has on its other services.

The confMAX_DAEMON_CHILDREN define sets the maximum number of sendmail processes that this sendmail daemon can run simultaneously. Every system has an upper limit on the number of processes it can effectively handle. A variety of DoS attacks are designed to overwhelm a system by launching so many mail processes that the system is no longer able to do any productive work. The confMAX_DAEMON_CHILDREN define protects the operating system from this type of attack.

By default, sendmail sets no upper limit on the number of child processes that can be launched to process mail. This recipe limits sendmail to 200 children so that sendmail accepts mail only when fewer than 200 children are running. This is not a recommended value; it is just an example. Study the actual usage patterns of your system before you select a value, and then set the value at least 50 percent above the observed value to allow for usage spikes.

confMAX_DAEMON_CHILDREN is most useful for systems that do more than just provide sendmail service. A good example is a general purpose server that has a relatively light email workload and that provides many other important user services. The confMAX_DAEMON_CHILDREN define protects the other services from runaway sendmail daemons. It makes sure that the user can still open an X window or start an editor even if the sendmail server is under attack. confMAX_DAEMON_CHILDREN provides this protection for the other services at the cost of making it simple for the attacker to shut down mail service. Simply sending enough mail to exceed the maximum number of children shuts down the SMTP port. Use this define carefully.

The confCONNECTION_RATE_THROTTLE define sets the maximum number of SMTP connections that are permitted for any one-second period. Like confMAX_DAEMON_CHILDREN, the confCONNECTION_RATE_THROTTLE command protects the server from being overwhelmed by email. Neither of these defines protects sendmail from attack; they both protect the system when sendmail is under attack.

By default, no limit is set on the rate at which new SMTP connections are accepted. sendmail handles connections as fast as they arrive. This recipe limits sendmail to 10 new connections per second so that sendmail rejects any network connections after the first 10 in any 1-second period. As before, this is not a recommended value; it is just an example. Study the actual usage patterns of your system before you select a value, and then set the value at least 50 percent above the observed value to allow for usage spikes.

Often, confCONNECTION_RATE_THROTTLE and confMAX_DAEMON_CHILDREN are used together. confMAX_DAEMON_CHILDREN sets an upper limit on the number of simultaneous email connections and confCONNECTION_RATE_THROTTLE sets the rate at which the system climbs to that maximum. An attacker can easily overrun the connection rate you set in order to deny mail access. However, setting the rate protects the other services on the system so that the system remains operational to help you deal with the attack.

It is impossible to completely protect sendmail from denial-of-service attacks. Limiting the amount of damage done by the attack is the real purpose of the defines used in this recipe, which is really meant to protect the system as a whole.

See Also

The sendmail book covers the confCONNECTION_RATE_THROTTLE define in Section 24.9.21 and the confMAX_DAEMON_CHILDREN define in Section 24.9.60.



[1] The ports used by sendmail can be changed in the configuration, but the default ports are 25 and 587.

[2] The pathnames used here are just examples. You should use the paths that are correct for your system.

[3] Using procmail as the local mailer also defeats the purpose of smrsh.

[4] Recipe 10.8 shows how to avoid using procmail as the local mailer on a Linux system.

[5] This example assumes that these are local files. If your system uses NIS or some other server for this information, make sure you check the correct source.

[6] Changing the ownership of the development directory does not change the fact that the Build install phase of installing sendmail must still be run as root.

[7] The access database requires more restrictive permission if it contains AuthInfo: entries. See Recipe 7.2.

[8] Recipe 10.16 covers the restrictexpand, restrictmailq, and restrictqrun flags.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.134.76.51