Anatomy of Postfix

by Ralf Hildebrandt

Please note that this book is based on is based on Postfix 2.1, later versions of Postfix have new daemons not discussed in the book.

This chapter describes how Postfix works, what each piece of the system does, and how these components relate to each other. After going through this material, you should have an understanding of Postfix as a whole, so that you can focus on individual goals.

Postfix consists of a small number of programs that interact with user processes (sendmail, postqueue, postsuper, and so on) and a larger number of programs that run in the background. Only the programs that run in the background are controlled by the master daemon. The master daemon's job is to determine what work there is to do and dispatch the appropriate program to do the work. This modular design allows for a higher level of security because each program runs with the lowest privilege set needed to fulfill its task.

You can think of the whole Postfix system as a router. This may sound strange at first, but remember that a router's job is to look at an IP packet, determine the destination IP address (and possibly the source), and then choose the right interface to route the packet toward its destination. Postfix does the same thing with mail (see Figure 5-1), looking at the destination of a message (the envelope recipient) and the source (the envelope sender) to determine the application that will move the message closer to its final destination.

Postfix works like a router

Now let's look more closely at the system. A real router usually accepts IP packets from multiple interfaces, routing them back out through the interfaces. The same is true for Postfix; it accepts messages from multiple sources and then passes the mail on to multiple destinations. A message's origin may be the local sendmail binary or an SMTP or QMQP connection. The destination can be a local mailbox, outgoing SMTP or LMTP, a pipe into a program, and more. Figure 5-2 shows this view of Postfix.

A Postfix "router" accepts and establishes all kinds of connections

The origin and destination of a message seem clear enough, but how does Postfix pick a delivery method given a destination? A router uses routing tables that match IP addresses to networks to determine a path. Postfix does the same thing with email addresses.

In Postfix, lookup tables are called maps. Postfix uses maps not only to find out where to send mail, but also to impose restrictions on clients, senders, and recipients, and to check certain patterns in email content. Figure 5-3 shows where the maps--to name but a few, aliases, virtual, and transport are shown--fit in.

Maps are the lookup tables of the Postfix "router"

Postfix Daemons

Figure 5-4 shows an overview of the Postfix daemons and how they fit together.

Figure 5-4: The relationships between the Postfix daemons

Note:

Postfix is constantly under development. The following list of daemons is based on Postfix 2.1.

master

The master daemon is the supervisor of Postfix, and it oversees all other Postfix daemons. The master waits for incoming jobs to be delegated to subordinate daemons. If there is a lot of work to do, the master can invoke multiple instances of a daemon. You can configure the number of simultaneous daemon instances, how often Postfix can reuse them, and a period of inactivity that should elapse before stopping an instance.

If you have ever worked with the inetd server on a Unix machine, you will find many similarities between it and the master daemon.

bounce and defer

A mail transfer agent must notify the sender about undeliverable mail. In Postfix, the bounce and defer daemons handle this task, which is triggered by the queue manager (qmgr). Specifically, the two event types that cause sender notices are unrecoverable errors and a destination that is unreachable for an extended period of time. The latter case results in a delay warning.

error

The error daemon is a mail delivery agent like local or smtp. It is a delivery agent that always causes mail to be bounced. Usually you don't use it unless you configure a domain as undeliverable by directing mail to the error delivery agent. If a mail is sent to the error daemon it will inform the bounce daemon to record that a recipient was undeliverable.

trivial-rewrite

The trivial-rewrite daemon acts upon request by the cleanup daemon in order to rewrite nonstandard addresses into the standard user@fqdn form.

This daemon also resolves destinations upon request from the queue manager (qmgr). By default, trivial-rewrite distinguishes only between local and remote destinations.

showq

The showq daemon lists the Postfix mail queue, and it is the program behind the mailq (sendmail -bp) command. This daemon is necessary because the Postfix queue is not world-readable; a non-setuid user program cannot list the queue (and Postfix binaries are not setuid).

flush

The flush daemon attempts to clear the mail queue of pending and deferred messages. By using a per-destination list of queued mail, it improves the performance of the SMTP Extended Turn (ETRN) request and its command-line equivalent, sendmail -qR destination. You can maintain the list of destinations with the fast_flush_domains parameter in the main.cf file.

qmgr

The qmgr daemon manages the Postfix queues; it is the heart of the Postfix mail system. It distributes delivery tasks to the local, smtp, lmtp, and pipe daemons. After delegating a job, it submits queue file path-name information, the message sender address, the target host (if the destination is remote), and one or more message-recipient addresses to the daemon it delegated the delivery task to.

The qmgr design is a good example of how Postfix handles jobs to avoid resource starving and to maintain stability. Two things stand out:

  • qmgr maintains a small active queue, with just a few messages pending for delivery. This queue effectively acts as a limited window for the potentially larger incoming and deferred queues, and it prevents qmgr from running out of memory under a heavy load.

  • If Postfix cannot immediately deliver a message, qmgr moves the message to the deferred queue. Keeping temporarily undeliverable messages in a separate queue ensures that a large mail backlog does not slow down normal queue access.

qmgr uses the bounce and error daemons to bounce mail for recipients listed in the relocated table that contains contact information for users or domains that no longer exist on the system.

proxymap

Postfix client processes can get read-only access to maps through the proxymap daemon. By sharing a single open map among many Postfix daemons, proxymap circumvents chroot restrictions and reduces the number of open lookup tables.

spawn

The spawn process creates non-Postfix processes on request. It listens on a TCP port, Unix domain socket, or FIFO connected to the standard input, output, and error streams. The only use for spawn discussed in this book is for the Postfix external content filtering system in Chapter 13.

local

As the name suggests, the local daemon is responsible for local mailbox delivery. The Postfix local daemon can write to mailboxes in the mbox and Maildir formats. In addition, local can access data in Sendmail-style alias databases and user .forward files.

Note: These capabilities make local the counterpart to the Sendmail mail posting agent, and they both maintain the same user interface.

As an alternative, local can delegate mailbox delivery to a local delivery agent (LDA) that provides more advanced features, such as filtering. Two very popular LDAs are procmail (www.procmail.org) and maildrop (www.flounder.net/~mrsam/maildrop).

Postfix can run multiple instances of local.

virtual

The virtual daemon, sometimes called the virtual delivery agent, is a stripped-down version of local that delivers exclusively to mailboxes. It is the most secure Postfix delivery agent; it does not perform alias and .forward file expansions.

This delivery agent can deliver mail for multiple domains, making it especially suitable for hosting several small domains on a single machine (a so-called POP toaster) without the need for real system or shell accounts.

smtp

The smtp client is the Postfix client program that transports outbound messages to remote destinations. It looks up destination mail exchangers, sorts the list by preference, and tries each address until it finds a server that responds. A busy Postfix system typically has several smtp daemons running at once.

lmtp

The lmtp client communicates with local and remote mailbox servers with the Local Mail Delivery Protocol (LMTP) defined in RFC 2033 (ftp.rfc-editor.org/in-notes/rfc2033.txt). It is often used with the Cyrus IMAP server (asg.web.cmu.edu/cyrus/imapd).

The advantages of a setup using Postfix's lmtp client are that Postfix handles all of the queue management and one Postfix machine can feed multiple mailbox servers (which need to have an LMTP daemon) over LMTP. The opposite is also true: several Postfix machines can feed one mailbox server through lmtp. These mailbox server(s) could, for example, be running Cyrus IMAP.

pipe

The pipe mailer client is the outbound interface to other mail transport mechanisms. It invokes programs with parameters and pipes the message body into their standard input.

pickup

The pickup daemon picks up messages put into the maildrop queue by the local sendmail user client program. After performing a few sanity checks, pickup passes messages to the cleanup daemon.

smtpd

The smtpd daemon handles communication with networked mail clients that deliver messages to Postfix through SMTP. smtpd performs a number of checks that protect the rest of the Postfix system, and it can be configured to implement unsolicited commercial email (UCE) controls (local or network-based blacklists, DNS lookups, other client requests, and so on).

After accepting a message, smtpd hands the message down to cleanup

cleanup

The cleanup daemon is the final processing stage for new messages. It adds any required missing headers, arranges for address rewriting, and (optionally) extracts recipient addresses from message headers. The cleanup daemon inserts the result into the incoming queue and then notifies the queue manager that new mail has arrived.

sendmail

sendmail is a Postfix command that replaces and emulates Eric Allman's MTA Sendmail. Its purpose is to provide a Sendmail-compatible interface to applications that will only invoke /usr/sbin/sendmail. It interacts with the postdrop binary to put mail into the maildrop queue for pickup.

Note: sendmail is the slowest way to inject mail into the Postfix queue system. If you need to send a large amount of mail at once, use SMTP instead.

qmqpd

The Postfix QMQP server implements the Quick Mail Queuing Protocol (QMQP; see http://cr.yp.to/proto/qmqp.html) to make Postfix compatible with qmail and the ezmlm list manager.

anvil

The Postfix anvil is a preliminary defense against SMTP clients and denial-of-service attacks that swamp the SMTP server with too many simultaneous or successive connection attempts. It comes with a whitelist capability for disabling restrictions for authorized clients. anvil is not included with Postfix 2.1, but it is available in the Postfix 2.2 experimental release. anvil will stay experimental until there is enough experience with Postfix rate limiting.

Postfix Queues

Postfix polls all queues in the directory specified by the queue_directory parameter in your main.cf file. The queue directory is usually /var/spool/postfix. Each queue has its own subdirectory with a name identifying the queue. All messages that Postfix handles stay in these directories until Postfix delivers them. You can determine the status of a message by its queue: incoming, maildrop, deferred, active, hold, or corrupt.

incoming

All new messages entering the Postfix queue system get sent to the incoming queue by the cleanup service. New queue files are created with the postfix user as the owner and an access mode of 0600. As soon as a queue file is ready for further processing, the cleanup service changes the queue file mode to 0700 and notifies the queue manager that new mail has arrived. The queue manager ignores incomplete queue files whose mode is 0600.

The queue manager scans the incoming queue when moving new messages into the active queue and makes sure that the active queue resource limits have not been exceeded. By default, the active queue has a maximum of 20,000 messages.

Caution: Once the active queue message limit is reached, the queue manager stops scanning the incoming and deferred queues.

maildrop

Messages submitted with the sendmail command that have not been sent to the primary Postfix queues by the pickup service await processing in the maildrop queue. You can add messages to the maildrop queue even when Postfix is not running; Postfix will look at them once it is started.

The single-threaded pickup service scans and drains the maildrop queue periodically, as well as upon notification from the postdrop program. The postdrop program is a setgid helper that allows the unprivileged sendmail program to inject mail into the maildrop queue and notify the pickup service of message arrival. (All messages that enter the main Postfix queues do so via the cleanup service.)

deferred

If a message still has recipients for which delivery failed for some transient reason, and the message has been delivered to all the recipients possible, Postfix places the message into the deferred queue.

The queue manager scans the deferred queue periodically to put deferred messages back into the active queue. The scan interval is specified with the queue_run_delay configuration parameter. If the deferred and incoming queue scans happen to take place at the same time, the queue manager alternates between the two queues on a per-message basis.

active

The active queue is somewhat analogous to an operating system's process run queue. Messages in the active queue are ready to be sent, but are not necessarily in the process of being sent.

The queue manager is a delivery agent scheduler that works to ensure fast and fair delivery of mail to all destinations within designated resource limits.

Note: Although most Postfix administrators think of the active queue as a directory on disk, the real active queue is a set of data structures in the memory of the queue manager process.

hold

The administrator can define smtpd access(5) policies and cleanup header and body checks (see Chapter 10) that cause messages to be automatically diverted from normal processing and placed indefinitely in the hold queue. Messages placed in the hold queue stay there until the administrator intervenes. No periodic delivery attempts are made for messages in the hold queue. You can run the postsuper command to manually put messages on hold or to release messages from the hold queue into the deferred queue.

Messages can potentially stay in the hold queue for a time that exceeds the queue file lifetime set by the maximal_queue_lifetime parameter (after which undelivered messages are bounced to the sender). If older messages need to be released from the hold queue, you can use postsuper -r to move them into the maildrop queue, so that the message gets a new timestamp and is given more than one opportunity to be delivered.

Note: The hold queue doesn't play much of a role in Postfix performance; monitoring of the hold queue is typically motivated by tracking spam and malware rather than by performance issues.

corrupt

The corrupt directory contains damaged queue files. Rather than discarding these, Postfix stores them here so that the (human) postmaster can inspect them using postcat.

Postfix logs a warning about any corrupt files upon startup.

Maps

Maps are files and databases that Postfix uses to look up information. Maps have many different purposes, but they all have one thing in common--a left-hand side (LHS, or key) and a right-hand side (RHS, or value).

Here are a few examples of keys and values:

KeyValue
postmaster:john
postmaster@example.comjohn
192.168.254.12REJECT
spammer@example.comREJECT
/^Subject: your account {25}[a-z]{8}/REJECT Mimail Virus Detected

To use a map, you specify a key and get the associated value as a result.

Note: The keys and values here come from various files and would not make sense in one file. The preceding list is just an illustration to show that all map entries take the same basic form.

Map Types

Postfix can use many different kinds of maps. The formats available depend on the way Postfix was compiled on your particular system. To find out what formats your Postfix supports, run postconf -m on the command line. You should get a list of map types:

# postconf -m
btree
cdb
cidr
environ
hash
ldap
mysql
nis
pcre
proxy
regexp
sdbm
static
tcp
unix

Indexed Maps (hash, btree, dbm, and So On)

Indexed maps are binary databases built from regular text files with commands such as newaliases, postalias, and postmap. The binary maps have an indexed format so that Postfix can quickly retrieve the value associated with a key. As a further performance improvement, the Postfix daemons open these maps when starting up, and they do not re-read them unless they notice a change in the map files in the filesystem. To reload a map, a daemon exits and a new one is started by the master daemon.

Note:

If you have indexed maps that change frequently, the daemons using these maps will restart just as often. Under a heavy load, this can lead to performance problems.

The most common indexed maps are built from the aliases, virtual, transport, relocated, and sasl_passwd text files. You can identify a map file because its name is the original file with a suffix that also tells you the index format. For example, an aliases map file built with the postalias command is named aliases.db.

Note:

When you create a file in order to build an indexed map from it you don't have to put keys in a specific order. The conversion tools and programs that use indexed maps do not require a specific order for input. In fact, the process of conversion removes the ordering.

Postfix queries entries in a predefined order specified in the manual pages for the tables (access(5), transport(5), virtual(5), aliases(5) and canonical(5)). In other words, each map lookup actually consists of a series of single queries (derived from the original query) on single keys in the indexed map.

Linear Maps (PCRE, regexp, CIDR, and Flat Files)

Linear maps are regular text files. Postfix reads these files from top to bottom, making them different from indexed maps. This difference is quite important, because the first match in the file determines the action that Postfix will take. Postfix ignores any later entries, whether they match the query or not.

Consider the following regexp map, where a john.doe@example.com lookup returns OK, because the first line matches.

/john\.doe@example\.com/ OK
/example\.com/ REJECT

However, if you swap the lines in the regexp map, the other entry matches first, so the same john.doe@example.com lookup returns REJECT:

/example\.com/ REJECT
/john\.doe@example\.com/ OK

You do not need to convert linear maps to a binary form (in fact, you can't do it). The Postfix daemons read them at startup and do not notice any changes to the map until they are restarted. Typical Postfix linear maps include header_checks, body_checks, and mime_header_checks (see Chapter 9).

Caution:

As your linear maps grow, it takes longer for the Postfix daemons to process them. This is especially true with respect to body or header checks, because the cleanup daemon needs to check every line of the body (up to body_checks_size_limit) and headers against every line of the map.

This can cause a significant slowdown, especially if you have extensive *_checks parameters that use regexp or PCRE (Perl-compatible regular expression) type maps in order to prevent spam from entering the system. When this happens, it's usually time to hand complex spam filtering to an external application.

To make the Postfix daemons notice changes in linear maps, run postfix reload. If the timing is not critical, you can set the max_use parameter to define a time-to-live for daemons. As soon as a daemon has processed the number of tasks specified in that parameter, it quits and is restarted by master. Upon restart, it re-reads all required maps.

Databases (MySQL, PostgreSQL, LDAP)

Postfix treats a database just like an indexed map. The result of a database query is Match (along with the value returned by the query) or No match. The principal difference between a database map and an indexed map is that you do not need to restart a daemon when there is a change to the database. Postfix does not assume that the postmaster is the only person who can alter the database.

The drawback to this approach is that the database may not be able to handle the number of queries gracefully, because Postfix needs to perform at least three queries for each lookup in a map (see the "See How Postfix Queries Maps" section that follows). Under heavy load, the database backend could stop working, and your mail service would be vulnerable to a self-induced meltdown or a denial-of-service attack. This possibility should not prevent you from using database backends, but you should be aware of the risk.

Database lookups can become a problem for systems with a heavy load, but this isn't the only issue to consider--latency can be another problem. Database queries have a higher latency than indexed maps because Postfix must connect to the database backend, send the query, and then wait for the result. With an indexed map, Postfix has only to consult data that is already loaded in memory.

If your database becomes a bottleneck, and you do not have an excessively large map, you can insert a map between the database and Postfix. That is, you can create an indexed map from a complete database query, and then run Postfix with that map. You need to remember to update the map as often as necessary, but the proxymap daemon can be used to significantly reduce the number of concurrent connections.

Determining the Number of Simultaneous Connections to a Database

Postfix daemons (smtpd, smtp, and so on) run with a process limit (set by default_process_limit) of 100 simultaneous processes. Running at peak load, there would be 100 concurrent smtpd daemons, each querying the database backend for one access(5) lookup (e.g., because we use a map for checking if the client is in our personal blacklist and should then be denied from sending mail to us).

Remember that one lookup results in at least three queries, so the number of simultaneous queries to the database would be at least default_process_limit * 3 (which, in the default configuration, would be 300 queries), while the number of simultaneous connections is default_process_limit. This is only the number of queries and connections for smtpd daemons; other daemons, such as local and qmgr, may be working on other jobs, adding to the number of open connections and simultaneous queries.

How Postfix Queries Maps

Maps can be used for various tasks. Postfix has table-driven mechanisms that use maps (see access(5), aliases(5), canonical(5), and transport(5)). These maps can use different lookup mechanisms (LDAP, NIS, SQL, btree, hash, regexp, cdb, cidr, pcre, and so on). Note that the lookup order described below only applies to access(5) type maps.

  1. <localpart@domainpart> Matches the specified mail address verbatim.

  2. <domainpart> Matches domainpart as the domain part of an email address. The pattern domainpart also matches subdomains, but only when the string smtpd_access_maps is listed in the Postfix parent_domain_matches_subdomains configuration setting. Otherwise, specify .domainpart (note the initial dot) to match subdomains.

  3. <localpart@> Matches all mail addresses with the specified user part (localpart), no matter what domain they belong to.

  4. Fail If the lookups don't match, Postfix will return no match found, and the query ends with an error.

Note:

It isn't possible to look up a null sender address in some lookup table types. By default, Postfix uses <> as the lookup key for the null sender address. The value is specified with the smtpd_null_access_lookup_key parameter in the main.cf file.

This order of lookups implies that Postfix performs several lookups for each query, which isn't really a problem unless you're using high-latency maps like SQL or LDAP maps (and, of course, you should expect that a lot of lookups will need multiple queries). This is just one thing to remember before you put all your maps into LDAP and then complain on the postfix-users mailing list that "Postfix is slow. . . ."

External Sources

Postfix supports information sources that are not built on top of Postfix and that aren't even under your direct control, such as blacklists (DNSBL and RHSBL lists), DNS-based lists, and other external sources. Blacklists are almost exclusively used in smtpd_*_restrictions parameters in order to reject mail coming from clients or senders listed in DNSBL- or RHSBL-style lists (see Chapter 7).

As with any external query, these lookups can fail due to connectivity problems, denial-of-service attacks against the blacklist servers, and other problems. In case of a timeout or other failure, Postfix may still accept mail (bypassing a possible restriction), but it will log an appropriate warning to the mail log.

Command-Line Utilities

Postfix ships with a number of command-line utilities to assist you with administration tasks. Although they perform different functions (such as querying maps, examining queue files, dequeuing and requeuing messages, and changing the configuration), they all have one thing in common--their names start with "post."

Note:

These commands can do much more than what is described here. We are focusing on the options that you will experience in day-to-day operation. If you don't find what you are looking for here, the first place to look is the online manual.

postfix

The postfix command stops, starts, and reloads the configuration with the stop, start, and reload options.

postalias

The postalias command creates an indexed alias map from an alias file. It works just like the postmap command (described shortly), but it pays special attention to the notation in an alias file (where a colon separates the key and value). postalias must be used on alias files.

postcat

The postcat command displays the content of a message in a mail queue.

To read a message in a mail queue, you need its queue ID. Run mailq for a list of queue IDs. For example, the queue ID of the following message is F2B9715C0B3:

# mailq
F2B9715C0B3 2464 Mon Oct 13 15:29:39 markus.herrmann@example.com
            (connect to mail.example.com[217.6.113.151]: Connection timed out)
            torsten.hecke@example.net
-- 2 Kbytes in 1 Requests.

After obtaining a queue ID, use it as an option to postcat to see the contents of the queue file:

# postcat -q F2B9715C0B3

postmap

The postmap command's primary purpose is to build indexed maps from flat files. For example, to build /etc/postfix/virtual.db from /etc/postfix/virtual, run the following command.

# postmap hash:/etc/postfix/virtual

The postmap command can do more. Among its most useful features is the ability to test any kind of map that your Postfix installation supports. This is extremely helpful when debugging a configuration where lookups to the maps appear to fail, and you are unsure whether the key and value are actually visible to Postfix.

Debugging an Entry in a Lookup Table

To determine whether Postfix can find an entry in a map, use postmap -q. For example, the following command returns the value assigned to the key <sender@example.com> in the map /etc/postfix/sender_access (type hash):

# postmap -q sender@example.com hash:/etc/postfix/sender_access
OK

It's important to note that postmap does not look for the terms <sender@>, <example.com>, and <com>, even though these terms are in the access(5) manual page. You need to perform those lookups manually:

# postmap -q sender@ hash:/etc/postfix/sender_access
# postmap -q example.com hash:/etc/postfix/sender_access
# postmap -q com hash:/etc/postfix/sender_access

postdrop

The postdrop command reads mail from the standard input and drops the result into the maildrop directory. This program works in conjunction with the sendmail utility.

postkick

The postkick command sends a request to a Postfix daemon through a local transport channel, making Postfix interprocess communication accessible to shell scripts and other programs.

Note:

The postkick command sends messages to Postfix daemon processes. This requires that Postfix is running.

Requeuing a Message

The following advanced postkick example shows how to requeue a message for immediate redelivery:

# cat queueidlist | postsuper -r -
postkick public pickup W

This sequence of commands moves all selected messages listed in queueidlist to the maildrop queue with the postsuper -r - command, where the pickup daemon would process them like any other piece of mail. By doing this, you reset the content filter to the setting appropriate for local submission and add an extra Received: header.

The postkick command requests an immediate maildrop queue scan. Otherwise, the messages would stay in the maildrop queue for a maximum of 60 seconds. The pickup daemon submits the message to the cleanup daemon, where it gets a new queueid and is deposited into the incoming queue. The whole point is to move the message to the active queue as quickly as possible.

postlock

The postlock command gives you exclusive access to mbox files that Postfix writes, and then it runs a command while holding the lock. The lock you get from postlock is compatible with the Postfix local delivery agent. Postfix does not touch the file while your command executes. Here is an example:

# postlock /var/mail/user from

Caution:

Try to avoid any commands that might require a ctrl-C to terminate. Interrupting postlock does not guarantee that the lock will go away; you may need to remove a lock file to deliver to the mailbox again. To see if there is a lingering lock file, run postlock without a command. If this hangs and eventually times out, you probably have a leftover lock.

postlog

The postlog command allows external programs, such as shell scripts, to write messages to the mail log. This is a Postfix-compatible logging interface; by default, it logs the text from the command line as a single record. Here's a very simple example:

# postlog This is a test
postlog: This is a test
# grep "This is a test" /var/log/mail.log
Feb 20 11:50:16 mail postlog: This is a test

postqueue

The postqueue command is a user interface to Postfix queues, giving you functionality that is traditionally available with the sendmail command.

  1. The -f parameter makes postqueue request the queue manager to deliver all queued mail (flush), regardless of destination. This is equivalent to postfix flush or sendmail -q:

    # postqueue -f
  2. The -p parameter makes postqueue print the contents of the queue. It is equivalent to mailq:

    # postqueue -p
  3. The -s domain parameter makes postqueue attempt to deliver all queued mail bound for domain. This is equivalent to sendmail -q domain:

    # postqueue -s example.com

Note:

The postqueue command sends messages to Postfix daemon processes. This requires that Postfix is running.

postsuper

The postsuper command maintains jobs inside Postfix queues. Unlike postqueue, this command is restricted to the superuser, and it can run while Postfix is down. Some postsuper features are needed to check the queue before daemon processes are started. Table 5-1 shows what the postsuper command can do.

Table 5-1: Capabilities of the postsuper Command

OptionAction
-dDelete a message with the named queue ID from the named mail queue(s)
-hPlace a message on hold so that no attempt is made to deliver it
-HRelease mail currently on hold
-pPurge temporary files left over from crashes
-rRequeue messages with a named queue ID from a named mail queue
-sCheck and repair the queue structure

One of the most frequent uses of postsuper is deleting a message from the mail queue with postsuper -d queueid. Doing this manually is tedious, especially when deleting many files. The following Perl script (delete_from_mailq) makes it easier:

#!/usr/bin/perl
$REGEXP = shift || die "no email-address given (regexp-style, e.g. bl.*\@yahoo.com)!";
@data = qx</usr/sbin/postqueue -p>;
for (@data) {
	if (/^(\w+)(\*|\!)?\s/) {
		$queue_id = $1;
	}
	if($queue_id) {
		if (/$REGEXP/i) {
			$Q{$queue_id} = 1;
			$queue_id = "";
		}
	}
}
#open(POSTSUPER,"|cat") || die "couldn't open postsuper" ;
open(POSTSUPER,"|postsuper -d -") || die "couldn't open postsuper" ;
foreach (keys %Q) {
	print POSTSUPER "$_\n";
};
close(POSTSUPER);

Here's how you'd use it:

# mailq
C73A015C095     7509 Mon Oct 13 14:56:17 MAILER-DAEMON
	(connect to mx5.ancientaward.com[64.156.166.211]: Connection refused)
 
National_Nosepicking_Month@mx5.ancientaward.com

Notice that the sender is identified as <MAILER-DAEMON> here. To remove these bounces, run delete-from-mailq as root:

# delete-from-mailq MAILER-DAEMON
postsuper: C73A015C095: removed
postsuper: Deleted: 1 message

About the Authors:

Ralf Hildebrandt and Patrick Koetter are active and well-known figures in the Postfix community. Hildebrandt is a systems engineer for T-NetPro, a German telecommunications company, and Koetter runs his own company consulting and developing corporate communication for customers in Europe and Africa. Both have spoken about Postfix at industry conferences and contribute regularly to a number of open source mailing lists.

No Starch Press has more information on the book here: www.nostarch.com/postfix.htmThe authors maintain an errata and download page for the book, which you might want to check out at: www.postfix-book.com/errata.html


         The book of Postfix: state-of-the-art message transport
         by Ralf Hildebrandt & Patrick Koetter
         Copyright 2005, 464 pages
         ISBN 1-59327-001-1
         No Starch Press (http://www.nostarch.com)
      

Load Disqus comments