Danger Level
There are many DoS attacks that simply flood a system with packets, called packet storms. There are others that are intended to run a system out of resources besides bandwidth, such as disk space or kernel table space. A popular way to do this is to send you massive amounts of junk e-mail to fill up your disk and waste your CPU time, process table slots, and so on. Regardless of whether the goal is to cripple your system or bother your users with phony get- rich-quick schemes, there are ways to resist.
If mail is sent very rapidly, in the process of forking off a child to handle each piece of e-mail, Sendmail may run the system out of processes. This is because Sendmail does not wait for one child to finish processing a piece of e-mail before starting the next, and the next, etc. Sendmail,
Inc.[21] recommends the variable values shown in Table 2.4 as a starting point in tuning your
sendmail 8.10 to be more resistant to DoS and spammer attacks. Most or all of these
recommendations will be applicable to later versions of Sendmail too. These values should be set in /etc/sendmail.mc. If a "M4 variable" listed, say confMIN_FREE_BLOCKS, is not already in the /etc/sendmail.mc file, it should be defined similarly to
define(`confMIN_FREE_BLOCKS', `100')
Then issue the following shell command to convert the /etc/sendmail.mc file into the /
etc/sendmail.cf file.
m4 /etc/sendmail.mc > /etc/sendmail.cf
Sendmail may be restarted so that it uses the new values. On Red Hat and its progeny, this is done with the following command. On other systems, such as Slackware, a system reboot is an easy way to restart sendmail; sending it a HUP signal and issuing the same sendmail
invocation that is used in /etc/rc.d/rc.M (found with grep) is an alternative.
/etc/rc.d/init.d/sendmail restart
Many more sendmail configuration improvements are addressed in "Sendmail".
Table 2.4. Sendmail DoS Fortification
Format:M4 variable (configuration file variable) [Default] Recommended: value Textual description
confMIN_FREE_BLOCKS (MinFreeBlocks) [100] Recommended: 4000 or larger
Minimum number of free blocks on queue file system to accept SMTP mail. (Prior to 8.7, this was minfree/maxsize, where minfree was the number of free blocks and maxsize was the maximum message size. In current versions of Sendmail, use confMAX_MESSAGE_SIZE
for the second value.)
confMAX_MESSAGE_SIZE (MaxMessageSize) [infinite] Recommended: 4000000 (?)
The maximum size of messages that will be accepted (in bytes).
confAUTO_REBUILD (AutoRebuildAliases) [False] Recommended: False
Automatically rebuild alias file if needed. There is a potential for a denial of service attack if this is set.
Load average at which queue-only function kicks in. Default value is (8 * numproc), where numproc is the number of processors (if that can be determined).
confREFUSE_LA (RefuseLA) [varies] Recommended: 8 (depending on CPU power)
Load average at which incoming SMTP connections are refused. Default value is (12 * numproc), where numproc is the number of processors online (if that can be determined).
confMAX_DAEMON_CHILDREN (MaxDaemonChildren) [undefined] Recommended:
40 (for 128 MB of RAM)
The maximum number of children the daemon will permit. After this number, connections will be rejected. If not set or <= 0, there is no limit. Set it to some number, depending on the amount of RAM. This value is suggested so as to not have so many active processes that thrashing sets in.
This is a DoS in itself. If you limit this to 40, an attacker need only open 40 connections and your system will refuse other connections. In a sense, it is a "no win" situation.
confMAX_HEADERS_LENGTH (MaxHeadersLength) [undefined] Recommended:
32K or 64K
Maximum length of the sum of all headers.
confMAX_MIME_HEADER_LENGTH (MaxMimeHeaderLength) [undefined]
Recommended: 1024 or less
Maximum length of certain MIME header field values.
confMAX_RCPTS_PER_MESSAGE (MaxRecipientsPerMessage) [infinite]
Recommended: 10-100 (depending on your site policy)
If set, allows no more than the specified number of recipients in an SMTP envelope. Further recipients receive a 452 error code (i.e., they are deferred to the next delivery attempt).
A nontrivial solution to this "sendmail connection flood" problem is to enhance
sendmail to limit the maximum number of open connections from any one system (or network) to a smaller number of connections. Any additional connections from the aberrant source will be closed immediately.
This might involve a table associating child PIDs of outstanding connections with the IP addresses of the systems that they are connected to, enabling easy processing when new connections are created. A likely location would be in daemon.c right after the accept(). Simply sequence through the table, counting the other connections from the same IP.
If the count exceeds the threshold (defaulting to one third of the total limit and settable on the command line) the SO_LINGER[a] is set to zero and the socket is closed. This change should take an experienced C programmer four to eight hours to
do. An alternative to modifying sendmail would be the use of a statefull firewall that has this capability of limiting the number of connections from a system. There also should be a shorter time limit (timeout) for the duration of a connection and its various phases; a default timeout of one hour is typical but excessive. The lines starting O Timeout (possibly commented out) in the
/usr/lib/sendmail-cf/m4/proto.m4
file should be examined and altered as necessary, especially most of the timeouts set to be 1h. Although an hour might have made sense long ago, a 100 KB message can be sent in 36 seconds over a 28.8 Kbaud line. A value of 5m should be sufficient for many installations. If messages take longer than that, it could be an indication of a flaky network and it would be better to drop the connection so that the sender can try again later when the network congestion clears.