Chapter 4. Maintain Security with sendmail
When the administrator is not careful, the misuse or misconfiguration of sendmail can lead to an insecure and possibly compromised system. Since pre-V8.12 sendmail is often installed to run as a set-user-id root process, it is a prime target for intrusion.[59] The “Internet worm,” for example, used a flaw in old versions of sendmail as one way to gain entry to thousands of machines.[60] If sendmail is not properly installed, improper file permissions can be used to trick the system into giving away root privilege.
In this chapter, we present several ways to protect your site from intrusion via sendmail. Most of these are just good common sense, and the experienced system administrator might be offended that we state the obvious. But not all system administrators are experienced, and not all who administer systems are system administrators. If you fall into the latter category, you might wish to keep a good, general Unix reference by your side to better appreciate our suggestions.
Why root?
One common complaint about sendmail centers on the fact that it is often run, set-user-id root (that is, run as root no matter who actually runs it).[61] Beginning with V8.12, the default is to run sendmail as a user other than root. The listening daemon needs to be root, but sendmail itself no longer needs to be set-user-id root.
For the most part, it is necessary for sendmail to run as root to satisfy legitimate needs. Consider the following:
Users want ~/.forward files to work even when their home directory is set to mode 700. The sendmail program requires root privilege so that it can temporarily become the user to read and process the ~/.forward file.
Users want :include: mailing-list files readable only by themselves and sendmail. The sendmail program requires root privilege so that it can temporarily become the owner of the list.
Users want programs that run on their behalf to run as themselves. This requires root privileges, and running as anything else would be potentially very dangerous.
Users want sendmail to listen on TCP/IP ports that are common (ports 25 and 587). The sendmail program requires root privilege so that it can initiate listening connections to privileged ports.
Some folks have been tempted to run sendmail as an untrusted pseudouser (such as nobody). But this doesn’t really work. For example, it causes programs in users’ ~/.forward files to be run as nobody, and it requires the queue to be owned by nobody. Consequently, such a scheme allows any user to break into and modify the queue.[62]
Test seteuid and setreuid
Clearly, many of sendmail’s duties require it to run as root. As a corollary, however, whenever sendmail does not need to be root, it should become the appropriate non-privileged user. It does this by using the following bit of logic:
If it was compiled with support for seteuid(3) (USESETEUID on page 151), use that routine to set the effective uid to that of the desired non-root user. This is less preferred than the following.
If it was compiled with support for setreuid(3) (HAS... on page 114), use that routine to set the effective and real uids to those of the desired non-root user.
Otherwise, use setuid(3) to become the desired non-root user.
Note that setreuid(3) is preferred over seteuid(3)[63] and setuid(3) because it allows sendmail to temporarily give away both its real and effective root privilege, then to get it back again. To illustrate the need for this behavior, consider processing a mailing list that saves mail to two different files:
/u/bill/archive ← owned by the user bill, mode 4600 /u/alice/archive ← owned by the user alice, mode 4600
Further consider that these files both have permissions of set-user-id to the individual users[64] and are writable only by the individual users. To perform delivery in this instance, sendmail must[65] first become bill (this requires root privilege). To become another user, sendmail forks. The parent remains root and the child becomes the user, bill in our example. When it is done, the child exits. The parent sendmail remains root so that it can next become alice. By retaining a real uid of root, sendmail is able to change its effective uid to one user after another as needed.
See the description of the test directory in USESETEUID on page 151 for more on this subject.
The Environment
As a general rule, programs should never trust their environment. Such trust can lead to exploitation that has grave security consequences. To illustrate, consider the often misused SunOS LD_LIBRARY_PATH environment variable. Programs that use shared libraries look at this variable to determine which shared library routines they should use and in what order they should load them. One form of attack against non-set-user-id programs (such as some delivery agents) is to modify the LD_LIBRARY_PATH variable (as in a user’s ~/.forward file) to introduce Trojan horse library routines in place of the real system’s library routines. Certainly, sendmail should not pass such variables to its delivery agents.
To improve security, early versions of V8
sendmail began deleting
variables from its environment before passing them to its
delivery agents. It removed the IFS variable to protect
Bourne shell-script agents and all variables beginning with
“LD_" to protect
all delivery agents from shared library attacks.
Beginning with V8.7, sendmail now takes
the opposite approach. Instead of trying to second-guess
attackers, it constructs the delivery agent environment from
scratch. In this scheme, it defines the AGENT variable as
sendmail, and the
TZ variable as is appropriate (see the TimeZoneSpec option, TimeZoneSpec on page 1110). Also, in
support of operating systems that require them, it passes
the ISP and SYSTYPE variables from its own environment to
the delivery agent’s environment.
The E Configuration Command
When sendmail executes (runs) a
delivery agent (The Child on page
757), it passes to that delivery agent an
environment that includes only the items described
earlier. Some delivery agents, however, might
require additional environment variables to function
properly. For those special cases,
sendmail offers the E configuration command
to set individual environment variables that will be
passed to all delivery agents:
Evar=valueThe var is the environment
variable that will be either defined or redefined.
It is immediately followed (with no intervening
space) by an equal-sign and then (again with no
intervening space) by the
value that will be
assigned to it.
If the =value is
missing, sendmail looks up the
variable var in its
environment and, if it is found, uses that value. If
the = is present
but the value is absent,
the var is assigned an
empty string (a single zero byte). If the
var is missing, a
variable name that is an empty string is
used.
The var is looked up to see
whether it is already a part of the delivery agent’s
environment. If it is, it is redefined to be the new
value. If it is not, it is added to that list of
variables. If that addition will cause the list to
exceed MAXUSERENVIRON variables (currently defined
as 100 in conf.h, MAX... on page 120), the definition is
silently ignored.
Whether or not the var was
added to, or updated in, the delivery agent’s
environment, it is always added or updated to
sendmail’s environment with
putenv(2). If this call
fails, sendmail logs and prints
the following message:
setuserenv: putenv(var=value) failedOnly one var can be defined
per E command.
Additional environment variables require multiple
E commands.
Each E command
affects all delivery agents. There is no way to tune
the environment on a per-delivery-agent
basis.
SMTP Probes
Although SMTP probes can be legitimate uses of the network, they can also pose potential risks. They are sometimes used to see whether a bug remains unfixed. Sometimes they are used to try to gather user login names or to feed a program unexpected input in such a way that it breaks and gives away root privilege.
SMTP Debug
An “unfixed bug” probe can use the SMTP debug and showq commands. The SMTP
debug command
allows the local sendmail to be
placed into debugging mode (as with the -d command-line switch,
The Syntax of -d on page 530)
from any other machine anywhere on the network. The
SMTP showq
command allows outsiders to view the contents of the
mail queue.
If SMTPDEBUG (SMTPDEBUG on page 144) is defined when sendmail is compiled, the SMTP debug and showq commands are allowed to work; otherwise, they are disabled. SMTPDEBUG should be defined only when modifying the sendmail code and testing a new version. It should never be defined in an official release of sendmail. To see whether it has been defined at your site, run the following command:
%telnet localhost 25Trying 123.45.6.7 ... Connected to localhost. Escape character is '^]'. 220 localhost sendmail 8.12 ready at Fri, 13 Dec 2002 06:36:12 −0800debug500 Command unrecognizedquit221 localhost.us.edu closing connection Connection closed by foreign host. %
When connected, enter the command debug. If you get the
answer 500 Command
unrecognized, you know that SMTPDEBUG is
not enabled. If, on the other hand, you get the
answer 200 Debug
set, SMTPDEBUG is defined on your
system, and you should immediately take steps to
correct the situation. Either contact your vendor
and request a new version of
sendmail, or get the
sendmail source and compile
it with SMTPDEBUG undefined.
When SMTPDEBUG is undefined and an outsider connects
to the local machine and attempts to execute the
debug or
showq command,
sendmail will
syslog(3) a message such as
the following:
Jul 22 07:09:00 here.domain sendmail[192]: "debug" command from there.domain
(123.45.67.89)This message shows the name of the machine that
attempts the probe, or
there.domain, and the IP
address of that machine. Note that this message is
logged only if the LogLevel option (LogLevel on page 1040) is
nonzero.
SMTP VRFY and EXPN
You might be dismayed to learn that the login names of ordinary users can be used to break into a system. It is not, for example, all that unusual for a user to select a password that is simply a copy of his login name, first name, last name, or some combination of initials. A risk of attack can arise from outsiders guessing login names. Any that they find can be used to try to break in, and the SMTP VRFY gives an attacker the means to discover login names.
Login names are also a way to gather addresses for spam email messages. The SMTP VRFY command, too, can be used to collect names for that illicit use.
The SMTP VRFY command causes sendmail to verify that it will accept an address for delivery. If a user’s login name is given, the full name and login name are printed:
vrfy george
250 George Washington <george@wash.dc.gov>Here, the 250 SMTP reply code (see RFC821) means a successful verification.[66] If the user is unknown, however, sendmail says so:
vrfy foo
550 5.7.1 foo... User unknownThe SMTP EXPN command is similar to the VRFY command, except that in the case of a mailing list, an aliases, or a ~/.forward file entry, it will show all the members. The SMTP EXPN command causes sendmail to expand (show all the recipients) of an address. To illustrate the risk, consider that many sites have aliases that include all or a large segment of users. Such aliases often have easily guessed names, such as all, everyone, or staff. A probe of all, for example, might produce something such as the following:
expn all
250-George Washington <george@wash.dc.gov>
250-Thomas Jefferson <tj@wash.dc.gov>
250-Ben Franklin <ben@here.us.edu>
250-Betsy Ross <msflag@ora.com>
250 John Q. Public <jqp@aol.com>With well-designed passwords these full and login
names can safely be given to the world at large. But
if one user (say, jqp) has a poorly designed password
(such as jqpublic), your site’s
security can easily be compromised.[67] Note that not all uses of VRFY or EXPN
represent probes. Some MUAs,[68] for example, routinely VRFY each
recipient before sending a message.
SMTP VRFY and EXPN commands are individually logged in a form such as one of the following:
Sep 22 11:40:43 yourhost sendmail[pid]: other.host: vrfy all Sep 22 11:40:43 yourhost sendmail[pid]: [222.33.44.55]: vrfy all Sep 22 11:40:43 yourhost sendmail[pid]: other.host: expn all Sep 22 11:40:43 yourhost sendmail[pid]: [222.33.44.55]: expn all
This shows that someone from the outside (other.host in the first
and third examples) attempted to probe for usernames
in the mailing list named all. In the second and last examples,
the probing hostname could not be found, so the IP
address is printed instead (in the square brackets).
Note that this form of logging is enabled only if
the LogLevel
option (LogLevel on page 1040) is
greater than 5.
Pre-V8 versions of sendmail do not report SMTP VRFY or EXPN attempts at all. Some versions of sendmail (such as the HP-UX version) appear to verify but really only echo the address stated.
V8 sendmail allows VRFY and EXPN
services to be accepted or rejected on the basis of
the setting of the PrivacyOptions option (PrivacyOptions on page 1065). For
improved security, we recommend this setting for the
PrivacyOptions
option:
O PrivacyOptions=novrfy,noexpn
V8.10 and above sendmail allow
VRFY and EXPN services to be selectively accepted or
rejected on the basis of rules in the check_vrfy (check_vrfy and check_expn on page 707)
and check_expn
(check_vrfy and check_expn on
page 707) rule sets. If, for example, you wish to
allow VRFY from internal hosts, but wish to deny it
for all outside hosts, you can do so by omitting a
definition of the PrivacyOptions option as explained
earlier, and by designing appropriate rules for the
check_vrfy rule
set.
The Configuration File
A number of security problems can be created by commands given
carelessly in the configuration file. Such problems can be
serious because sendmail starts to run
as root, provided that it has not been
given an unsafe command-line switch (such as -C; see -C on page 238) or an unsafe option (Options That Are Safe on page 951). It
can continue as root until it delivers
mail, whereupon it generally changes its identity to that of
an ordinary user. When sendmail reads
its configuration file, it can do so while it is still
root. Consequently, as we will
illustrate, when sendmail is improperly
configured, it might be able to read and overwrite any
file.
The F Command—File Form
The file form of the F configuration command (The F Class Command on page 857) can
be used to read sensitive information. That command
looks like this in the configuration file:
FX/path patThis form is used to read class macro entries from
files. It can cause problems through a
misunderstanding of the
scanf(3) pattern
pat. The
/path is the name of
the file, and the optional
pat is a pattern to be
used by scanf(3) (scanf(3) variations on page 858).
To illustrate the risk of the
pat, consider the
following configuration file entry:
Fw/etc/myhostnames %[^#]
Normally, the F
command reads only the first whitespace-delimited
word from each line of the file. But if the optional
pattern pat is specified,
the F command
instead reads one or more words from each line based
on the nature of the pattern. The pattern is used by
scanf(3) to extract words,
and the specific pattern used here, [^#], causes
scanf(3) to read everything
up to the first comment character (the #) from each line. This
pat allows multiple
hostnames to be conveniently listed on each line of
the file. Now assume that a new administrator, who
is not very familiar with
sendmail, decides to add an
F command to
gather a list of UUCP hosts from the
/etc/uucp/Systems file. Being
a novice, the new administrator copies the existing
entry for use with the new file:
FU/etc/uucp/Systems %[^#]
This is the same pattern that was correctly used for /etc/myhostnames. Unfortunately, the Systems file contains more than just host entries on each line:
linda Any ACU 2400 5551212 "" \d\n in:-\r-in: Uourhost word: MublyPeg hoby Any ACU 2400 5551213 "" \d\n in:-\r-in: Uourhost word: FuMzz3.x
A part of each line (the last item in each) contains
nonencrypted passwords. Prior to V8.12, an
unscrupulous user, noticing the mistaken [^#] in the
configuration file, could run
sendmail with a -d36.5 debugging switch
and watch each password being processed. For
example:
%/usr/lib/sendmail -d36.5 -bt < /dev/null← ...some output deleted STAB: hoby 1 entered STAB: Any 1 entered STAB: ACU 1 entered STAB: 2400 1 entered STAB: 5551213 1 entered STAB: "" 1 type 1 val 0 0 200000 0 STAB: \d\n 1 entered STAB: in:-\r-in: 1 entered STAB: Uourhost 1 entered STAB: word: 1 enteredSTAB: FuMzz3.x 1 entered← note STAB: local 3 type 3 val 34d00 0 0 0 STAB: prog 3 type 3 val 34d80 0 0 0
Note the third line from the bottom, where the
password for the UUCP login into the host hoby is printed. Also
note that this is no longer possible with V8.12 and
above if sendmail is installed
as non-set-user-id as
recommended.
This example illustrates two rules about handling the configuration file:
Avoid using the
Fcommand to read a file that is not already publicly readable. To do so can reveal sensitive information. Even if the scanf(3) option is correct, a core dump[69] can be examined for sensitive information from otherwise secured files.Avoid adding a new command to the configuration file by blindly copying and modifying another. Try to learn the rules governing the command first.
The F Command—Program Form
Another form of the F (File) configuration command is the
program form, which looks like this:
FX|/pathHere, the | prefix
to the /path tells
sendmail that
/path is the name of a
program to run. The output produced by the program
is appended to the class, here
X.
To illustrate another potential security risk, consider a configuration file that is group-writable, perhaps by a few administrators who share the job of postmaster. To break into root, the attacker needs to assume the identity of only one of those users and, under that identity, edit the configuration file. Consider the following bogus entry added by an attacker to that configuration file:
FX|/tmp/.sh
Consider further a change to the DefaultUser option
(DefaultUser on page 1000) that
causes the default uid and
gid to become those of
root:
O DefaultUser=0:0
With these changes in place, the program (actually a
shell script) called /tmp/.sh
is run by sendmail to fill the
class X with new
values. All this seems harmless enough, but suppose
/tmp/.sh does the
unexpected:
#!/bin/sh cp /bin/sh /tmp/.shell chmod u+s /tmp/.shell
Here, the Bourne shell is copied to /tmp/.shell, and the set-user-id root bit is set. Now, any user at all can run sendmail and become root:
%ls -l /tmp/.shell/tmp/.shell not found %/usr/lib/sendmail -bt < /dev/null%ls -l /tmp/.shell-rwsr-xr-x 1 root 122880 Sep 24 13:20 /tmp/.shell
The program form of the F configuration command can clearly be
dangerous. The sendmail
configuration file must never
be writable by anyone other than
root. It should also live in
a directory, every path component of which is owned
by and writable only by root.
(We’ll discuss this latter point in greater detail
soon.) If the configuration file is created with the
m4 technique, care must be
taken to ensure that only root
can write to the mc file, and
that only root can use that
mc file to install the
configuration file.
The P= of Delivery Agents
Just as the program form of the F command can pose a
security risk if the configuration file is poorly
protected, so can the M delivery agent definition.
Specifically, the P= equate for a delivery agent (P= on page 748) can be modified
to run a bogus program that gives away
root privilege. Consider the
following modification to the local delivery
agent:
Mlocal, P=/bin/mail, F=rlsDFMmnP, S=10, R=20, A=mail -d $u
↓
becomes
↓
Mlocal, P=/tmp/mail, U=0,F=SrlsDFMmnP, S=10, R=20, A=mail -d $u
↑ ↑
note noteHere, local mail should be delivered with the
/bin/mail program, but
instead it is delivered with a bogus frontend,
/tmp/mail. If
/tmp/mail is carefully
crafted, users will never notice that the mail has
been diverted. The S flag in the F= equate (F=S on page 780) causes
sendmail to retain its
default identity when executing the bogus
/tmp/mail. The U=0 equate (U= on page 755) causes that
default to become the identity of
root.
Delivery agent P=
equates must be protected by protecting the
configuration file. As an additional precaution,
never use relative pathnames
in the P=
equate.
The F=S and
U=0 are
especially dangerous. They should never appear in
your configuration file unless you have deliberately
placed them there and are 100% certain of their
effect. For example, the local_lmtp feature (FEATURE(local_lmtp) on page 625) correctly sets them for the local delivery agent
because the mail.local program
is no longer set-user-id
root.
StatusFile Option and the Statistics File
When sendmail attempts to record
its delivery agent statistics (The statistics File on page 365), it
checks for the existence and write permissions of
the file specified by the StatusFile option (StatusFile on page 1095). Prior to
V8.9, sendmail did not care
where that file lived or what permissions it
had—only that it existed.
A security problem could arise if one is tempted to locate the statistics file in a spool or temporary area. Consider the following location, for example:
define(`STATUS_FILE',`/usr/tmp/statistics')
Here, the administrator sets the StatusFile option to
locate the statistics file in the
/usr/tmp directory. The
intention is that the file can be easily created by
anyone who wishes to gather statistics, then
removed. Unfortunately, the
/usr/tmp directory is usually
world-writable.
Thus, prior to V8.9, any unhappy or malicious user could bring the system to its knees:
%cd /usr/tmp%ln -s /vmunix statistics
Here, sendmail clobbers the disk
copy of the kernel. Nothing bad might happen at
first,[70] but the machine will require manual
intervention to boot in the future.[71] Clearly, precautions must be taken. For
example, any file that sendmail
writes to (such as the StatusFile option statistics file or
the aliases database files)
must be writable only by root
and live in a directory, every path component of
which is writable only by
root.
Permissions
One technique that attackers use to gain root privilege is to first become a semiprivileged user such as bin or sys. Such semiprivileged users often own the directories in which root-owned files live. For example, consider the following:
drwxr-sr-x 11 bin 2560 Sep 22 18:18 /etc/mail -rw-r--r-- 1 root 8199 Aug 25 07:54 /etc/mail/sendmail.cf
Here, the /etc/sendmail.cf configuration file is correctly writable only by root. But the directory in which that file lives is owned by bin and writable by bin. Having write permission on that directory means that bin can rename and create files. An individual who gains bin permission on this machine can create a bogus sendmail.cf file by issuing only two simple commands:
%mv /etc/mail/sendmail.cf /etc/mail/...%mv /tmp/sendmail.cf /etc/mail/sendmail.cf
The original sendmail.cf is renamed
... (a name that
is not likely to be randomly noticed by the real system
administrator). The bogus
/tmp/sendmail.cf then replaces
the original:
drwxr-sr-x 11 bin 2560 Sep 22 18:18 /etc/mail -rw-r--r-- 1 bin 4032 Nov 16 00:32 /etc/mail/sendmail.cf
Unix pays less attention to semiprivileged users than it does root. The user root, for example, is mapped to nobody over NFS, whereas the user bin remains bin. Consequently, the following rules must be observed to prevent malicious access to root-owned files:
All directories in the path leading to a root-owned file must be owned by root and writable only by root. This is true for all files, not just sendmail files.
Files owned by root must be writable only by root. Group write permission, although at times desirable, should consistently be avoided.
Because sendmail is running as root when processing the configuration file, care should be taken to ensure the safety of system files as well. All system directories and files must live in directories whose path component parts are owned by and writable only by root. All system files (except possibly set-user-id or set-group-id files) must be owned by root and be writable only by root. If any program “breaks” after securing permissions, complain to your vendor at once!
Dangerous Write Permissions
The sendmail program, of necessity, needs to trust its configuration file. To aid in the detection of risks, it checks the permissions of its configuration file when first reading that file. If the file is writable by group or world, sendmail logs the following message:[72]
configfile: WARNING: dangerous write permissions
If sendmail is being started as a daemon or is being used to initialize the aliases database, it will print the same message to its standard error output.
Permissions for :include:
The sendmail program doesn’t
always run as root. When
delivering mail, it often changes its identity into
that of a nonprivileged user. When delivering to an
:include:
mailing list, for example, it can change its
identity to that of the owner of the list. This,
too, can pose security risks if permissions are not
appropriate.[73] Consider the following
aliases file entry:
newprogs: :include:/usr/local/lists/proglist
Here, notification of new programs is mailed to the
alias newprogs.
The list of recipients is taken from the following
file:
-rw-rw-r— 2 bin prog 704 Sep 21 14:46 /usr/local/lists/proglist
Because this file is owned by bin, sendmail changes its identity to bin when delivering to the list of recipients. Unfortunately, the file is also writable by the group prog. Anyone in the group prog can add a recipient to that list, including one of the form:
|/tmp/x.sh
This tells sendmail to deliver a copy of the message by running the program (a shell script) /tmp/x.sh. The sendmail program (which is still running as bin) executes that program as bin. Further, suppose the program /tmp/x.sh contains the following:
#!/bin/sh cp /bin/sh /tmp/sh chmod u+s /tmp/sh cat - > /dev/null exit 0
This causes bin first to make a
copy of the Bourne shell in
/tmp (a copy that will be
owned by bin), and then to set
the set-user-id bit on that
copy (the u+s):
-rwsr-xr-x 1 bin 64668 Sep 22 07:38 /tmp/sh
The script then throws away the incoming mail message and exits with a zero value to keep sendmail unsuspecting. Through this process, an ordinary user in the group prog has created a set-user-id shell that allows anyone to become the semiprivileged user bin. From the earlier discussion (Permissions on page 164), you can see the trouble that can cause!
Mailing lists (:include:) must live in a directory,
all the components of which are writable only by
root. The lists themselves
should be writable only by the owner.
Mailing list (:include:) files can safely be owned by
root. When
sendmail processes a
root-owned mailing list, it
changes itself to run as the user and group
specified by the DefaultUser option (DefaultUser on page 1000). That option
defaults to daemon[74] but should be set to the
mailnull user and
mailnull group. The DefaultUser option
should never be set to
root.
Permissions for ~/.forward Files
The ~/.forward file can pose a
security risk to individual users. There is a higher
degree of risk if the user is
root or one of the
semiprivileged users (such as
bin). Because the
~/.forward file is like an
individual mailing list (:include:) for the user, risk can be
encountered if that file is writable by anyone but
the user.[75] Consider the following, for
example:
drwxr-xr-x 50 george guest 3072 Sep 27 09:19 /home/george/ -rw-rw-r— 1 george guest 62 Sep 17 09:49 /home/george/.forward
Here, the user george’s
~/.forward file is writable
by the group guest. Anyone in group guest can edit
george’s
~/.forward file, possibly
placing something such as this into it:
\george |"cp /bin/sh /home/george/.x; chmod u+s /home/george/.x"
Now all the attacker has to do is send george mail to create a set-user-id george shell. Then, by executing /home/george/.x, the attacker becomes george.
The semiprivileged users such as bin, and root in particular, should never have ~/.forward files. Instead, they should forward their mail by means of the aliases file directly.
User ~/.forward files must be writable only by the owning user. Similarly, user home directories must live in a directory that is owned and writable only by root, and must themselves be owned and writable only by the user.
Some users, such as the pseudouser uucp, have home directories that must be world-writable for software to work properly. If that software is not needed (if a machine, for example, doesn’t run UUCP software), that home directory should be removed. If the directory must exist and must be world-writable, to ensure that the ~/.forward file is never processed you can create an alias in the aliases database for uucp that points to root. For example:
uucp: root
Thereafter, although the ~uucp directory is world-writable (so that anyone can remove anything from it), that file will be ignored by sendmail, even if someone places a ~/.forward file in it.
Note that all critical dot files in a world-writable
home directory must be protected from creation by
others. Each of .rhosts,
.login,
.cshrc,
.profile, and
.logout, for example, should
be made a nonempty, root-owned
directory with mode 000. World-writable home
directories must be owned by
root instead of by the user,
and they must have the +t (sticky bit) set.
When processing a user’s ~/.forward file, sendmail requires that the file be owned by the user or by root. If ownership is correct, it then examines the ~/.forward file’s permissions. If that file is world- or group-writable, sendmail ignores (and logs) attempts to run programs and to write directly to files.
Recommended Permissions
Table 4-1 shows the recommended ownerships and permissions for all the files and directories in the sendmail system. The path components will vary depending on the vendor version of sendmail you are running. For example, where we show the /usr/sbin/sendmail directory, your site might use /usr/lib/sendmail, or even /usr/lib/mail/sendmail.
In Table 4-1, we show the owner as root,
or as a T (which
means the owner can be the user listed with the
TrustedUser
option; TrustedUser on page 1112),
or as an R (which
means the owner must be the one specified by the
RunAsUser
option; RunAsUser on page 1083) if
that option was specified. Under the “Owner” column,
we show a colon and the group when the group is
important.
|
Path |
Type |
Owner |
Mode | |
|
/ |
Directory |
root |
0755 |
|
|
/usr |
Directory |
root |
0755 |
|
|
/usr/sbin[a] |
Directory |
root |
0755 |
|
|
/usr/sbin/sendmail |
File |
root:smmsp |
02555 |
|
|
/etc |
Directory |
root |
0755 |
|
|
/etc/mail |
Directory |
root,T |
0755 |
|
|
/etc/mail/sendmail.cf |
File |
root,T |
0644 or 0640 | |
|
/etc/mail/statistics |
File |
root,T,R |
0600 |
|
|
/etc/mail/helpfile |
File |
root,T |
0444 |
|
|
/etc/mail/aliases |
File |
root,T |
0644 |
|
|
/etc/mail/aliases.pag |
File |
root,T,R |
0640 |
|
|
/etc/mail/aliases.dir |
File |
root,T,R |
0640 |
|
|
/etc/mail/aliases.db |
File |
root,T,R |
0640 |
|
|
F/path |
Directory |
root,T |
0755 |
|
|
/path/file |
File |
T |
0444 or 0644 | |
|
/var |
Directory |
root |
0755 |
|
|
/var/spool |
Directory |
root |
0755 |
|
|
/var/spool/mqueue |
Directory |
root,R |
0700[c] |
|
|
/var/spool/clientmqueue |
Directory |
smmsp:smmsp |
0770 |
|
|
:include:/path |
Directories |
root |
0755 |
|
|
:include:/path/list |
File |
n/a |
0644 |
|
[a] a The sendmail program sometimes lives in /usr/lib or in some other directory. If so, adjust this path accordingly. [b] b As of V8.12, sendmail is no longer set-user-id root, but is instead set-group-id smmsp or the like, and sendmail is root only when it is run by root. The older versions of sendmail might need to be set-group-id kmem for the load average to be checked on some systems. [c] c CERT (the Computing Emergency Response Team) and the sendmail document doc/op/op.me recommend that the queue directories be mode 0700 to prevent potential security breaches. | ||||
Don’t Blame sendmail
In DontBlameSendmail on page 1009,
we describe the DontBlameSendmail option, which can be
used to allow looser permissions. We mention this
option here because its misuse can lead to a
weakening of security.
Consider a site where you use group permissions to
allow system administrators to edit :include: files, rather
than allowing them to do so by becoming
root. Note that these mailing
lists include archive files—that is, entries that
append messages to archive files.
Unless you tell sendmail
otherwise, it will refuse to run programs listed in
such group-writable :include: files, and also refuse to
append to any files listed in such :include: files (append
to archive files). Every time mail is sent to such a
mailing list, sendmail will log
the following warning:
/path: group writable :include: file, marked unsafeYou can prevent this warning and allow running of
disallowed programs and appending to disallowed
files by declaring the DontBlameSendmail option in your
mc configuration file:
define(`confDONT_BLAME_SENDMAIL', `GroupWritableIncludeFileSafe')
This declaration tells sendmail
that you consider it safe to append to archive files
from inside :include: files, even when the :include: file is
group-writable. The result is that you have
streamlined your department’s operation, but you
have done so at the price of security.
The sendmail program is paranoid
about group-writable permissions because such
permissions open the door to intrusion by insiders.
Group permissions are managed via the
passwd and
group files, and :include: files can be
silently edited with no record made about what was
done to them. Contrast this approach to one that
uses sudo(8) or a similar
program, to manage access to
root and other privileges.
The sudo(8) program executes
programs (such as an editor to edit an :include: file) with
special permissions (such as
root) and logs a record of
each command executed.
It is vastly better to keep
sendmail’s file permissions
narrow and to use other security tools to manage
those files. We recommend you never use the DontBlameSendmail option
to loosen permissions. If you think you need to do
so, you should review your overall approach. Try to
find a safe way to satisfy your needs, rather than
loosening sendmail’s security
behavior.
The aliases File
The aliases file can easily be used to
gain privileged (but not root) status
if it is wrongly or carelessly administered. In addition to
proper permissions and ownership, you should be aware of
potentially harmful entries that you might have inherited
from the vendor or previous administrators. For example,
many vendors used to ship systems with a decode alias in the
aliases file (this practice is
becoming less common):
# you might wish to comment this out for security decode: |/usr/bin/uudecode
The intention is to provide an easy way for users to transfer
binary files using mail. At the sending site, the user
converts the binary to ASCII with
uuencode(1), and then mails the
result to the decode
alias at the receiving site. That alias pipes the mail
message through the /usr/bin/uudecode
program, which converts the ASCII back into the original
binary file.
The uudecode(1) program takes the name of
the file to create from the file it is decoding. That
information is in the begin line, used by
uudecode. For example, here’s
an attempt to use uudecode(1) to place
a bogus queue file directly into the
sendmail queue:
begin 777 /var/spool/mqueue/qfl0NFMs3g016812
Here, the begin tells
uudecode to begin conversion.
The 777 is the
permissions to give to the file that will be created. That
is followed by the full pathname of the file. If the queue
directory were wrongly owned by daemon,
any outsider could create a bogus queued message at your
site.
Some versions of uudecode (such as the
one with SunOS) will create set-user-id
files. That is, a begin
line such as the following can be used to create a
set-user-id daemon shell in
/tmp:
begin 4777 /tmp/sh
The decode alias should be
removed from all aliases files.
Similarly, every alias that executes a program—that you did
not place there yourself and check completely—should be
questioned and probably removed.
The Alias Database Files
The aliases(5) file is often stored in dbm(3) or db(3) database format for faster lookups. The database files live in the same directory as the aliases file. For all versions of sendmail they are called aliases.dir and aliases.pag for dbm(3), but for V8 sendmail, only a single database file might exist and be called aliases.db for db(3).
It is useless to protect the aliases(5) file if you do not protect its corresponding database files. If the database files are not protected, the attacker can create a private aliases file and then run:
% /usr/lib/sendmail -oA./aliases -biThis causes sendmail to build ./aliases database files in the current directory. The attacker then copies those bogus database files over the unprotected system originals. The sendmail program never detects the change because the database files appear to be newer than the aliases file.
Note, for best security, that the aliases file and its database files must be owned by root, and be writable only by root. They must live in a directory, every path component of which is owned by and writable only by root.
Forged Mail
Although most users are aware that paper mail can be forged, many are blissfully unaware that email can also be forged. Forged mail can lead to a serious breach of security. Two points of vulnerability that require particular attention are the queue file and the SMTP interface of sendmail.
Forging with the Queue Directory
All versions of sendmail trust the files in the mail queue. They assume that only sendmail has placed files there. As a consequence, a poorly protected queue directory can allow the attacker to create mail that looks 100% authentic. This can be used to send forged mail, to append to system-critical files, or to run arbitrary programs as root or other users. Consider the following bogus qfl0NFMs3g016812 file for sending forged mail (qf files are described in The qf File Internals on page 445):
V8 T829313834 N0 P943442 Fs $_root@yourhost S<root@yourhost> RPFD:george@yourhost H?P?return-path: <root@yourhost> Hmessage-id: <200712141257.l0NFSKNK016837@yourhost> HFrom: root@yourhost HDate: Thu, 14 Dec 2007 05:47:46 −0800 HTo: george@yourhost HSubject: Change your Password Now!!
This qf file causes
mail to be sent to george that
appears in all ways to come from
root. There is nothing in
this qf file to
indicate to the recipient (or to
sendmail) that the message is
not authentic. Now further suppose that the df file (the message
body) contains the following text:
The system has been compromised. Change your password NOW!
Your new password must be:
Fuzz7bal
Thank you,
—System AdministrationUnfortunately, in any large organization there will be more than a few users who will obey a message such as this. They will gladly change their password to one assigned to them, thereby providing the attacker with easy access to their accounts.
The queue directory must be owned by and writable only
by root or the user defined by
the RunAsUser
option (RunAsUser on page 1083).
CERT recommends that the queue directory always be
mode 0700.
The MSP queue of V8.12 and above (typically /var/spool/clientmqueue) must be owned by smmsp, with group smmsp, and should be mode 0770.
The queue files placed into the queue by
sendmail must be well
protected by defining narrow default permissions
with the TempFileMode option (TempFileMode on page 1097) prior to
V8.12, or the QueueFileMode option (QueueFileMode on page 1071) beginning
with V8.12. A default of 0600 is best for the main
queue, and a default of 0660 is recommended for the
MSP queue.
Forging with SMTP
We won’t illustrate the SMTP interaction here. But
note that anyone can connect to your local
sendmail via
telnet(1) at port 25 or run
sendmail with the -bs command-line switch.
Once connected, sendmail must,
of necessity, believe everything it receives. The
only exception is the hostname sent in the HELO or
EHLO message.[76] In that case, the
sendmail program looks up the
real hostname based on the connection. If the stated
hostname and the real hostname differ, the false
name is used as the name of the sending host with
the real name added in parentheses:
250 your.host Hello false.host (real.host), pleased to meet you
The real hostname is then used as the sending hostname in the construction of all headers. The result (the header and body received by the user) might look something like this:
From root@false.host Dec 14 14:36:40 2007
Received: from false.host (real.host [real.IP.address]) by your.host (8.14.1/8.14.1)
id AA00998; Thu, 14 Dec 2007 14:36:38 −0700
Message-Id: <200712141257.l0NFSKNK016837@yourhost>
From: root@false.host (System Administration)
To: you@your.host
Subject: Change your password now!
Date: Thu, 14 Dec 2007 05:47:46 −0800
To improve security at our location you are requested to immediately
change your password. The password you have been assigned is:
7Fuzzy1's
Thank you,
--rootFortunately, this Received: header contains the name of
the real host (which is not always the case). An
attentive user can tell that this is a forged
message because the host in that header line differs
from the false hostname used in the other header
lines.
However, most mail-reading programs allow users to
filter out (prevent your seeing) uninteresting
header lines.[77] Typically, users choose to ignore
headers such as Received: and Message-ID:. For such users, the task
of detecting forged mail is much more difficult.
Instead of seeing the earlier message with real
hostnames, they might see the following with only
false names:
From root@false.host Dec 14 14:36:40 2007
From: root@false.host (System Administration)
To: you@your.host
Subject: Change your password now!
Date: Thu, 14 Dec 2007 14:36:38 −0800
To improve security at our location you are requested to immediately
change your password. The password you have been assigned is:
7Fuzzy1's
Thank you,
—rootClearly, a user who sees only this much of the mail message will be more likely to believe that it is real. There are several ways you can educate your users that mail can be forged:
Teach users what to look for when they receive a message of questionable authenticity.
Rarely, if ever, send mail as root. Always communicate as yourself and always use a distinctive style of writing. If users never see mail from root, they will be more likely to question such mail when it arrives. Even if the forger pretends to be you, that forger will likely not be in a position to imitate your distinctive writing style.
Train users to never send (or ask to receive) clear-text passwords or other security-related information by email.
Train users to use digital signatures, such as PGP or S/MIME, to authenticate email contents.
Security Features
We now turn our attention from security problems to security features. Many security features are discussed in the various README files supplied with the sendmail source distribution. In this section, we discuss the most common security features:
The
Tconfiguration command (classt) defines which users are allowed to use the-fcommand-line switch to override the sender address with one of their own, and which users are allowed to rebuild the aliases database.The smrsh program replaces /bin/sh as the program run by the
progdelivery agent to execute programs. The smrsh program is simple yet immensely valuable. We recommend that it be routinely installed on all your machines. The smrsh program is described in detail in The smrsh Program on page 379.Several options can be used to tighten security and to provide reports of security violations.
The /etc/shells file prevents ordinary users from running programs on your mail server.
Trusted Users
Under pre-V8 sendmail, trusted
users are those who are allowed to use the -f command-line switch
(-f on page 241) to override
the sender address with one of their own. V8.1
sendmail eliminated this
configuration command. V8.7 restored it, but as a
class, and uses that class only to suppress warning
headers. V8.11 and above allow only users in that
class to rebuild the aliases
database.
Trusted users are necessary for certain kinds of mail
to flow properly. For example, the
rmail(8) program of the UUCP
suite of programs runs
set-user-id to
uucp. If
rmail were not to use the
-f command-line
switch, all mail from UUCP would wrongly appear to
come from the uucp user. To
circumvent this problem, rmail
runs sendmail as:
/usr/lib/sendmail -f reallyfromThis tells sendmail to show, in both the header and envelope, the message as being from reallyfrom, rather than from uucp.
The concept of a trusted user is intended to prevent ordinary users from changing the sender address and thereby forging mail. Although that intention is laudable and good for UUCP, it can cause problems with mailing lists. Consider the following:
list: "|/usr/lib/sendmail -oi -flist-request -odi list-real" list-real: :include:/export/share/mail-lists/list.list
The intention here is for all mail sent to the mailing
list named list
to be dispatched as though it were sent from the
address list-request (the -f). This causes errors
to be returned to the maintainer of the list (the
list-request),
but replies still go to the real sender.
Unfortunately, this scheme fails when mail is posted
to list from the
local machine. Recall that only trusted users can
change the identity of the sender with -f. This is why V8.1
sendmail eliminated the
concept of the trusted user (anyone could use the
-f
switch).
Declare trusted users (ignored V8.1 through V8.6)
Trusted users are defined by those lines in
the sendmail.cf file that
begin with the uppercase letter T. Only trusted users
can use the sendmail
program’s -f
command-line switch to specify who sent the
message. Beginning with V8.7
sendmail, the class t can also be
used.
The T
sendmail.cf command must
begin a line. One or more space-delimited
usernames then follow on that same line. There can
be multiple T
commands in a sendmail.cf
file, each adding names to
the list of trusted users. Prior to V8 there could
be, at most, MAXTRUST trusted users, where MAXTRUST was defined in
conf.h when you compiled
sendmail. Beginning with
V8.7, there is no limit:
T uucp ← legal in V8.1 through V8.6 but ignored Troot daemon ← legal in V8.1 through V8.6 but ignored Ct uucp ← ignored pre-V8.7 Ctroot daemon ← ignored pre-V8.7 define(`confTRUSTED_USERS',`root daemon') ← V8.7 and above in mc file
The two T
commands show that there might optionally be
whitespace between the T and the first name in any list of
names. They indicate that
uucp,
root, and
daemon are trusted and have
been added to the list of trusted users in that
order. The two class declarations show a similar
declaration for use beginning with V8.7
sendmail (but note that V8.7
and above can still use the old syntax).
Prior to V8 sendmail, if
you listed more than MAXTRUST trusted users,
sendmail printed and
syslog(3)'ed a message such
as this:
sendmail: too many T lines, 32 max
This message was not fatal. The
sendmail program issued it
for each excess T line (ignored those trusted users)
and continued to run. V8
sendmail has implemented
trusted users as a class, and there is no longer
any limit imposed.
Prior to V8 sendmail, if
a user who was not trusted attempted to use the
-f switch, that
attempt was silently ignored (silently
disallowed). Beginning with V8.7
sendmail, if a user who is
not trusted attempts to use the -f switch, that attempt
can produce an X-Authentication-Warning: header (X-Authentication-Warning: on page
1167) if the PrivacyOptions option (PrivacyOptions on page 1065) has
authwarnings
listed.
Even though some users find them annoying, we
recommend that you always enable X-Authentication-Warning: headers. They
warn of suspicious behavior. If the behavior is
legitimate, modify that behavior to eliminate the
header instead of eliminating the more valuable
warning headers.
Security Options
The sendmail program offers several options that can help you to improve the security at your site. Some we have discussed already. We touch on a few more in this section, and provide a recommended setting where appropriate. For a full description of each, see the sections referenced.
The DefaultUser option
The DefaultUser option (DefaultUser on page 1000) can be used
to ensure that the default identity (when it is
not running as root) is a
safe one. CERT recommends that you create a
pseudouser whose uid and
gid are used nowhere on your
system, and then define the DefaultUser option to be
that pseudouser. As an additional precaution, make
sure that pseudouser lacks a valid shell and has
no valid home directory:
mailnull:*:32765:32765:Sendmail Default User:/no/such/directory:/bin/false
At the same time, set up a group entry for this user’s group:
mailnull:*:32765:
This is necessary if you want to refer to this group symbolically at some later time. This is also recommended to avoid the risk of someone else reusing that group ID for another purpose in the future.
Avoid using the name nobody, because root is mapped to nobody over NFS. If root were to create a file over NFS that it thought was safe because root owned it and because it was readable only by root, that root user would be surprised to find that file owned by nobody. Consequently, we recommend that in an NFS environment, you set the default user to one less than nobody.[78] For example, if nobody has the uid 65534, you could set up:
mailnull:*:65533:65533:Sendmail Default User:/no/such/directory:/bin/false
The RunAsUser option (V8.8 and above)
The RunAsUser option (RunAsUser on page 1083) is just like
the DefaultUser
option (DefaultUser on page
1000) described earlier. But instead of setting
the identity to be used when
sendmail is not running as
root, this option sets the
identity to replace root.
Because a non-root program
cannot assume the identity of other users, this
option cannot be used in conjunction with the
DefaultUser
option. Instead, this option sets the only
identity that sendmail will
use.
Although it is tricky to get sendmail to run as a non-root process in all circumstances, V8.12 offers a way to get part of sendmail to do this. The idea is that initial mail submission (by local users) can be sent safely with a non-root sendmail, whereas handling inbound mail and local delivery can require a root process. V8.12 handles this division by creating two separate sendmail processes, handling the two separate roles. See Install sendmail on page 60 for a complete explanation of this process.
The TrustedUser option (V8.10 and above)
The TrustedUser option (TrustedUser on page 1112) defines the
user that can administer
sendmail. If set, this user
will own database map files (such as
aliases), and will also own
the control socket (ControlSocketName on page 990). Even
though only root can start
sendmail, this user can stop
and restart the sendmail
daemon.
By setting this option, you can employ a user other than root to administer sendmail. But if you have been administering sendmail as root, you cannot simply set this option and be done. Instead, you need to shut down sendmail, make a few changes and then restart.
The first change is needed to ensure that this trusted user can edit the source files for database files created by sendmail (the aliases database).
The second change is needed to remove the control socket (if you use one) so that sendmail can create it with the proper ownerships.
With these simple changes in place, you can add the following line to your mc configuration file, and build and install a new configuration file from it:
define(`confTRUSTED_USER',`user')Here, user is a user login name, or a user ID number.
When you restart sendmail with this new trusted user in place, you can thereafter routinely employ that user to administer sendmail.
The ForwardPath option
The ForwardPath option (ForwardPath on page 1034) lists a
series of directories that
sendmail will search for user
~/.forward files. At most
sites, there are users who are savvy and able to
correctly administer their own
~/.forward files, but there
are others who are untrained or careless. You can
allow experienced users to use the
~/.forward facility, while
denying this ability to the others with the
ForwardPath
option:
O ForwardPath=/usr/local/etc/forwards/$u.forward:$z/.forward
Here, sendmail will first
search the
/usr/local/etc/forwards
directory to find a file that begins with the
user’s login name (the $u, $u on page
848) followed by a .forward.
If you set up such a file for the untrained
user—say, bob:
-rw-r—r— 1 root system 0 Dec 13 2002 /usr/local/etc/forwards/bob.forward
and if that file is empty, bob’s mail will always be delivered locally, regardless of what bob puts in his ~/.forward file. For experienced users, you can omit their files from the /usr/local/etc/forwards directory, thus enabling them to use their own ~/.forward files.
The LogLevel option
The sendmail program
normally logs a great deal of useful information
via syslog (syslog(3) on page 514). There will be times, however,
when the normal amount of information is
insufficient. Consider, for example, that some
outsider is using your site to forge mail. Because
this is done over an SMTP connection, it would be
handy to have both sides of all SMTP conversations
logged. You can do this with the LogLevel option (LogLevel on page 1040):
O LogLevel=12 ← V8.8 and above configuration file define(`confLOG_LEVEL', 12) ← V8.8 and above mc configuration
Beginning with V8.8 sendmail, a level of 12 causes both sides of every SMTP conversation to be logged. That logging looks very similar to the logging produced by verbose mode (Verbose Mode (-v) on page 24).
Note that after changing the log level in your configuration file, you will need to restart the daemon. With V8.7 and above sendmail you restart the daemon like this:
# kill -HUP `head −1 /etc/sendmail.pid'Be aware that a log level of 12 produces a huge amount of output. Be prepared to prune your logfiles more often than usual while running at this higher logging level.
The PostmasterCopy option
The PostmasterCopy option (PostmasterCopy on page 1064) causes a
copy of every bounced message to be delivered to a
named user. Usually, that user is the person who
handles email problems. But because clumsy
intrusion attempts can result in bounced mail,
there will be times when bounced mail should also
be delivered to the security administrator.
Consider the following:
——- Transcript of session follows ——- >>> RCPT To:<root@your.site.domain> <<< 550 cannot open /tmp/.../getshell: No such file or directory 550 5.7.1 cannot open /tmp/.../getshell: No such file or directory
This bounced mail message indicates that someone tried to become root by breaking through your aliases database.
Users are added to the list of those who get
copies of bounced messages with the PostmasterCopy
option:
O PostmasterCopy=postmaster,securitymaster
↑
addedHere, securitymaster (probably an alias to a
real user) was added.
The PrivacyOptions option
The PrivacyOptions option (PrivacyOptions on page 1065) is used
to limit the amount of information offered to the
outside world and to limit other kinds of access.
The most restrictive setting for the PrivacyOptions option is
probably best:
define(`confPRIVACY_FLAGS', ``goaway,restrictmailq,restrictqrun'')
This setting disables the EXPN and VRFY SMTP
commands, requires other sites to identify
themselves before sending mail, and limits access
to the mail queue directory. As a side effect, it
also disables DSN parameters because goaway includes noreceipts. If that is a
problem for you, you can manually set up
everything that goaway does, but exclude noreceipts.[79] Note that the following line is split
to fit the page:
define(`confPRIVACY_FLAGS', ``needmailhelo,noexpn,novrfy,noverb,authwarnings, restrictmailq,restrictqrun'')
As a general rule, it is best to begin with tight security. This minimizes your risk from the beginning and allows you to cautiously ease restrictions at a comfortable rate. Beginning with loose restrictions can force you to tighten restrictions in a panic when it is least convenient to do so.
The SafeFileEnvironment option
Beginning with V8.7
sendmail, the SafeFileEnvironment
option (SafeFileEnvironment on
page 1084) determines how delivery will be made to
files. Ordinarily, sendmail
will deliver to anything, provided that it has
permission to do so (Delivery to Files on page 466). It
can, for example, deliver by appending to ordinary
files or by writing to a device such as
/dev/log.
If the SafeFileEnvironment option is declared,
sendmail will deliver only to
ordinary files. This improves security by
preventing anyone from scribbling over sensitive
things, such as directories and devices.
(Beginning with V8.8
sendmail, it is still OK to
write to /dev/null even
though this option is set.)
The SafeFileEnvironment option can also be
used to define a directory under which all files
that will be appended to must exist. This might
inconvenience some users but will generally
improve the security of your site. We
recommend:
O SafeFileEnvironment=/path ← configuration file define(`confSAFE_FILE_ENV',`/path') ← mc configuration
This takes care of both security enhancements.
Of course, you will need to create the directory
specified in /path and
populate it with the appropriate files.
Note that, just before appending to a file,
sendmail does a
chroot(2) into
/path. As a
consequence, an entry such as the following
requires that the full path exist, such as
/path/admin/mail:
bob: \bob, /admin/mail/bob.archive
But sendmail is also
clever, and if an aliases
path begins with the same path as the SafeFileEnvironment
path, and that latter path is removed before the
write:
bob: \bob, /path/admin/mail/bob.archive
Here, because the SafeFileEnvironment option specifies
/path,
sendmail will perform the
chroot(2) into
/path, then will strip
/path from the
aliases file entry to form
/admin/mail.
If all you want to do is prevent writing to directories and devices, and if you do not want to place all files in a special path, you can accomplish this by defining /path as the root directory:
O SafeFileEnvironment=/The TempFileMode and QueueFileMode options
The TempFileMode option (TempFileMode on page 1097) specifies
the mode (file permissions) to give all temporary
files and queue files. Beginning with V8.12, the
QueueFileMode
option (QueueFileMode on page
1071) specifies the permissions given to queue
files. In general, all files that are created by
sendmail should be considered
proprietary for safety’s sake. We recommend a
setting of:
O TempFileMode=0600 ← pre-V8.12, for all temp files and queue files O QueueFileMode=0600 ← V8.12 and above, for queue files only, in sendmail.cf O QueueFileMode=0660 ← V8.12 and above, for MSP queue files only, in submit.cf
With this narrow setting, the risk of accidental or malicious easing of permissions of your mail archive directories or queue becomes less of a risk.
The /etc/shells File
To prevent certain users from running programs or writing to files by way of the aliases or ~/.forward files, V8 sendmail introduced the concept of a “valid shell.” Just before allowing delivery via an alias so:
|"/some/program" /save/to/a/file
the user’s password entry is looked up. If the shell entry from that password entry is a valid one, delivery is allowed. A shell is valid if it is listed in the /etc/shells file.[80] If that file does not exist, sendmail looks up the shell in its internal list, which looks (more or less) like this:[81]
/bin/bsh /bin/csh /bin/ksh /bin/pam /bin/posix/sh /bin/rksh /bin/rsh /bin/sh /bin/tcsh /usr/bin/bsh /usr/bin/csh /usr/bin/keysh /usr/bin/ksh /usr/bin/pam /usr/bin/posix/sh /usr/bin/rksh /usr/bin/rsh /usr/bin/sh /usr/bin/tcsh
With this technique it is possible to prevent certain users from having sendmail running programs or delivering to files on their behalf. To illustrate, consider the need to prevent the ftp pseudouser from misusing sendmail:
ftp:*:1092:255:File Transfer Protocol Program:/u/ftp:/no/shell
Here, any attempt by ftp to send mail through a program or into a file will fail because the shell /no/shell is not a valid shell. Such mail will bounce with one of these two errors:
User ftp@here.us.edu doesn't have a valid shell for mailing to programs User ftp@here.us.edu doesn't have a valid shell for mailing to files
Note that unusual circumstances might require you to allow users with invalid shells to run programs or deliver to files. To enable this for all such users (as on a mail server with restricted logins), place the following line directly in the /etc/shells file:
/SENDMAIL/ANY/SHELL/
To enable this for selected users, just replace their shell with a bogus one that is listed in /etc/shells:
ftp:*:1092:255:File Transfer Protocol Program:/u/ftp:/bogus/shellWe recommend that all pseudousers (such as bin and ftp) be given invalid shells in the password file and that /SENDMAIL/ANY/SHELL/ never be used.
Be warned, however, that if a user can get into your machine as ftp, it can be possible for that user to run another shell, such as csh(1). Thus, in addition to listing a bogus shell, you might need to take further steps to prevent such access.
Other Security Information
No single chapter on security can be fully complete. The subject is so complex and far-ranging that an entire book might not be enough. To augment the information we have given here, we recommend these other important sources:
- http://www.sendmail.org/~gshapiro/
Gregory Shapiro has authored a number of fine papers on sendmail. Of special interest, as of this writing, is Sendmail Security (based on V8.12), a brief document that outlines much of what we have talked about in this chapter, and provides tips we have not covered.
- sendmail/SECURITY
The file sendmail/SECURITY is supplied with the sendmail source distribution and mainly deals with a non-root setup. You should read this file each time you download a new sendmail release.
- http://www.cert.org/
This is the official site for the CERT Coordination Center, which studies Internet security vulnerabilities, handles computer security incidents, and publishes security alerts. This is an excellent site for security information, and it allows you to sign up for a mailing list that can warn you about security incidents.
- http://www.sans.org/
The official site for the SANS Institute, an organization that provides security training and information. This site allows you to subscribe to a mailing list that provides routine digests of security matters.
- Practical Unix & Internet Security, Third Edition
By Simson Garfinkel and Gene Spafford (O’Reilly), this comprehensive book on security that includes information about many versions of Unix. It contains information about network security that is germane to sendmail administration.
- Other web sources
Any of your favorite search engines can be used to find additional material about computer security in general, email security, and sendmail security in specific.
Pitfalls
The sendmail program is only as secure as the system on which it is running. Correcting permissions and the like is useful only if such corrections are systemwide and apply to all critical system files and programs.
Time spent tightening security at your site is best spent before a break-in occurs. Never suppose that your site is too small or of too little consequence to be attacked. Start out by being wary, and you will be more prepared when the inevitable happens.
Newer versions of perl(1) object to PATH environment variables that begin with a dot (such as
.:/bin:/usr/bin). V8 clears the PATH variable before executing programs in a user’s ~/.forward file. Some shells put it back with the dot first. Under such versions of the Bourne shell, execute perl(1) scripts like this:|"PATH=/bin:/usr/bin /home/usr/bin/script.pl"
There is no check in the
Tcommand to determine that the names listed are the names of real users. That is, if you mistakenly enteredTuupcwhen you really meantTuucp, pre-V8 sendmail remained silent and UUCP mail mysteriously failed. V8.7 and above sendmail log warning messages.
[59] * The default beginning with V8.12 is to install sendmail as a non-set-user-id program that operates as root only if it is run by root.
[60] † That flaw has been eliminated—wrongly by some vendors who turned all debugging completely off, correctly by most who simply disabled SMTP debugging.
[61] ‡ Contrary to popular belief, sendmail does not run as root to handle local delivery (except that sendmail can deliver directly to files when necessary, but that is not directly germane to this discussion). Local delivery is handled by delivery agents (such as /bin/mail), which may run set-user-id root themselves (or set-group-id mail as in SysV).
[62] * But note that V8.8 sendmail has loosened the latter for use on firewall machines, where it won’t complain about non-root qf files if it is not running as root.
[63] † Except when seteuid(3) is POSIX-compliant. Old implementations of seteuid(3) didn’t properly save the uid, hence the preference, in that case, for setreuid(3).
[64] * When delivering to files, sendmail will become the owner of the file if that file’s set-user-id bit is set and if no execute bits are set.
[65] † We say “must” because in an NFS environment, root is mapped to nobody, so in that instance, even root won’t be able to write to bill’s files unless sendmail becomes bill.
[66] * See the
F=q flag (F=q on page 778) for a way and
reason to change this SMTP reply code to
252.
[67] † The fingerd(8) daemon can also reveal login IDs.
[68] ‡ The GNU fingerd(8) daemon also uses VRFY to provide mailbox information.
[69] * Most versions of Unix disallow core dumps of set-user-id root programs.
[70] * Programs that need kernel symbols, such as ps(1), will cease to work or will produce garbage output.
[71] † The savvy administrator can still boot off the network or from a CD-ROM and quickly install a new kernel.
[72] * This is done
only when not in rule-testing mode to prevent
spurious warnings when you already know you are
using a weak configuration file with -C.
[73] † We refer here
to both file permissions and permissions granted
by the DontBlameSendmail option (Don’t Blame sendmail on
page 168). Beginning with V8.9, for example, the
behavior we describe requires the DontBlameSendmail option
to be set to GroupWritableIncludeFileSafe.
[74] * Actually,
beginning with V8.10, it defaults to whichever of
the following is found first to exist in the
passwd file:
mailnull,
sendmail, or
daemon. If none of those
exists, the default becomes 1:1.
[75] † Beginning with
V8.9, the problem we describe is not possible with
the default settings of the configuration file.
However, if you enable the DontBlameSendmail option
(Don’t Blame sendmail
on page 168) with a setting of GroupWritableForwardFileSafe, you
override the default safety features and allow
this dangerous behavior.
[76] * V8 sendmail also tries to verify the connection itself with identd, if possible.
[77] † In fact, old versions of the GNU emacs(1) mail reader delete those lines irrevocably.
[78] * If that user ID is already in use, find an available number that is below nobody’s number, and use it instead.
[79] * Actually,
goaway also
includes needexpnhelo and needvrfyhelo, but these
are superseded by noexpn and novrfy, respectively.
[80] * The /etc/shells file is also used by the ftpd daemon, and by other daemons, to screen users.
[81] † This is an amalgamation of many vendor lists. See conf.c in the source distribution for details.