The directory /etc/postfix contains Postfix configuration
files. The two most important files used in the configuration of Postfix
are master.cf and main.cf. These
files should be owned by, and only writable by, the
root user. They should be readable by
everyone. Whenever you make changes to these files, you have to reload
Postfix for your changes to go into effect:
The master daemon is the overall process that controls other Postfix daemons for mail handling. The master daemon uses the master.cf file for its configuration information. The master.cf file contains a line for each Postfix service or transport. Each line has columns that specify how each program should run as part of the overall Postfix system. See Chapter 3 for information on Postfix’s architecture and how various components interact with each other. In many installations, you will never have to change the default master.cf file. See Section 4.5 later in the chapter for information on when and how to make changes to master.cf.
The main.cf file is the core of your Postfix configuration. Nearly
all configuration changes occur in this file. The default main.cf file lists only a portion of the
nearly 300 Postfix parameters. Most Postfix parameters do not need to be changed, but the
flexibility is there when it’s required. All Postfix parameters are
listed and described in the various sample configuration files. The sample files are located
in the directory specified by the
sample_directory parameter, which is usually
the same directory as your main.cf file. Both the main.cf file and the sample files that come
with the Postfix distribution contain comments that explain each of
Throughout this book, when the text says to modify a parameter, it always refers to a parameter in your main.cf unless a different file is indicated.
You can edit main.cf
with the postconf
command, as you saw earlier in the chapter, or you can change the file
directly with any text editor (such as vi or
emacs). The file contains blank
lines, comment lines, and lines that assign values to parameters.
Comment lines start with the
# character and continue to the end of the
line. Blank and comment lines are ignored by Postfix. Parameters can
appear in any order within the file, and are written as you would
# The myhostname value must be a fully qualified hostname. myhostname = mail.example.com # The rest of the file continues below...
You cannot have a comment on the same line as a parameter. The following example is incorrect and, with some parameters, could cause unexpected behavior that might be difficult to track down:
# # This is a bad parameter assignment. Never do this. # myhostname = mail.example.com # must be fully qualified hostname
mydestination = example.com oreilly.com ora.com postfix.org
is the same as:
mydestination = example.com oreilly.com ora.com postfix.org
mydomain = example.com myorigin = $mydomain
This causes the value of
myorigin to be “example.com.”
You can reference a value in the file even before it has been set. The following example works as well as the previous one:
myorigin = $mydomain mydomain = example.com
Many parameters can have more than one value. Multiple values can be separated by commas, spaces, tabs, or new lines. Remember that when you separate values with new lines there must be spaces or tabs in front of the values to indicate a continuation of the previous line:
mydestination = $mydomain, example.com, oreilly.com mydestination = $mydomain example.com oreilly.com mydestination = $mydomain example.com oreilly.com
These three assignments to
mydestination are effectively the
Certain parameters allow you to place multiple values
in a text file and then point the parameter to that file in
main.cf . A value that starts with a forward slash is assumed
to be a pointer to a file. If your system receives mail locally for
many destinations, you may want to keep the list of destinations in
a separate file. Then point the
mydestination parameter to that
mydestination = /etc/postfix/destinations
The parameters that can use external files to store values are
those that accept lists where the order of the listed items is not
significant, such as
relay_domains. Check the documentation for
a particular parameter to see if it supports this feature.
If you have thousands of items in a list, it can be more efficient to keep them in a lookup table instead. Lookup tables are described in the next section.
See Section 4.4.2 later in the chapter for more information about stopping and starting Postfix.
Rather than using complicated rewriting or pattern
transformation rules as Sendmail does, Postfix makes use of simple,
yet flexible, lookup tables. Many parameters point to lookup tables to
obtain important configuration information. One such parameter is
canonical_maps . It’s used to rewrite email addresses in messages.
Consider a site that uses account names internally for email
addresses, but wants any publicly visible addresses to have the form
For example, the address
firstname.lastname@example.org should appear as
canonical_maps lookup table provides the
mapping from a
key (email@example.com) to a
There are many parameters that use lookup maps, but they all work on the same principle. An email message (or client) provides some kind of key used to look up a value. Based on the value, Postfix takes some action or makes some change.
Postfix lookup tables are usually Unix database files, which are specially indexed files that provide faster access to the stored items. Lookup tables start as simple text files, with each key and value on the same line separated by spaces or tabs:
# # canonical mappings # firstname.lastname@example.org email@example.com
Each entry has a unique key. The keys are often referred to as the LHS, or lefthand side of an entry, and the values are referred to as the RHS, or righthand side of an entry. Keys in lookup tables are not case-sensitive. The files can contain comment and blank lines just like main.cf, and line continuation works by putting whitespace at the beginning of carry-over lines. Lookup tables also do not treat quotation marks with any special significance.
Once you have created a text file with all of your mappings, you have to execute the postmap command against it to create the actual indexed version of the file:
Whenever you change your text file you must execute postmap against it.
postmap -q firstname.lastname@example.org /email@example.com
Different types of Unix database files have different
internal formats. The format you use depends on the database
libraries available on your system. Normally Postfix supports one or
more of three types:
hash. Depending on your system libraries,
you may have fewer or more than these three types available. It’s
important to know which map type you use. The postconf command with the
-m option lists all of the map types
supported by your installation of Postfix:
postconf -mstatic pcre nis regexp environ proxy btree unix hash
The output of this command lists all map types, some of which
are used for access to other kinds of storage. But you should find
at least one of the three database types (
postconf default_database_typedefault_database_type = hash
All of the examples in this book use the
hash type, but if your installation is
using something different, be aware of that as you follow the
If you don’t specify a database type with postmap, it automatically uses your default type. In general, you can just use the default type configured on your system, but you must know what it is when assigning lookup tables to mapping parameters.
type is the storage access
name is the resource
containing keys and values. With indexed datafile lookups,
name is the filename. The canonical
example is assigned as follows:
canonical_maps = hash:/etc/postfix/canonical
You can assign multiple lookup tables to a parameter. Postfix
searches the tables in the order listed, stopping as soon as it
finds a match. Some table lookups are recursive, depending on the
parameter in these examples is one such parameter. With recursive lookups, once a value is found, Postfix
tries to match it against all of the keys again until a key matches
itself or is not found.
You may have noticed that when postmap indexes files, it creates additional files. postmap creates either one additional file with the extension .db, or two additional files with the extensions .dir and .pag, depending on your database format. When you assign the lookup table to its parameter, specify the path and filename without any extensions.
Since keys are often email addresses, Postfix
automatically parses addresses, breaking them up into their parts.
You can have keys that match a full address, just the domain
portion, or just the local part. The way Postfix searches for
addresses or portions of addresses depends on the type of mapping
parameter. Certain maps might sensibly include the simple local part of an address, such as
canonical_maps. Others would not expect a
local part key, such as
transport_maps. The order in which Postfix
searches for a match differs slightly, depending on which type of
parameter it’s working with. Check the lookup table’s manpage to see
which search order it follows.
The complete address. Example: firstname.lastname@example.org
The local part alone. Example: kdent
The domain portion only, specified with the @ character. Example: @example.com
The complete address. Example: email@example.com
The domain by itself. Example: example.com
The domain specified with an initial period, which matches any subdomain. Example: .example.com
If you always want domains to match themselves plus any subdomain, you
can simplify your lookup tables somewhat by setting the
parameter. The parameter, by default, contains many
lists. To add
the list, append it as follows:
parent_domain_matches_subdomains = debug_peer_list fast_flush_domains mynetworks permit_mx_backup_networks qmqpd_authorized_clients relay_domains smtpd_access_maps transport_maps transport_maps = hash:/etc/postfix/transport
Now, a domain entry in the /etc/postfix/transport matches itself and all of its subdomains automatically. You no longer need any entries such as the third item, .example.com, from the preceding list.
Some parameters that normally take a simple list, such
mydestination, can also be
specified with a lookup table. The LHS keys are the items in the
list. You still have to provide a RHS value for each key, but the
value is simply ignored. You can specify any text you want. It’s a
good place to provide yourself a comment. Using a lookup table for a
straight list is useful when you have thousands of items; otherwise,
a simple text file is more than adequate and probably has better
performance. If you use a lookup table for lists of network IP addresses, you cannot use the
network/netmask notation to specify an entire subnet. You must list
each address individually. Check the documentation to see if a list
parameter supports the lookup table feature.
Postfix provides a special lookup table type using regular expressions that offers even more flexibility for matching keys in lookup tables. Regular expressions are used in many Unix utilities. They provide a powerful tool for specifying matching patterns. There are two types of regular expression libraries that you might use with Postfix, depending on which libraries are available on your system.
By default, Postfix uses POSIX extended regular expressions, which I’ll refer
to as regexp. POSIX, which stands for
Portable Operating System Interface, is a standard
that encourages portability across different operating systems. It
includes specifications for regular expressions. Postfix also
supports Perl-compatible regular expressions, which I’ll refer
to as pcre. If you’re used to regular
expressions in Perl, you’ll find that regexp patterns are a bit
different. If you want pcre support, be sure you have a pcre library
to link with when building Postfix. With the pcre format, some
features differ from regexp, and the performance is usually better.
It’s possible that your Postfix distribution already includes pcre
support. You can check by executing the postconf command with the
-m option, as you did earlier in the
If pcre is listed among your map types, then you can use Perl-style regular expressions for your regular expression lookup tables. But don’t rush to add pcre support if you don’t have it; the default regexp is quite powerful and usually adequate for administrators who need regular expressions. Install pcre only if you know of particular Perl-style regular expression features you need.
Both Perl-style and POSIX regular expressions are very
well-documented in many places. Any book on Perl should include
information on its regular expressions, and if you have Perl
installed on your system, you should find a manpage called
perlre(1). Documentation for regexp
usually appears in a manpage called
re_format(7). If your system does not
include the manpage, you should be able to find it on the Web.
sed & awk by Dale Dougherty and Arnold
Robbins (O’Reilly) contains information on POSIX regular
body_checks = regexp:/etc/postfix/re_body_checks
The most common use of regular expression tables is with the
parameters for blocking spam. See Chapter 11 for more
Postfix can make use of other backend systems for its
lookup tables. (Later chapters discuss using MySQL and LDAP lookup tables.) When you make use of
these external sources for lookup values, you should start
with one of the simple database formats, such as
hash. Make sure your configuration works as
expected. After setting up your external data source, verify that it
returns the same results as your simple tables.
postmap -q hash:/etc/postfix/transport$
postmap -q mysql:/etc/postfix/transport.cf
See Chapter 15 for more information on using Postfix with external data sources.
Alias files are a special case of Postfix lookup tables because they use a Sendmail-compatible format. The file has traditionally been called aliases, and its location depends on your platform, but it is normally within the /etc directory or a subdirectory below it. By default, Postfix is configured to point to your original aliases file, so if you are migrating from Sendmail, your existing aliases continue to work.
Historically, email systems used a single alias
database. Postfix lets you have as many as you want. Multiple alias
files can help in organizing your configuration information.
Typically, administrators configure multiple alias files for
convenience when configuring separate mailing lists. The
alias_maps parameter points to your alias files.
If your system supports NIS, which is a network database of users (including
their aliases), then by default Postfix includes NIS among your
alias maps. A typical default
alias_maps looks like the
alias_maps = hash:/etc/aliases, nis:mail.aliases
If your system includes support for NIS, but you’re not using it, you should change the parameter so that it points to your aliases file only:
alias_maps = hash:/etc/aliases
You may want to locate your aliases file in your Postfix
configuration directory for consistency. Some administrators prefer
to have all of the email configuration files located together.
point to the new location:
alias_maps = hash:/etc/postfix/aliases
You should also reassign
alias_database so that your newaliases command continues to work
correctly (see the next section):
alias_database = hash:/etc/postfix/aliases
Since the format of alias maps differs from that of Postfix lookup tables, you cannot use postmap to build the alias database from your text file. Instead, Postfix provides the postalias command. Its command-line syntax is the same as that of postmap, allowing you to create or query alias maps. To build an alias database from your aliases file, execute the following:
Another Sendmail compatibility command related to alias files
is the newaliases command. It provides a convenient way to rebuild your
alias databases. The Postfix installation includes a replacement
version of the command that follows the same syntax as the original.
It’s normally executed with no arguments and determines which alias
files to rebuild from the
alias_database parameter. The
alias_database parameter differs from
alias_maps in that it includes
only standard Unix database-mapped files (those that should be
indexed by newaliases), whereas
alias_maps might also contain
other map types such as
newaliases uses the
default_database_type parameter discussed earlier to determine which
database format to use.
The text file for alias databases is much like Postfix
lookup tables, except for the alias definition itself. Alias files can have blank and
comment lines that are ignored. Comments are marked by a
# at the beginning of the line and cannot
be on the same line as an alias definition. A single alias
definition can be broken onto multiple lines by starting
continuation lines with whitespace.
The form of an alias definition consists of the name being
aliased, followed by a colon, followed by one or more targets for
the aliased name. Aliases can be directed to different types of
targets (discussed below). Multiple targets are
separated by commas. Both aliases and targets should be quoted if they
contain whitespace or any special characters such as a
#, :, and @:
kyle.dent: kdent, firstname.lastname@example.org
Specify the full path to a file. New messages are appended to the file specified. Delivery occurs to the file as it would to any local mailbox. See Chapter 7 for information on local delivery to mailboxes and on specifying different mailbox formats. For example:
Specify a pipe character and a command. See Chapter 14 for more information on delivery to commands. For example:
An included file contains a list of additional alias targets. The targets in the file can be any valid target type as described here, but by default filenames and commands are not allowed. The next section discusses configuration parameters to override these default restrictions. For example:
Normally, when Postfix makes a local delivery it assumes the
identity of the recipient of the message. With aliases, Postfix uses
the identity of the owner of the alias file, except when the file is
root. When a
delivery would occur as
Postfix uses the identity of the account configured with the
default_privs parameter instead.
You can control which kinds of targets are allowed in
your alias files with the parameters
allow_mail_to_files. Each of these
parameters takes a list of the aliasing mechanism that permits its
action. Aliasing mechanisms are “alias,” the alias file we’ve
been discussing; “include,” the include target, and “forward,” which
is the .forward file discussed
in Chapter 7.
The default setting for the two parameters is to allow delivery to commands and files from both alias and .forward files, but not from include files, for security considerations. If you want to disallow delivery to commands and files from your aliases database entirely, set the parameters to blank:
allow_mail_to_commands = allow_mail_to_files =
If you would like to make delivery to commands and files available in all the alias mechanisms, set the parameters as follows:
allow_mail_to_commands = alias, forward, include allow_mail_to_files = alias, forward, include
This setting is equivalent to the default behavior for Sendmail. However, it could expose access to possibly vulnerable mailing-list managers that might be coerced into adding a filename or command as a destination address. If you don’t need the additional include option for files and commands, it’s best to accept the Postfix default.
There are several common aliases that are configured
by default. By convention, these system aliases point to the
root account. You want to make sure that
root’s mail is read regularly.
This is normally accomplished by creating an alias for
root to the normal login account of the
person or persons responsible for system administration.
RFC 2142 defines several mailbox names that all
domains should have, depending on which services they run on the
Internet. At a minimum, you should have a
postmaster alias, and you should review
the RFC to see if there are other aliases you want to create.
 If you change the
inet_interfaces parameter, you must stop
and start Postfix.
 Postfix expects configuration files to contain normal Unix-style line endings. If you edit your configuration files from another platform, such as Windows or Mac, make sure that your editor uses the correct line endings for Unix.