Building and Installing Postfix

This document describes how to build, install, and configure the Postfix mail transfer agent (MTA) on a system that does not have an do not have an existing MTA. One example of such a system is the box that was used for this document, a freshly-installed Slackware 9.1 box on which I expressly did not install Sendmail or any of its configuration files.

Assumptions

I make the following assumptions throughout this document:

The Procedure

With the assumptions just mentioned in mind, this is the procedure I followed to build and install Postfix. After building and installing Postfix, I've concluded that Sendmail is far too complex and baffling. While Sendmail might surpass Postfix in terms of configurability and features, Postfix provides all of the functionality I need without forcing me to learn arcane configuration hieroglyphics.

  1. Download the latest Postfix release. I recommend using a mirror from the list at at the Postfix Web site, http://www.postfix.org/download.html. I've also put up a copy of the version I used, postfix-2.1.1 on my public FTP site as ftp://ftp.kurtwerks.com/pub/postfix-2.1.1.tar.gz.
  2. Unpack the tarball. I built in my home directory, or, more precisely, $HOME/src:
    $ gzip -cd postfix-2.1.1.tar.gz | tar -xf -
    $ cd postfix-2.1.1
    
  3. Build the Postifx distribution. It should build quickly (00:01:23 on my Pentium III):
    $ make
    [...]
    gcc -Wmissing-prototypes -Wformat -DHAS_PCRE  -g -O -I. -I../../include -DLINUX2
    -o proxymap proxymap.o ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/lib
    util.a -L/usr/lib -lpcre -ldb -lnsl -lresolv
    cp proxymap ../../libexec
    $ 
    
  4. If you have an existing Sendmail installation, I recommend keeping the old Sendmail binaries around for a little while. Assuming the pathnames are correct, the following commands should do:
    # mv /usr/sbin/sendmail /usr/sbin/sendmail.OFF
    # mv /usr/bin/newaliases /usr/bin/newaliases.OFF
    # mv /usr/bin/mailq /usr/bin/mailq.OFF
    # chmod 755 /usr/sbin/{sendmail,newaliases,mailq}.OFF
    

    The first three commands rename the binaries with innocuous names. The final command makes sure that they newly-renamed binaries are executable. As the # prompt suggests, you need to execute these commands as the root user.

  5. Create a user and group that only the Postifx system uses. The user account does not need a login shell or a home directory. For simplicity's sake, I used postfix for both the user and the group:
    # /usr/sbin/groupadd postfix
    # /usr/sbin/useradd -g postfix -d /dev/null -s /bin/false postfix
    

    Here are the resulting entries in /etc/group and /etc/passwd:

    $ egrep postfix /etc/group /etc/passwd
    /etc/group:postfix:x:102:
    /etc/passwd:postfix:x:1001:102::/dev/null:/bin/false
    
  6. Create a group named postdrop with a group ID (GID) not used by any other group. The postdrop group won't even be used the the postfix user:
    # /usr/sbin/groupadd postdrop
    

    The resulting entry in /etc/group:

    $ egrep postdrop /etc/group
    postdrop:x:103:
    
  7. Optionally, if you want to install stripped versions of the Postfix binaries, execute the following command:
    $ strip bin/* libexec/*
    

    If you don't understand what "stripped versions of the Postfix binaries" means, skip this step and go on to the next one.

  8. If this is your first installation of Postfix, use the make install command, which performs an interactive installation. The interactive installation offers sane suggestions for pathnames (which you can override) and then stores these preferences in /etc/postfix/main.cf to make future upgrades easy (and, happily, non-interactive). The default values for each item appear between brackets (that is, []) - press Enter to accept the defaults or type the input and then press Enter:
    # make install
    [...]
    /bin/sh postfix-install
    
        Warning: if you use this script to install Postfix locally,
        this script will replace existing sendmail or Postfix programs.
        Make backups if you want to be able to recover.
    
        Before installing files, this script prompts you for some definitions.
        Most definitions will be remembered, so you have to specify them
        only once. All definitions should have a reasonable default value.
    
    Please specify the prefix for installed file names. Specify this ONLY
    if you are building ready-to-install packages for distribution to other
    machines.
    install_root: [/] 
    
    Please specify a directory for scratch files while installing Postfix. You
    must have write permission in this directory.
    tempdir: [/home/kwall/src/postfix-2.1.1]
    
    Please specify the destination directory for installed Postfix
    configuration files.
    config_directory: [/etc/postfix] 
    
    Please specify the destination directory for installed Postfix daemon
    programs. This directory should not be in the command search path of
    any users.
    daemon_directory: [/usr/libexec/postfix] 
    
    Please specify the destination directory for installed Postfix
    administrative commands. This directory should be in the command search
    path of adminstrative users.
    command_directory: [/usr/sbin] 
    
    Please specify the destination directory for Postfix queues.
    queue_directory: [/var/spool/postfix] 
    
    Please specify the full destination pathname for the installed Postfix
    sendmail command. This is the Sendmail-compatible mail posting interface.
    sendmail_path: [/usr/sbin/sendmail] 
    
    Please specify the full destination pathname for the installed Postfix
    newaliases command. This is the Sendmail-compatible command to build
    alias databases for the Postfix local delivery agent.
    newaliases_path: [/usr/bin/newaliases] 
    
    Please specify the full destination pathname for the installed Postfix
    mailq command. This is the Sendmail-compatible mail queue listing command.
    mailq_path: [/usr/bin/mailq] 
    
    Please specify the owner of the Postfix queue. Specify an account with
    numerical user ID and group ID values that are not used by any other
    accounts on the system.
    mail_owner: [postfix] 
    
    Please specify the group for mail submission and for queue management
    commands. Specify a group name with a numerical group ID that is
    not shared with other accounts, not even with the Postfix mail_owner
    account. You can no longer specify "no" here.
    setgid_group: [postdrop] 
    
    Please specify the destination directory for the Postfix HTML
    files. Specify "no" if you do not want to install these files.
    html_directory: [no] /usr/local/doc/postfix-2.1.1/html
    
    Please specify the destination directory for the Postfix on-line manual
    pages. You can no longer specify "no" here.
    manpage_directory: [/usr/local/man] 
    
    Please specify the destination directory for the Postfix README
    files. Specify "no" if you do not want to install these files.
    readme_directory: [no] /usr/local/doc/postfix-2.1.1
    
    Updating /usr/libexec/postfix/bounce...
    Updating /usr/libexec/postfix/cleanup...
    [...]
    Updating /usr/local/doc/postfix-2.1.1/html/virtual.5.html...
    Updating /usr/local/doc/postfix-2.1.1/html/virtual.8.html...
    postfix: warning: My hostname luther is not a fully qualified name - set myhostname or mydomain in /etc/postfix/main.cf
    
        Warning: you still need to edit myorigin/mydestination/mynetworks
        parameter settings in /etc/postfix/main.cf.
    
        See also http://www.postfix.org/faq.html for information about dialup
        sites or about sites inside a firewalled network.
    
        BTW: Check your /etc/aliases file and be sure to set up aliases
        that send mail for root and postmaster to a real person, then run
        /usr/bin/newaliases.
    
    #
    
  9. We are replacing Sendmail altogether, even though the assumption noted at the beginning of this document was that we were installing Postfix on a machine with no MTA (Sendmail) installed. First, edit /etc/postfix/main.cf (or wherever you installed the Postfix configuration files if you did not accept the defaults when you executed make install).
    1. The myorigin variable identifies the domain name appended to unqualified addresses (that is, user names without the @my.dom goober attached):
      myorigin = $mydomain
      

      This causes all mail going out to have your domain name appended. Thus, if the value of mydomain (see below) is possum_holler.com and the user name is bubba, then outgoing mail from bubba will appear to come from bubba@possum_holler.com.

    2. The myhostname variable identifies the local machine, that is, the one on which you've just installed Postfix.
      myhostname = luther.kurtwerks.com
      
    3. The mydomain variable specifies your domain name:
      mydomain = kurtwerks.com
      
    4. The mydestination variable tells Postfix what addresses it should deliver locally. For a standalone workstation, which is a system that is connected directly to the Internet and that has some sort of domain name resolver (DNS) running, you want mail to that machine and to localhost (and/or localhost.$mydomain) delivered locally, so the following entry should suffice:
      mydestination = $myhostname, localhost, localhost.$mydomain
      

    Postfix supports a larger number of configuration variables, but these are the mandatory changes you have to make.

  10. Create or modify /etc/aliases. At the very least, you need aliases for postfix, postmaster, and root in order for mail sent to those addresses to get to a real person. Here are the contents of my initial /etc/aliases file:
    postfix: root
    postmaster: root
    root: kwall
    

    After creating/editing the aliases file, regenerate the alias database using the Postfix newaliases command:

    # /usr/sbin/newaliases
    
  11. Start Postfix:
    # postfix start
    postfix/postfix-script: starting the Postfix mail system
    #
    
  12. Make sure Postfix will start when you boot the system. The easy way to accomplish this is to edit /etc/rc.d/rc.local (which might be present as /etc/rc.d/init.d/rc.local on your system) and add the following command to that file:
    /usr/sbin/postfix start
    

    This assumes you installed the Postfix binaries in /usr/sbin, which appears to be the default location.

  13. TIP: Here is the rc script I use to start Postfix at boot time on my Slackware system. It resides in /etc/rc.d/rc.local:

    #!/bin/sh
    
    # start Postfix
    if [ -x /usr/sbin/postfix start ]; then
    	echo -ne "Starting Postfix mail server..."
    	/usr/sbin/postfix start > /dev/null 2>&1
    	ret=$?
    	if [ $ret -eq 0 ]; then
    		echo "done"
    	else
    		echo "FAILED: $ret"
    	done
    fi
    
  14. Finally, modify your syslog configuration to handle Postfix log messages appropriately. I prefer that mail log messages go to their own files to avoid cluttering up the primary system log. So, here at KurtWerks, I use the following entries in /etc/syslog.conf, which controls the system log:
    *.info;*.!warn;authpriv.none;cron.none;mail.none  -/var/log/messages
    *.warn;authpriv.none;cron.none;mail.none          -/var/log/syslog
    mail.*;mail.!err                                  -/var/log/mail.log
    mail.err                                          -/var/log/mail.err
    

    The first two lines keep any mail related messages from being logged to /var/log/messages and /var/log/syslog. The third line logs everything but errors to /var/log/mail.log. The last line drops all error message from Postfix into /var/log/mail.err. The - character before each file name tells the system logging daemon, syslogd, to use asynchronous writes, which means that the logging daemon doesn't force the log messages to the specified file before returning control to the system - this measure helps Postfix run somewhat faster, especially on a heavily loaded system. However, using asynchronous writes might result in lost messages if the system crashes, because synchronous writes are forced to disk before the write call returns.

  15. Naturally, you have to restart syslogd to cause these changes to take effect. You can do a simple:
    # kill -HUP `pidof syslogd`
    
    On my Slackware system, I use:
    # /etc/rc.d/rc.syslog restart
    

At this point, you have a basic, functional Postfix installation. There is a great deal more customization that you can do and might want to do, but what I've covered here should get you started and offer some insight into the simplicity of Postfix installation and configuration.

Modifications

If the system on which you install Postfix is behind a firewall or you have a dialup system without a direct or constant Internet connection, you probably want to define a relay host that handles your email. In this case, Postfix will simply hand locally-generated email off to the relay host (which must be configured to relay for you, but that's beyond the scope of this Step). For the internal network here at KurtWerks, I added the following entries to /etc/postfix/main.cf

relayhost marta.$mydomain
disable_dns_lookups = yes

marta.$mydomain (marta.kurtwerks.com) handles actual mail delivery. Because I don't run DNS on the internal network, the second line disables SMTP client DNS lookups and causes Postfix to retrieve the the host IP for my relayhost from /etc/hosts. If you make these (or other) changes to the Postfix configuration file, you have to tell Postfix about them. Use the following command to do so:

# /usr/sbin/postfix reload
postfix/postfix-script: refreshing the Postfix mail system
#

For more tips and hints and some example configurations, see: