BSD DevCenter
oreilly.comSafari Books Online.Conferences.


Postfix: A Secure and Easy-to-Use MTA

by Glenn Graham

On March 3rd, 2003, Internet Security Systems, in cooperation with the Department of Homeland Security, issued a warning regarding a hole found in Sendmail. Sendmail, of course, is responsible for handling over half of the world's e-mail traffic. The warning, echoed by CERT, warned system admins that any version lower than 8.12.8 was vulnerable to a serious root exploit. I heard the warning loud and clear, so I wasted little time upgrading each system on our network.

Sendmail has a long history of security holes, most of which have been thoroughly documented on security sites around the world. Why do people continue to run Sendmail? The majority of my systems used to run Sendmail compared to the minority that ran other MTAs such as Postfix or Qmail. Sendmail isn't easy to configure. It lacks a user-friendly front end. It certainly doesn't come ready to use or with easy-to-understand documentation. Is Sendmail still used because it ships as the default mailer with almost every flavor of Unix? Whatever the reason, many would agree its time to adopt a more user friendly mail transport agent.

Welcome to Postfix

Postfix was developed as a replacement for Sendmail and is known to compile on almost every flavor of Unix including Mac O/S X. Wietse Venema, program founder and security specialist, several years developing the application while working as a researcher at IBM's T.J. Research lab. Postfix is the free version of IBM's commercial Mailer, Secure Mailer. It was released in 1998 and dubbed IBM's Christmas present to the Internet. Postfix became especially popular during the Linux revolution by enthusiasts who were looking for open source code that would compile on a free operating system.

Related Reading

The Complete FreeBSD
Documentation from the Source
By Greg Lehey

Postfix attempts to be fast, easy to administer, and secure, while at the same time being compatible enough with Sendmail so as not to upset existing users. Thus, the outside has a Sendmailish flavor, but the inside is completely different. With this in mind, let's take a closer look at Postfix.

Postfix has a unique internal structure that supports SASLv1/v2, SSL/TLS, DB3, MySQL and LDAP. The application runs in a chrooted environment, and upon execution, chroots (jails) the mail queue and daemons. First time users will benefit from a single, easy to understand configuration file written in plain English, unlike the archaic, cryptic Sendmail counterpart. Most defaults are set to sensible values, allowing you to configure only two or three parameters prior to initial use. Advanced users will benefit from hundreds of additional options including a wide range of add-on software allowing enhanced versatility.

Every mail server, or Mail eXchanger, must have a DNS entry for each domain for which it receives mail. These are called Exchange records or MX entries. They are commonly listed as primary and secondary, each one instructing the domain system to send SMTP traffic destined for some domain to the primary exchanger. In the event delivery to the primary exchanger fails, a secondary exchanger will queue any remaining messages. For more detailed information regarding MX records, please see the DNS manual.

The Postfix receiving cycle consists of seven steps. An in-depth explanation is available through the Postfix website.


Before we begin, we need to remember that Postfix uses several Sendmail-specific filenames such as sendmail, mailq, and newaliases. These are overwritten during installation, so we need to back these files up prior to installing Postfix. Some operating systems, in particular the *BSDs, come packaged with MailWrappers that allow you to wrap a number of mail packages into one, thus providing the luxury of editing mailer.conf with site-specific paths to existing binaries. For more information see man mailer.conf.

% mv /usr/sbin/sendmail /usr/sbin/sendmail.old
% mv /usr/bin/mailq /usr/bin/mailq.old
% mv /usr/bin/newaliases /usr/bin/newaliases.old

Throughout this article, I'll use examples from the FreeBSD Postfix port installation. Alternately, if you are compiling from source, download Postfix from any number of global mirrors, then uncompress the file to src.

Next, if Sendmail is running, stop it. Also, remove any Sendmail specific security or sanity checks from your cron. Save your current Sendmail configuration files, such as aliases, virtusertable, and access for later reference. The FreeBSD port installs the sendmail binary under /usr/local/sbin/, where it used to exist under /usr/sbin/. To conform with existing scripts, I suggest making a symlink from /usr/local/sbin/sendmail to /usr/sbin/sendmail. Most source installations install under /usr/sbin/

If you are installing via the FreeBSD port, make will spawn an ncurses-based GUI where you may add compilation options such as support for SSL/TLS, SASL, DB3, MySQL, and LDAP. This is especially advantageous for those planning to include add-ons such as phpMailAdmin or other apps requiring LDAP/MySQL compiled support. Users requiring only basic functions may bypass this option and continue with make.

The install target is an interactive script that adds other options such as postfix users, groups, and file locations. The defaults should suffice for most users.

BSD users should keep in mind that make world will reinstall Sendmail binaries, over-writing the Postfix installation. Remember to keep a current copy of your Postfix binaries and config files in the event you plan to make world.

Configuration is accomplished through a single, easy to understand configuration file. The default configuration path is usually /etc/postfix, while the default FreeBSD port installs under /usr/local/etc/postfix. By editing, a few options need be changed to suit your system prior to running the application:

  • the fully-qualified server name (
    myhostname =
  • the path of the primary domain (
    mydomain =
  • the path of the fully-qualified domain ( or the path of the primary domain (
    myorigin = $myhostname 
    # or
    myorigin = $mydomain

These are later referenced in the sample configuration file.

By default, Postfix looks to /etc for the aliases.db file. Depending on where your aliases and aliases.db files are located, you should make a symlink to /etc. The location of this file may be configured under, with the alias_maps directive. To initiate your aliases database, run the standard Sendmail command newaliases. The aliases file uses the standard Sendmail format. Note that attempting to run Postfix without aliases.db in the path will cause an error.

To start Postfix, run:

% postfix start

To stop Postfix, run:

% postfix stop

Anytime you make changes to, restart Postfix by running:

% postfix reload

Next, let's test our server by issuing a telnet connection on port 25, then send some common mail commands (like those sent by an SMTP client) to the server. After each command is issued, the mail server should respond with an acknowledgment.

command: telnet 25
response: Trying
Connected to
Escape character is '^]'. 
220 machine1.domain.tld ESMTP Postfix
(Connected to machine1.domain.tld identified by ESMTP postfix)

command: HELO
response: 250

Machine1.domain.tld responds by saying hello back to remotehost.domain.tld by doing a reverse dns lookup. This helps prevent host spoofing.

command: MAIL FROM:
response: ok

The server responds that the email address is acceptable and issues an ok.

command: RCPT TO: glenn@localhost
response: 250 ok

The server recognizes glenn as a valid system user and issues another ok reply. If the recipient does not exist, the server would issue a user unknown response.

command: DATA:
Type in the data of the mail message you wish to send to
glenn.  End this message with a . after a
carriage return on a line by itself

command: . 
response: 250 Ok: queued as EAAD3167

The mail message has been queued for delivery to glenn with the ID: EAAD3167.

command: QUIT
(Issue the quit command to end the connection)

Use a simple mail reader, such as pine, to check the user's mail on the local system to ensure delivery. In the event mail is not received, check that aliases.db resides under /etc and that a user exists under /var/mail. Some archaic systems require the mail drop to be created manually. This is accomplished by doing

% touch /var/mail/user; chown user:postfix /var/mail/user

If syslogd logs mail messages to a specific logfile such as /var/log/maillog, you should tail this file to ensure proper delivery or to check for errors in configuration.

Next, try sending a test message to a local user on the system from another host on your network, for example, Your message should arrive without error.

Pages: 1, 2

Next Pagearrow

Sponsored by: