Serving Mail with Postfix

[OpenBSD 5.0, Postfix 2.8.7]

OpenBSD default install is preconfigured with Sendmail as the mail server (MTA.)

These notes guide you through the installation of Postfix and Dovecot for a Mail Server that can provide email for users with accounts on the system/box.

The Port

Install the postfix package, using the appropriate binary package.

# pkg_add postfix-2.8.7-mysql
-> Creating /etc/mailer.conf.postfix
-> Creating Postfix spool directory and chroot area under /var/spool/postfix
-> Creating Postfix data directory under /var/postfix
+---------------
| Configuration files have been installed in /etc/postfix.
| Please update these files to meet your needs.
+---------------
postfix-2.8.7-mysql: ok
The following new rcscripts were installed: /etc/rc.d/postfix
See rc.d(8) for details.
--- +postfix-2.8.7-mysql -------------------
Postfix can be set up to replace sendmail entirely. Please read the
documentation at file:/usr/local/share/doc/postfix/html/index.html or
http://www.postfix.org/ carefully before you decide to do this!

To replace sendmail with Postfix you have to install a new mailer.conf
using the following command:

    /usr/local/sbin/postfix-enable

If you want to restore sendmail, this is done using the following command:

    /usr/local/sbin/postfix-disable

The above screen output, shows a successful install of the binary package, with explicit instructions to complete before we can assume that postfix is minimally installed.

  1. Read the documentation
  2. Enable Postfix using provided script
  3. Minimal Configuration
  4. Enable automatic startup on System Restart
  5. Disable Sendmail
  6. Verify alias configuration

1. Documentation

The documentation is made available in html format, below is an example local webspace for reading.

# mkdir -p /var/www/htdocs/manual
# cp -R /usr/local/share/doc/postfix/html /var/www/htdocs/manual/postfix

If you've previously enabled the standard OpenBSD apache base installation then you should now be able to browse the Postfix documentation locally at http://www.example.org/manual/postfix/. If you have enabled the Apache server and have no intentions of doing so, then you can read the official documentation at http://www.postfix.org/docs.html.

2. Enable Postfix

Enable Postfix using the provided script, and follow the manual configuration changes specified by the script.

/usr/local/sbin/postfix-enable
old /etc/mailer.conf saved as /etc/mailer.conf.pre-postfix
postfix /etc/mailer.conf enabled

NOTE: do not forget to add sendmail_flags=NO to
      /etc/rc.conf.local to disable sendmail.

NOTE: do not forget to add "-a /var/spool/postfix/dev/log" to
      syslogd_flags in /etc/rc.conf.local and restart syslogd.

NOTE: do not forget to add postfix to pkg_scripts in
      /etc/rc.conf.local to start postfix automatically.

NOTE: do not forget to remove the "sendmail clientmqueue runner"
      from root's crontab.

Ensure configuration is correct by completing the above instructions, before continuing.

  1. Add flag entry to /etc/rc.conf.local: sendmail_flags=NO
  2. Add flag entry to /etc/rc.conf.local: syslogd_flags="-a /var/spool/postfix/dev/log"
  3. Add flag entry to /etc/rc.conf.local: pkg_scripts="postfix"
  4. Modify root's crontab, and remove "sendmail clientmqueue runner"
  5. Restart syslogd:

1. sendmail_flags

sendmailflags sets the daemonflags for use by the rc.d(8) script.

NO - turns off the flag setting.

2. syslogd_flags

Explaining syslogd(8) '-a /var/spool/postfix/dev/log' (from the man pages)

 
syslogd reads and logs messages to the system console, log files, pipes
to other programs, other machines and/or users as specified by its
configuration file.

-a path
    Specify a location where syslogd should place an additional log
    socket.  Up to about 20 additional logging sockets can be
    specified.  The primary use for this is to place additional log
    sockets in /dev/log of various chroot filespaces.

3. pkg_scripts

Explainin pkg_scripts from the rc.conf.local(8) manpage.

The fourth section contains the pkg_scripts variable, responsible for
starting and stopping rc.d(8) scripts installed by packages in the
specified order.  For example, the following line

    pkg_scripts="dbus_daemon cupsd"

will run /etc/rc.d/dbus_daemon then /etc/rc.d/cupsd with the start
argument at boot time and in reverse order with the stop argument at
shutdown.

4. Root's Crontab

To complete the installation of Postfix, and disabling of Sendmail, we need to edit root's crontab and disable supplied Sendmail behaviour

  • comment out the Sendmail clientmqueue runner
# sendmail clientmqueue runner
*/30   *       *       *       *       /usr/sbin/sendmail -L sm-msp-queue -Ac -q

To be safe, you should just comment out the relevant line, (just in case you need or want to go back to Sendmail.) We use 'crontab -e' and add '#' hashes to 'comment' out the execution of the Sendmail line shown below.

# crontab -e
#minute hour    mday    month   wday    command
#
# sendmail clientmqueue runner
#*/30   *       *       *       *       /usr/sbin/sendmail -L sm-msp-queue -Ac -q

Configuration

[Ref: Mandatory ]

The Postfix installation documentation highlights some key areas you need to review, consider in your basic configuration.

File Fragment: /etc/postfix/main.cf

mydomain = example.org
alias_database = hash:/etc/postfix/aliases
parent_domain_matches_subdomains =

Postfix install Mandatory is a collection of Best Practises. You should at least read these to incorporate into your configuration, unless you know better. Topics include:

  • Configuration files( /etc/postfix/{main.cf|master.cf} )
  • Authorized clients to relay mail for
  • Authorized remote clients
  • Alias database

Authorized Clients

Find out which clients your mail server is authorizing by checking the mynetworks settings:

# /usr/local/sbin/postconf | grep ^mynetwork
mynetworks = 127.0.0.0/8 192.168.2.0/24 [::1]/128 [fe80:3::]/64 [fe80:1::]/64

On my test host, Postfix has automatically detected the above IP-Addresses and set them as trusted SMTP clients.

mynetworks (default: see "postconf -d" output)

The list of "trusted" remote SMTP clients that have more privileges than "strangers".

In particular, "trusted" SMTP clients are allowed to relay mail through Postfix. 
See the smtpd_recipient_restrictions parameter description in the postconf(5) manual.

mydomain

Remember that we generally name our hosts as something like

  • machine-id.domain.tld

(where tld is short for Top Level Domain)

But, when we are sending/recieving email we will be using @domain.tld. For our test installation, we'll specify the domain is going to be example.org.

Alias Database

Create, or confirm the alias database we are going to use:

# /usr/local/sbin/postconf alias_maps
alias_maps = hash:/etc/mail/aliases

The default install, retains use of the sendmail(8) aliases file. With a clean/new install, I prefer to keep the postfix files together and instead of the above (default) configuration, update the postfix main.cf configuration file.

Edit file: /etc/postfix/main.cf

alias_maps = hash:/etc/postfix/aliases

In the above, we're specifying the new location for aliases, as well as specifying that it's a DB file of type "hash". Edit the above listed file (/etc/postfix/aliases) as you wish and then update the hash/database file for aliases.

# /usr/local/sbin/postalias hash:/etc/postfix/aliases

Parent Domain Matches

This just caught me out a couple of times, and it took a while to find out the cause of the problem, so let's just do this up front.

Parent domain matches sub-domains

parent_domain_matches_subdomains 

What Postfix features match subdomains of "domain.tld" automatically, instead of 
requiring an explicit ".domain.tld" pattern. This is planned backwards compatibility: 
eventually, all Postfix features are expected to require explicit ".domain.tld" style 
patterns when you really want to match subdomains. 
## Starting Postfix [Ref: postfix(1)] Now, we are ready to make some fundamental tests, so let's start Postfix which at this stage is a nice 5 step process. - Restart syslogd - Kill Sendmail - Check files and configuration - Start postfix ### Restart syslogd: We've configured some new settings for syslogd above. If you haven't already done so, restart syslogd.
kill -HUP `cat /var/run/syslog.pid`
We are sending the SIGHUP (hangup) to syslogd, from the man page. [syslogd(8)]
syslogd reads its configuration file when it starts up 
and whenever it receives a hangup signal.

Kill existing session of sendmail

Because email is instrinsic to Unix/OpenBSD operations, it is automatically started on your OpenBSD box. But, it is the default MTA (sendmail.) We need to terminate/kill that service so our postfix service can be used.

kill -KILL `cat /var/run/sendmail.pid`

Check Files

[Ref: postconf(1), postfix(1)]

Postfix comes with rudimentary testing of file (using postfix check) and configuration settings(using postconf), so its a good habit to give it a test run before doing anything else.

The first quick test can be performed using the postfix command

From the manpage postfix(1):

check Warn about bad directory/file ownership or permissions, and
      create missing directories.
# /usr/local/sbin/postfix check

postfix

The following commands are implemented:

check Warn about bad directory/file ownership or 
permissions, and create missing directories.

Essentially, just run the program and if it doesn't give you error messages, then we are one step closer with 'fewer' errors in our setup.

# postfix check
The second test can be performed using the postconf 'Postfix configuration utility' , from the man pages postconf
-n Print parameter settings that are not left at 
        their built-in default value, because they are explicitly specified in 
        main.cf.

This essentially lets us quickly find out any blatant errors. For example, an output could look like this.

# /usr/local/sbin/postconf | grep ^my
mydestination = $myhostname, localhost.$mydomain, localhost
mydomain = example.org
myhostname = myhost.example.org
mynetworks = 127.0.0.0/8 public_ip/23 192.168.1.0/24 192.168.2.0/24 [::1]/128 
        ...IPV6_Addresses
mynetworks_style = subnet
myorigin = $mydomain

A quick perusal of the postconf output should give us an idea if we forgot or incorrectly put some information in.

Using 'postconf -n' is a good way to check for typing mistakes that can lead to many lost hours due the system being misconfigured and we're still trying to solve a problem with the wrong expections because the settings we placed in the configuration have not been set because of a typing mistake.

At this point in our install, there has been no serious changes to the configuration files.

Start Postfix Service

If all the above checks went through successfully, we can now start Postfix.

# /usr/local/sbin/postfix start
postfix/postfix-script: starting the Postfix mail system

or, we can use the new rc.d(8) script

# /etc/rc.d/postfix start

Validate the Mail Services

[Ref: The Network People, Inc. Mail Server Testing ]

We should now be able to test whether the server's 'face' to the world (smtp) is working.

To simplify testing, we will perform the tests on server itself. Where possible/practical, you should also run the tests from an external client to verify expected behaviour with an active firewall or other systems between your Postfix/SMTP Server and your clients.

This test procedure will only test a few basic commands, writing myself a message, my system user account is samt (and you can use any valid user account on the system)

telnet localhost smtp

Screen Session

$ telnet localhost smtp  
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 myhost.example.org ESMTP Postfix
EHLO example.org
250-myhost.example.org 
250-PIPELINING 
250-SIZE 10240000 
250-VRFY 
250-ETRN 
250-ENHANCEDSTATUSCODES 
250-8BITMIME 
250 DSN 
MAIL FROM: <samt@example.org>
250 2.1.0 Ok 
RCPT TO: <samt@example.org>
250 2.1.5 Ok 
DATA
354 Enter mail, end with '.' on a line by itself
Subject: This is my subject line

I continue writing until I'm out of interesting things to say
which is not that far away

.

250 2.0.0 Ok: queued as 
699ACBA2D7 
QUIT
221 2.0.0 Bye 
Connection closed by foreign host. 

I've just used capital letters for the SMTP commands, but obviously they work fine with lowercase. If your server is not yet online with a valid DNS record, then you can test using RCPT TO: samt@localhost.

Mail Log

The corresponding log messages will look something like the below.

Screen Session

# tail -f /var/log/maillog
starting the Postfix mail system
daemon started -- version 2.3.2, configuration 
/etc/postfix
connect from localhost[::1]
5E4A5BA2D4: client=localhost[::1]
5E4A5BA2D4: 
message-id=<20061212080251.5E4A5BA2D4@hostname.example.org>
5E4A5BA2D4: from=<samt@example.org>, size=457, nrcpt=1 (queue active)
5E4A5BA2D4: to=<samt@example.org>, relay=local, 
delay=77, delays=77/0.05/0/0.03, dsn=2.0.0, status=sent (delivered to 
mailbox)
5E4A5BA2D4: removed
disconnect from localhost[::1]

'tail' is a unix program to look at the recent additions to a file, and in our case we're looking at the log file for 'mail' related programs. Using the '-f' parameter tells 'tail' to continue looking at the recent additions to the file (such that updates to the file are displayed on the screen for us.) Use Ctrl+C (i.e. hold the Ctrl key while pressing C) to break out of the log review session shown above

mail

[Ref: mail(1)]

While we're testing with real system user accounts, we can use the unix 'mail' program to check our mail message.

Screen Session

# /usr/bin/mail -u samt
Mail version 8.1.2 01/15/2001. Type ? for help.
'/var/mail/samt': 1 message 1 new
>N 1 samt@example.org Tue Dec 12 21:03 18/605 This is my subject line
& more 1
Message 1:
From samt@example.org Tue Dec 12 21:03:54 2006
X-Original-To: samt@myhost.example.org
Delivered-To: samt@myhost.example.org
Subject: This is my subject line
From: samt@example.org
To: undisclosed-recipients:; 

I continue writing until I'm out of interesting things to say
which is not that far away
& q
Saved 1 message in mbox

In the above example, we enter mail for the user samt ('-u samt') and the 'mail' client shows a list of current email for user 'samt' and then gives us the '&' ampersand prompt.

We can read the email message by typing the message number, and 'mail' supports the use of a screen 'pager' such as 'more' so that we can scroll through longer messages.

Quit. We quit out of 'mail' using the 'q' command.

The above reference to the log files and mail client is to provide you with more tools for validating your installation.

Summary

We now have a fully functional email server that can receive email messages, and store those messages for users.

Postfix chroot files

Postfix's OpenBSD port is built as a privilege separated service, launching minimal server requirements as root and servicing transactions as a minimally authenticated user. This requires a few files to be made available within the chroot, such as:

resolv.conf contains the DNS server list that postfix will interrogate when it needs to perform name lookups.

# cp /etc/resolv.conf /var/spool/postfix/etc

If you're mail MTA is slow to respond, and you know from the log files that the server is up and running, then a 1st diagnostic investigation is to confirm that the DNS entries (as seen by postfix, above) are correct.

Summary

The above installation is a fully functional mail service for users on your host. Connecting to and from other Mail servers is essentially a function of the network availability.

Before connecting your host to send/recieve e-mail on the Internet please review at least your Postfix main.cf: mynetworks for a list of trusted SMTP clients.

Reference Resources

Troubleshooting Postfix from the Book of Postfix