1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
|
<HTML>
<HEAD>
<!-- This HTML file has been created by texi2html 1.52
from spec on 25 November 2000 -->
<TITLE>Exim Specification - 55. Security considerations</TITLE>
</HEAD>
<body bgcolor="#FFFFFF" text="#00005A" link="#FF6600" alink="#FF9933" vlink="#990000">
Go to the <A HREF="spec_1.html">first</A>, <A HREF="spec_54.html">previous</A>, <A HREF="spec_56.html">next</A>, <A HREF="spec_59.html">last</A> section, <A HREF="spec_toc.html">table of contents</A>.
<P><HR><P>
<H1><A NAME="SEC907" HREF="spec_toc.html#TOC907">55. Security considerations</A></H1>
<P>
<A NAME="IDX1990"></A>
This chapter discusses a number of issues concerned with security, some of
which are also covered in other parts of this manual.
</P>
<P>
For reasons that this author does not understand, some people have promoted
Exim as a `particularly secure' mailer. Perhaps it is because of the existence
of this chapter in the documentation. However, the intent of the chapter is
simply to describe the way Exim works in relation to certain security concerns,
not to make any specific claims about the effectiveness of its security as
compared with other MTAs.
</P>
<P>
What follows is a description of the way Exim is supposed to be. Best efforts
have been made to try to ensure that the code agrees with the theory, but an
absence of bugs can never be guaranteed. Any that are reported will get fixed as
soon as possible.
</P>
<P>
<H2><A NAME="SEC908" HREF="spec_toc.html#TOC908">55.1 Root privilege</A></H2>
<P>
<A NAME="IDX1991"></A>
<A NAME="IDX1992"></A>
The Exim binary is normally setuid to root. In some special cases (for example,
when the daemon is not in use and there are no conventional local deliveries),
it may be possible to run it setuid to some user other than root. However, root
privilege is usually required for two things:
</P>
<UL>
<LI>
To set up a socket connected to the standard SMTP port (25) when initialising
the listening daemon.
If Exim is run from <EM>inetd</EM>, this privileged action is not required.
<LI>
To be able to change uid and gid in order to read forward files and perform
local deliveries as the receiving user or as specified in the configuration.
</UL>
<P>
It is not necessary to be root to do any of the other things Exim does, such as
receiving messages and delivering them externally over SMTP, and it is
obviously more secure if Exim does not run as root except when necessary.
</P>
<P>
If no user is specified for Exim in either the compile-time or run time
configuration files, it runs as root all the time, except when performing
local deliveries. When an alternative user is specified (which is recommended),
it gives up root privilege when it can. Exactly how and when it does this
depends on whether the operating system supports the <EM>seteuid()</EM> or the
<EM>setresuid()</EM> function.
</P>
<P>
To avoid unnecessary complication, the discussion below talks about users, and
functions for setting the uid. It should be understood that in all cases there
is a corresponding group and gid, and that this is also changed whenever the
uid is changed.
<A NAME="IDX1993"></A>
<A NAME="IDX1994"></A>
The description is written in terms of <EM>seteuid()</EM>, since this is
more common than <EM>setresuid()</EM>. However, it is possible to specify at
compile time that an operating system has <EM>setresuid()</EM> and not <EM>seteuid()</EM>.
</P>
<P>
On systems without <EM>seteuid()</EM>, Exim uses <EM>setuid()</EM> to give up root privilege
at certain times, at the expense of having to re-invoke itself (using <EM>exec</EM>)
in order to regain privilege when necessary. If <EM>seteuid()</EM> is available, there
is a configuration choice as to which method is used for temporarily giving up
the privilege. Using <EM>setuid()</EM> is more secure, and is the default, but uses
more resources.
</P>
<P>
There are two instances in which Exim always uses <EM>setuid()</EM>:
</P>
<UL>
<LI>
Exim always uses <EM>setuid()</EM> to become a non-root user when running a local
delivery process. There are no exceptions. This applies whether or not an Exim
user is defined.
<LI>
Exim always uses <EM>setuid()</EM> to change to the Exim user (if one is defined)
before doing remote deliveries. These are the last things a delivery process
does, so it does not need to regain root privilege again.
</UL>
<P>
There are two instances in which Exim always uses <EM>seteuid()</EM> (provided it is
available in the operating system):
</P>
<UL>
<LI>
When reading a user's <TT>`.forward'</TT> file, Exim uses <EM>seteuid()</EM> to become that
user. This is necessary when the file is not publicly readable and is on a
remote NFS file system that is mounted without root privilege. If this is the
case on a system without <EM>seteuid()</EM>, the <TT>`.forward'</TT> file cannot be read.
<LI>
If any director or router has the <EM>require_files</EM> option set to check the
existence of a file as a specific user, <EM>seteuid()</EM> is used to become that
user for the duration of the check.
</UL>
<P>
For other operations, the <EM>security</EM> configuration option controls whether Exim
uses <EM>setuid()</EM> or <EM>seteuid()</EM> to change to its own uid.
It can be set to one of three strings:
</P>
<UL>
<LI>
<EM>seteuid</EM>: Exim uses <EM>seteuid()</EM> to give up root temporarily when it does not
need it, and to regain the privilege subsequently. This enables it to run with
a non-root effective uid most of the time, at very little cost, but offers less
security.
<LI>
<EM>setuid</EM>: Exim uses <EM>setuid()</EM> to give up root when it is receiving a locally
generated message, and after it has set up a listening socket when running as a
daemon. This means that, in order to deliver a message that it has received, it
has to re-invoke a fresh copy of itself to regain root privilege. During
delivery, it retains root except when actually transporting the message. In
particular, it runs the directors and routers as root. <EM>Setuid()</EM> is generally
reckoned to be more secure than <EM>seteuid()</EM> but running this way uses more
resources.
<LI>
<EM>setuid+seteuid</EM>: Exim uses <EM>setuid()</EM> as described immediately above, but in
addition, it uses <EM>seteuid()</EM> to give up root privilege temporarily when it
needs to regain it subsequently without losing a lot of state information, for
example, while running the directors and routers.
</UL>
<P>
On systems that do not support the <EM>seteuid()</EM> function, the only possible
value for the <EM>security</EM> option is `setuid', and this is the default on such
systems if an Exim user is defined. Otherwise the default is `setuid+seteuid'
-- the most secure setting.
</P>
<P>
<font color=green>
<H2><A NAME="SEC909" HREF="spec_toc.html#TOC909">55.2 Running Exim without privilege</A></H2>
<P>
<A NAME="IDX1995"></A>
<A NAME="IDX1996"></A>
Some installations require to run Exim in an unprivileged state almost all the
time, for added security. Support for this mode of operation is provided by the
setting
<PRE>
security = unprivileged
</PRE>
<P>
When this is done, all deliveries take place under the Exim user/group (which
must be defined), and there are restrictions on the features that can be used
in the configuration. There are two possibilities if you want to run Exim in
this way:
</P>
<UL>
<LI>
Keep it setuid to <EM>root</EM>, as in standard configurations. In this configuration,
except when starting the daemon, Exim gives up the root privilege and becomes
the Exim user/group as soon as it has started, using <EM>setuid()</EM> and <EM>setgid()</EM>.
This removes all privilege that might have been associated with the calling
user. In the case of the daemon, root privilege is retained until it has bound
its listening socket to the SMTP port, but then it gives it up in the same way.
The daemon can respond correctly to SIGHUP because the re-invocation regains
root privilege.
<LI>
Make Exim setuid/setgid to the Exim user and group. This means it cannot
start up the daemon unless it is called by a root process, and
consequently, the daemon cannot restart itself as a result of SIGHUP
because it is no longer a root process at that point. It is still useful
to set
<PRE>
security = unprivileged
</PRE>
in this case, because this setting stops Exim from trying to re-invoke itself
to do a delivery after a message has been received. Such a re-invocation is a
waste of time because it would have no effect.
</UL>
<P>
When using the second style (setuid to the Exim user), unless called by root
(in which case it behaves as first style), Exim is running with the real uid
and gid set to those of the calling process, and the effective uid/gid set to
Exim's values. Ideally, any association with the calling process' uid/gid
should be dropped, that is, the real uid/gid should be reset to the effective
values so as to discard any privileges that the caller may have. While some
operating systems have a function that permits this action for a non-root
effective uid, quite a number of them do not. Because of this lack of
standardization, Exim does not address this problem at this time. For this
reason, the first style is perhaps the better approach to take.
</P>
<P>
Because Exim no longer needs to re-exec itself when starting a delivery process
after receiving a message, using
<PRE>
security = unprivileged
</PRE>
<P>
is more efficient than either of
<PRE>
security = setuid
security = setuid+seteuid
</PRE>
<P>
However, to achieve this extra efficiency you have to submit to the following
restrictions:
</P>
<P>
You can deliver only as the Exim user/group. You should explicitly use the
<EM>user</EM> and <EM>group</EM> options to override directors or transports that normally
deliver as the recipient. (This makes sure that configurations that work in
this mode function the same way in normal mode.) Any implicit or explicit
specification of another user causes an error.
</P>
<P>
Use of <TT>`.forward'</TT> files is severely restricted, such that it is usually
not worthwhile to include a <EM>forwardfile</EM> director in the configuration.
</P>
<P>
Users who wish to use <TT>`.forward'</TT> would have to make their home directory and
the file itself accessable to the Exim user. Pipe and append-to-file entries,
and their equivalents in Exim filters, cannot be used. While they could be
enabled in the Exim user's name, that would be insecure and not very useful.
</P>
<P>
Unless the user mailboxes are all owned by the Exim user (possible
in some POP3 or IMAP-only environments):
</P>
<UL>
<LI>
They must be owned by the Exim group and be writable by that group.
This implies you must set <EM>mode</EM> in the appendfile configuration,
as well as the mode of the mailbox files themselves.
<LI>
You must set <EM>no_check_owner</EM>, since most or all of the files will
not be owned by the Exim user.
<LI>
You must set <EM>file_must_exist</EM>, as Exim cannot set the owner correctly on a
newly created mailbox when unpriviledged. This also implies that new mailboxes
need to be created manually.
</UL>
<P>
There are no additional restrictions on message reception or external (SMTP)
delivery.
</font>
</P>
<H2><A NAME="SEC910" HREF="spec_toc.html#TOC910">55.3 Alternate configurations and macros</A></H2>
<P>
Exim can be run with an alternate configuration file by means of the -<EM>C</EM>
option, and macros for use in its configuration can be set on the command line
using the -<EM>D</EM> option. If the -<EM>C</EM> option specifies a file other than the one
whose name is built into the binary, or if there is any use of the -<EM>D</EM> option,
and the caller is not root or the Exim user, Exim immediately gives up its
privilege, and runs with the real and effective uid and gid set to those of the
caller.
</P>
<H2><A NAME="SEC911" HREF="spec_toc.html#TOC911">55.4 Reading forward files</A></H2>
<P>
<A NAME="IDX1997"></A>
When forward files are read from users' home directories and those home
directories are NFS mounted without root privilege, even a program running as
root cannot read a forward file that does not have world read access.
</P>
<P>
If the <EM>seteuid()</EM> function is being used as described in the previous section,
so that Exim is not root when running the directors, the <EM>forwardfile</EM>
director automatically uses <EM>seteuid()</EM> to become the local user when
attempting to read a <TT>`.forward'</TT> file in a user's home directory. If <EM>seteuid()</EM>
is not being used generally, but is available in the operating system, the
<EM>forwardfile</EM> director can be configured to make use of it when reading files
in home directories.
</P>
<P>
The <EM>forwardfile</EM> director does not necessarily have to read from users' home
directories as obtained from <EM>getpwnam()</EM>. It can be given a directory
explicitly, and a specific associated user and group. The above remarks are
applicable in this case also.
</P>
<P>
On systems that do not have <EM>seteuid()</EM>, the only way to support forward files
on NFS file systems that do not export root is to insist that the files be
world readable.
</P>
<P>
<A NAME="IDX1998"></A>
Forward files are permitted to contain :include: items unless forbidden by
setting <EM>forbid_include</EM> in the director. If <EM>seteuid()</EM> is being used to read
the forward file, any included files are read as the same user. Otherwise
Exim is running as root, and it insists that any included files are within the
same directory as the forward file, and that there are no
<A NAME="IDX1999"></A>
<A NAME="IDX2000"></A>
symbolic links below the directory. If no directory is specified (either
explicitly or by looking up a local user's home directory) then included files
are not permitted when <EM>seteuid()</EM> is not in use.
</P>
<P>
When the filtering option is enabled for forward files, users can construct
pipe commands that contain data from the incoming message by quoting variables
such as $<EM>sender_address</EM>. To prevent the contents of inserted data from
interfering with a command, the string expansion is done after the command
line is split up into separate arguments, and the command is run directly
instead of passing the command line to a shell.
</P>
<H2><A NAME="SEC912" HREF="spec_toc.html#TOC912">55.5 Delivering to local files</A></H2>
<P>
Full details of the checks applied by <EM>appendfile</EM> before it writes to a file
are given in chapter 15.
</P>
<H2><A NAME="SEC913" HREF="spec_toc.html#TOC913">55.6 IPv4 source routing</A></H2>
<P>
<A NAME="IDX2001"></A>
<A NAME="IDX2002"></A>
Many operating systems suppress IP source-routed packets in the kernel, but
some cannot be made to do this. Exim is configured by default to log incoming
IPv4 source-routed TCP calls, and then to drop the call. These actions can be
independently turned off. Alternatively, the IP options can be deleted instead
of dropping the call. Things are all different in IPv6. No special checking is
currently done.
</P>
<H2><A NAME="SEC914" HREF="spec_toc.html#TOC914">55.7 The VRFY, EXPN, and ETRN commands in SMTP</A></H2>
<P>
Support for these SMTP commands is disabled by default. The VRFY command
can be enabled by setting <EM>smtp_verify</EM>. The EXPN command can be enabled
for specific
hosts by setting <EM>smtp_expn_hosts</EM>,
and there is a similar option controlling ETRN.
</P>
<H2><A NAME="SEC915" HREF="spec_toc.html#TOC915">55.8 Privileged users</A></H2>
<P>
<A NAME="IDX2003"></A>
<A NAME="IDX2004"></A>
<A NAME="IDX2005"></A>
Exim recognises two sets of users with special privileges. Trusted users are
able to submit new messages to Exim locally, but supply their own sender
addresses and information about a sending host. For other users submitting
local messages, Exim sets up the sender address from the uid, and doesn't
permit a remote host to be specified.
</P>
<P>
However, an untrusted user is permitted to use the -<EM>f</EM> command line option in
the special form -<EM>f <></EM> to indicate that a delivery failure for the message
should not cause an error report. This affects the message's envelope, but it
does not affect the <EM>Sender:</EM> header.
</P>
<P>
Trusted users are used to run processes that receive mail messages from some
other mail domain and pass them on to Exim for delivery either locally, or over
the Internet. Exim trusts a caller that is running as root, as the Exim user (if
defined), as any user listed in the <EM>trusted_users</EM> configuration option, or
under any group listed in the <EM>trusted_groups</EM> option.
</P>
<P>
Admin users are permitted to do things to the messages on Exim's queue. They
can freeze or thaw messages, cause them to be returned to their senders, remove
them entirely, or modify them in various ways. In addition, admin users can run
the Exim monitor and see all the information it is capable of providing, which
includes the contents of files on the spool.
</P>
<P>
By default, the use of the -<EM>M</EM> and -<EM>q</EM> options to cause Exim to attempt
delivery of messages on its queue is restricted to admin users. However, this
restriction can be relaxed by setting the <EM>no_prod_requires_admin</EM> option.
</P>
<P>
Exim recognises an admin user if the calling process is running as root or as
the Exim user (if defined) or if any of the groups associated with the calling
process is the Exim group (if defined). It is not necessary actually to be
running under the Exim group. However, if admin users who are not root or exim
are to access the contents of files on the spool via the Exim monitor (which
runs unprivileged), Exim must be built to allow group read access to its spool
files.
</P>
<H2><A NAME="SEC916" HREF="spec_toc.html#TOC916">55.9 Spool files</A></H2>
<P>
<A NAME="IDX2006"></A>
<A NAME="IDX2007"></A>
<A NAME="IDX2008"></A>
If a uid and gid are defined for Exim, the spool directory and everything
it contains will be owned by exim and have its group set to exim. The
mode for spool files is defined in the <TT>`Local/Makefile'</TT> configuration file, and
defaults to 0600. This should normally be changed to 0640 if a uid and gid are
defined for Exim, to allow access to spool files via the Exim monitor by other
members of the exim group.
</P>
<H2><A NAME="SEC917" HREF="spec_toc.html#TOC917">55.10 Use of argv[0]</A></H2>
<P>
Exim examines the last component of <EM>argv[0]</EM>, and if it matches one of a set
of specific strings, Exim assumes certain options. For example, calling Exim
with the last component of <EM>argv[0]</EM> set to `rsmtp' is exactly equivalent to
calling it with the option -<EM>bS</EM>. There are no security implications in this.
</P>
<H2><A NAME="SEC918" HREF="spec_toc.html#TOC918">55.11 Use of %f formatting</A></H2>
<P>
The only use made of `%f' by Exim is in formatting load average values. These
are actually stored in integer variables as 1000 times the load average.
Consequently, their range is limited and so therefore is the length of the
converted output.
</P>
<H2><A NAME="SEC919" HREF="spec_toc.html#TOC919">55.12 Embedded Exim path</A></H2>
<P>
Exim uses its own path name, which is embedded in the code, only when it needs
to re-exec in order to regain root privilege. Therefore it is not root when it
does so. If some bug allowed the path to get overwritten, it would lead to an
arbitrary program's being run as exim, not as root. If there's still paranoia
about this, two separate copies of the name could be kept, or a checksum could
be applied to the global data.
</P>
<H2><A NAME="SEC920" HREF="spec_toc.html#TOC920">55.13 Use of sprintf()</A></H2>
<P>
<A NAME="IDX2009"></A>
A large number of occurrences of `sprintf' in the code are actually calls to
<EM>string_sprintf()</EM>, a function which returns the result in malloc'd store. The
intermediate formatting is done into a large fixed buffer by a function that
runs through the format string itself, and checks the length of each conversion
before performing it, thus preventing buffer overruns.
</P>
<P>
The remaining uses of <EM>sprintf()</EM> happen in controlled circumstances where the
output buffer is known to be sufficiently long to contain the converted string.
</P>
<H2><A NAME="SEC921" HREF="spec_toc.html#TOC921">55.14 Use of debug_printf() and log_write()</A></H2>
<P>
Arbitrary strings are passed to both these functions, but they do their
formatting by calling the function <EM>string_vformat()</EM>, which runs through the
format string itself, and checks the length of each conversion.
</P>
<H2><A NAME="SEC922" HREF="spec_toc.html#TOC922">55.15 Use of strcat() and strcpy()</A></H2>
<P>
These are used only in cases where the output buffer is known to be large
enough to hold the result.
</P>
<P><HR><P>
Go to the <A HREF="spec_1.html">first</A>, <A HREF="spec_54.html">previous</A>, <A HREF="spec_56.html">next</A>, <A HREF="spec_59.html">last</A> section, <A HREF="spec_toc.html">table of contents</A>.
</BODY>
</HTML>
|