Three weeks ago I finally managed to finish one of my longest lasting IT projects at home: replacing the Sendmail MTA on all my NetBSD systems with Postfix. There were plenty of reasons for this migration:
- Sendmail’s configuration files are incomprehensible to most people including me. You can build them from somewhat understandable templates. But that is still far from ideal.
- Sendmail’s monolithic architecture is prone to security problems.
- As Sendmail is basically an interpreter for a weird text processing language with builtin SMTP support it is not very efficient.
- Sendmail’s support for filtering spam e-mails is somewhat limited, at least if you don’t want to write rules for its configuration file manually.
- After Sendmail was removed from the NetBSD source tree convenience was no longer an excuse to use it on my NetBSD systems.
I picked Postfix as the replacement because it is now in the NetBSD source tree (very convenient), uses a secure architecture, provides powerfull builtin mail filtering and last but not least support for Sendmail mail filters (see below).
I started the migration almost three years ago by switching all my NetBSD clients to Postfix which wasn’t really difficult. However the last machine still running Sendmail was my main mail server which provides multiple services:
- It is used as mail relay by all our computers at home and by some of our friends and our family members.
- It is the primary mail server for a couple of domains like zhadum.org.uk.
- It provides backup mail services for a few other domains.
This server’s spam filtering was also reasonably complicated. Besides milter-greylist and milter-regex it used multiple home grown scripts which modified the configuration automatically. Porting all those extras to Postfix wouldn’t be an easy task.
A few weeks back I realized how long this project had dragged on and got back to my Postfix book. After I had finished reading it I finally set a date for the migration.
On the big day things went pretty well initially. I had warned my users and configured packet filter rules to prevent new e-mails from arriving before I finished. After a quick check on the backup mail server I stopped Sendmail and started working on the Postfix configuration. An hour later I had a configuration which seemed to be mostly working. Two problems remained however:
- procmail was reporting errors when it tried to save e-mails to a large mail folder.
- If Postfix was configured to use milter-greylist for mail filtering it stopped accepting E-Mails over SMTP.
Trying to solve both problems at the same time I made no headway at all. I finally decided to focus on the procmail problem and turned off mail filtering temporarily. After various futile attempts to debug the problem I finally resorted to ktrace(1) to figure out why procmail was failing. Reading the kernel trace data I finally found the cause of the problem: Postfix imposed a process limit which restricted the maximum file size that procmail could use. A quick look in the documentation revealed that the mailbox_size_limit setting controlled this behavior. After changing it to a suitable value procmail worked fine.
The milter problem was unfortunately much harder to solve. I spent hours checking my configuration and couldn’t find a problem. I finally began to debug Postfix itself and found a problem in the internal communication between two of its components. Thanks to Michael van Elst’s help I managed to fix the problem. Postfix and milter-greylist started to cooperate at long last and I finished my work at about 1:00 o’clock on Sunday morning.
Postfix worked very reliably ever since and I only had to make a few configuration changes. I’m also astonished how much faster than Sendmail it delivers e-mail. I didn’t think it would make such a difference on a fast machine connected via an A-DSL link.
Finally having finished this I’m not about to be idle tough as a new home IT project has emerged: migrating my friend’s server which is my backup mail server to Postfix as well. I hope that I’ll get this one done more timely. 🙂