Using Postfix for Secure SMTP Gateways
To understand how postfix works, it's useful to consider its background. The main purpose for postfix's existence is sendmail's complexity. Postfix is a full-featured MTA, and therefore its core functions are the same as any other's. But postfix was written with unusual attention to:
Security. Postfix was designed with security as a fundamental requirement rather than as an afterthought. It's obvious that Mr. Venema has taken the lessons of history (as chronicled by CERT, bugtraq, et al.) very much to heart. For example, the system doesn't trust any data, regardless of its source. And with least privilege in a chrooted jail (see below), risks are reduced. Furthermore, protective measures against buffer overflows and other user-input attacks have been implemented. If something still fails, postfix's protection mechanism tries to prevent any of the processes under its control from gaining rights they shouldn't have. Since postfix is comprised of many different programs that function without a direct relationship to each other, if something goes wrong, the chance that such a problem can be exploited by an attacker is minimized. Of course, we all know that no system is 100% secure; the goal must be to minimize and manage risks. Postfix is definitely engineered to minimize security risks.
Simplicity and compatibility. Postfix has been written in such a way that setting it up “from scratch” can take as little as five minutes. When you want to replace sendmail or other MTAs, it's even better: postfix by default can use the old configuration files!
Robustness and stability. Postfix was written with the expectation that certain components of the mail network (the Local Area Network, the Internet uplink, the local interfaces, etc.) will occasionally fail. By anticipating things that can go wrong at either end of any given transaction, postfix is capable of keeping the server up and running in many (if not most) circumstances. If, for instance, a message cannot be delivered, it is scheduled to be delivered later, without immediately initiating a continuous retry.
A key contributor to the stability and the speed of postfix is the intelligent way in which it queues mail. Postfix uses four different queues, each one of which is handled differently (see Figure 1):
Maildrop queue. Mail that is delivered locally on the system is accepted in the Maildrop queue. Here, the mail is checked for proper formatting (and fixed if necessary) before being handed to the Incoming queue.
Incoming queue. The Incoming queue receives mail from other hosts, clients or the Maildrop queue. As long as e-mail is still arriving and as long as postfix hasn't really handled the e-mail, this queue is the place where the e-mails are kept.
Active queue. The Active queue is the queue that is used to actually deliver messages and therefore has the greatest potential risk of something going wrong. This queue has a limited size, and messages will be accepted only if there is space for them. That means e-mail in the Incoming and Deferred queues have to wait until the Active queue can accept them.
Deferred queue. E-mail that cannot be delivered is placed in the Deferred queue. This prevents the system from continuously trying to deliver e-mail and keeps the Active queue as short as possible in order to give newer messages priority. This also enhances stability. If the MTA cannot reach a domain, all the e-mail for that domain is placed in the Deferred queue, so that those messages will not needlessly monopolize system resources. Retry is scheduled with an increasing waiting time. When the waiting time expires, the e-mail is again placed in the Active queue for delivery; the system keeps track of retry history.
And now the part you've been waiting for (or have skipped directly to): postfix setup. Like sendmail, postfix uses a “.cf” text file as its primary configuration file called main.cf. However, “.cf” files in postfix use a simple “parameter=$value” syntax. What's more, these files are extremely well commented and use highly descriptive variable names.
In fact, if your e-mail needs are simple enough, it's probably possible for you to figure out much of what you need to know by editing main.cf and reading its comments as you go.
For many users, this is all one needs to do to configure postfix on an SMTP gateway:
Install postfix from a binary package via your local package tool (rpm, etc.) or by compiling from source and running postfix's INSTALL.sh script.
Open /etc/postfix/main.cf with the text editor of your choice.
Uncomment and set the parameter myhostname to equal your server's fully qualified domain name (FQDN), e.g., “myhostname = buford.dogpeople.org”.
Uncomment and set the parameter mydestination as follows, assuming this is the e-mail gateway for one's entire domain:
mydestination = $myhostname, localhost.$mydomain, $mydomain
NOTE: Enter the above line verbatim.
Save and close main.cf.
If desired, add a line to /etc/aliases diverting root's mail to a less-privileged account, e.g., root: mick. This is also the place to map aliases for users who are served by internal mail servers (for example, mick.bauer: email@example.com). When you are done editing and/or adding aliases, save the file and enter the command newaliases to convert it into a hash database.
Execute the command postfix start.
(NOTE: While this may be enough to get postfix working, it is not enough to secure it. Don't stop reading yet!)
Practical books for the most technical people on the planet. Newly available books include:
- Agile Product Development by Ted Schmidt
- Improve Business Processes with an Enterprise Job Scheduler by Mike Diehl
- Finding Your Way: Mapping Your Network to Improve Manageability by Bill Childers
- DIY Commerce Site by Reven Lerner
Plus many more.
- Happy GPL Birthday VLC!
- Server Hardening
- Unikernels, Docker, and Why You Should Care
- diff -u: What's New in Kernel Development
- Controversy at the Linux Foundation
- Giving Silos Their Due
- What's New in 3D Printing, Part II: the Hardware
- Don't Burn Your Android Yet
- Tech Tip: Really Simple HTTP Server with Python
- ABINIT for Chemists