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.
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 |
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 main.cf, a few
options need be changed to suit your system prior to running the application:
bar.foo.com):
myhostname = bar.foo.comfoo.com):
mydomain = foo.combar.foo.com) or the
path of the primary domain (foo.com):
myorigin = $myhostname
# or
myorigin = $mydomainThese 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
main.cf, 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 main.cf, 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 machine1.domain.com 25
response: Trying 209.58.173.10...
Connected to machine1.domain.com
Escape character is '^]'.
220 machine1.domain.tld ESMTP Postfix
(Connected to machine1.domain.tld identified by ESMTP postfix)
command: HELO test.com
response: 250 remotehost.domain.com
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:
johnny@test.com
response: ok
The server responds that the email address johhny@test.com 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, user@fullyqualified.domain.com. Your message should arrive without error.
|
If you're running Postfix in a production environment, you'll need to add
some additional configurations such as a Primary MX, Virtual Domains, Host
Relays and a Secondary MX. Some of these options require building a hash style
database. Postfix uses a utility called postmap, a replacement
for makemap with a similar syntax.
If your machine accepts mail for domains outside your network, setting the
primary MX entries correctly is a critical component in the Postfix
configuration. This is accomplished by editing main.cf and
appending to the end of the file:
relay_domains = $mydestination, /usr/local/etc/postfix/relay-domains
Edit the file relay-domains according to this format:
another_domain.com
second_domain.com
third_domain.com
In the event your server is used as a secondary exchanger as defined in the
DNS record (MX), you may define allowable domains by editing
main.cf and adding the line:
relay_domains = $mydestination the.backed-up.domain.com
You may optionally choose to allow the world to MX through your host. Edit
smtpd.cf, then add the line:
smtpd_recipient_restrictions = permit_mx_backup
Remember to reload Postfix after changing main.cf.
Virtual Hosting is the ability to receive and redirect mail for a user of another domain, not our own, to a local user or a user on a remote system. For example, joe@foo.com might redirect to joe@localhost, or joe@foo.com may also redirect to joe@another_domain.com.
Creating a Virtual Domain is accomplished by editing main.cf
and appending to the end of the file:
virtual_alias_maps = hash:/usr/local/etc/postfix/virtual
Edit the file virtual according to this format, the same as of
virtusertable under Sendmail:
user@domain.com
user@localhost
# or user@remote.domain
Then, hash it to a database.
% postmap /usr/local/etc/postfix/virtual < /usr/local/etc/postfix/virtual
If you allow your host to act as an SMTP relay, you need to configure the
relay options under main.cf. Under the section Trust and
Control, look to mynetworks for a list of variable options.
In this example, we allow relaying based on two network subnets. This means
that hosts within the class C ranges of 168.100.189.0 and localhost 127 can
relay.
mynetworks = 168.100.189.0/24, 127.0.0.0/8
If you run into problems or require additional configuration sets, I suggest consulting the Postfix FAQ.
# Global Postfix configuration file. This file lists only a subset
# of all 250+ parameters. See the sample-xxx.cf files for a full list.
# NOTE - CHANGE NO MORE THAN 2-3 PARAMETERS AT A TIME, AND TEST IF
# POSTFIX STILL WORKS AFTER EVERY CHANGE.
queue_directory = /var/spool/postfix
command_directory = /usr/local/sbin
daemon_directory = /usr/local/libexec/postfix
mail_owner = postfix
myhostname = bar.foo.com
mydomain = foo.com
myorigin = $bar.foo.com
unknown_local_recipient_reject_code = 450
# Here is the MX (mx) stuff
relay_domains = $mydestination, /usr/local/etc/postfix/relay-domains
# The aliases
alias_maps = hash:/usr/local/etc/postfix/aliases
alias_database = hash:/usr/local/etc/postfix/aliases
debug_peer_level = 2
debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin \
xxgdb $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/local/sbin/sendmail
newaliases_path = /usr/local/bin/newaliases
mailq_path = /usr/local/bin/mailq
setgid_group = maildrop
manpage_directory = /usr/local/man
sample_directory = /usr/local/etc/postfix/samples
readme_directory = no
# Here is the Virtual User stuff
virtual_alias_maps = hash:/usr/local/etc/postfix/virtual
# Allow local and remote network to relay through this machine
mynetworks = 168.100.189.0/24, 127.0.0.0/8
Postfix uses the same start parameters as Sendmail, so most existing
start-scripts should suffice. In the unlikely event your sendmail-ish scripts
fail or hang, try starting Postfix from rc.local or, under BSD,
/usr/local/etc/rc.d/postfix.sh. The syntax is:
% /usr/local/sbin/postfix start &
Postfix is a robust, secure MTA. I was impressed with the ease of installation, well-defined documentation, and its ability to receive and relay mail without complex configuration. I've compiled Postfix under Solaris, various flavors of BSD, Slackware, and Red Hat. A wide range of add-on software including phpMailAdmin helps add an additional layer of functionality. Today I see Postfix as a major contender in the race for secure E-mail communications.
Glenn Graham has been working with telecommunications since 1977.
Return to the Linux DevCenter.
Copyright © 2009 O'Reilly Media, Inc.