Postfix, Message Flows, and Common Issues


Postfix

Postfix is a free and open-source mail transfer agent (MTA) that routes and delivers electronic mail. It is intended as a fast, easier-to-administer, and secure alternative to the widely-used Sendmail MTA. Postfix is released under the IBM Public License 1.0 which is a free software licence. It was originally written in 1997 by Wietse Venema at the IBM Thomas J. Watson Research Center and first released in December 1998, Postfix continues as of 2012 to be actively developed by its creator and other contributors. The software is also known by its former names VMailer and IBM Secure Mailer.

Postfix has many features including many of the most common ones you are already familiar with, including TLS, SSL, M-box and Maildir support. In addition to these options Postfix also supports envelope rewriting, database mapping (MySQL, PostgreSQL, SQLite, LDAP, and more.), perl regular-expressions, delegation of SMTP policy, milters, and is IPV6 Compatible. Postfix is written and maintained by a prolific Unix security software author. Releases come in bursts, with some releases containing only very small improvements. Postfix has a monolithic main configuration file similar to Sendmail and it is generally table-driven. Thus the reason that Postfix supports a number of different database types. These databases or tables can contain  everything from list of legitimate users and networks to transport lists (routes) and virtual mailboxes.

Postfix has a strong emphasis on security, but not to the extent of imposing unusual Unix management practices. The Sendmail team explicitly acknowledges Postfix as an influence on their next-generation replacement for Sendmail, Postfix has a particular resilience against buffer overflows and can handle large amounts of e-mail fairly well. A Postfix system implements a cooperating  network of different daemons and each daemon fulfills a single task using a minimum level of privileges. In this way, if a single daemon is compromised, the impact remains limited to that daemon and cannot spread throughout the entire system. Only one process has root level access on a system (master), and few processes actually write to locations outside of the queue directory or invoke external programs. Most daemons can be easily chrooted and communicate through named pipes or UNIX-domain sockets.

See the man pages or online documentation for additional details.

http://www.postfix.org/documentation.html

Basic Message Flows

Diagram1

Master

Mail that is processed by Postfix is pushed through several daemons, queues and clients. Each daemon, Queue, or client performs a specific task or delivery type and is a required part of  message transport on a Postfix system. All of these systems run under Postfix's master process.The master daemon is the resident process that runs Postfix daemons on demand: daemons  to send or receive messages via the network, daemons to deliver mail locally, daemons to process envelope clean-up and message routing. These daemons are created on demand by the  Master process, up to a configurable maximum number per service. Postfix daemons terminate voluntarily, either after being idle for a configurable amount of time, or after having serviced a  configurable number of requests.The best way to look at the Master process, is to consider it a container for all of the sub-proccess that spawn during message delivery.

warning Exceptions to this rule are the resident queue manager, address verification server, and the TLS session cache and pseudo-random number server.

The behavior of the master daemon is controlled by the master.cf configuration file and its options.

 

Incoming Mail Handlers

smtpd_qmpd_pickup

Smtpd

The SMTP server accepts network connection requests and performs zero or more SMTP transactions per connection. Each received message is piped through the cleanup daemon, and is placed into the incoming queue as one single queue file. For this mode of operation, the program expects to be run from the master process manager. Alternatively, the SMTP server be can run in stand-alone mode; this is traditionally obtained with "sendmail -bs". When the SMTP server runs stand-alone with non $mail_owner privileges, it receives mail even while the mail system is not running, deposits messages directly into the maildrop queue,and disables the SMTP server's access policies. The SMTP server implements a variety of policies for connection requests, and for parameters given to HELO, ETRN, MAIL FROM, VRFY and RCPT TO commands.

If SMTPD runs in a standalone mode it uses the maildrop queue.

Qmqpd

The Postfix (Quick Mail Queuing Protocol) QMQP server receives one message per connection. Each message is piped through the cleanup daemon, and is placed into the incoming queue as one single queue file. The program expects to be run from the master process manager.

This system will perform one transaction per connection and is designed to provide a centralized mail Queue system in a clustered environment. The QMQPD system will only communicate with QMQP clients. QMQP is faster than SMTP as it only handles full formed messages and envelops. QMQP can handle as many as 1000 messages in a 10 second time span over a 28.8k connection. You will probably never see this on our network but it is good to be familiar with all of the functioning components of Postfix.

Pickup

The pickup daemon waits for hints that new mail has been dropped into the maildrop directory, and feeds it into the cleanup daemon. Mail is generally added to the maildrop queue by local processes and the commands such as mail or sendmail.

warning Ill-formatted files that are dropped into this queue are deleted by the Pickup process without notifying the originator of the message. If mail is vanishing from a phpmailer its possible that the Pickup process is involved.

Cleanup

cleanup.pngThe cleanup daemon processes inbound mail, inserts it into the incoming mail queue, and informs the queue manager of its arrival.

The cleanup daemon always performs the following transformations:

  • Insert missing message headers: (Resent-) From:, To:, Message-Id:, and Date:.
  • Transform
    envelope and header addresses to the standard
    user@fully-qualified-domain form that is expected by other Postfix
    programs. This task is delegated to the trivial-rewrite daemon.
  • Eliminate duplicate envelope recipient addresses.

The following address transformations are optional:

  • Optionally, rewrite all envelope and header addresses according to the mappings specified in the canonical look up tables.
  • Optionally, masquerade envelope sender addresses and message header addresses (i.e. strip host or domain information below all domains listed in the  masquerade_domains parameter, except for user names listed in masquerade_exceptions). By default, address masquerading does not affect envelope  recipients.
  • Optionally, expand envelope recipients according to information found in the virtual look up tables.

The cleanup daemon performs sanity checks on the content of each message. When it finds a problem, by default it returns a diagnostic status to the client, and leaves it up to the client to deal with the problem. Alternatively, the client can request the cleanup daemon to bounce the message back to the sender in case of trouble.

 

Trival-rewrite

The trivial-rewrite daemon processes three types of client service requests. This daemon appears in two different steps of the message flow. Its first appearance is  during the Clean up Process. Here it ensures that the envelope information is up to date and complete as delegated by the Clean up Daemon. Later in the message  flow this daemon appears again and interacts directly with the Queue Manager to verify sender addresses, resolve those addresses, and determine any relevant information associated with transport and delivery of the message.

  • Rewrite context address
    Rewrite an address to standard form, according to the address rewriting context.
  • Resolve sender address
    Resolve the address to a (transport, next-hop, recipient, flags) quadruple.
  • Verify sender address
    Resolve the address for address verification purposes.

 

Primary Message Queues

message_queues.pngThere are several queues that are part of Postfix though the ones to the left are the primary ones you will interact with. These queues are at the heart of Postfix's delivery process and are a critical subsystem. Unlike Exim all of the messages are stored in queues that represent their state in the message delivery process. These queues are monitored and managed by the Queue Management Daemon or QMGR. (As seen in the Message Flow Diagram)

If any single queue that is part of the active delivery process encounters a problem, that problem will create a domino effect on other queues within the system.

Incoming Queue

All new mail entering the Postfix queue is written by the cleanup service into the "incoming" queue. New queue files are created and owned by the  "Postfix" user with an access bitmask (or mode) of 0600. Once a queue file is ready for further processing the cleanup service changes the queue file  mode to 0700 and notifies the queue manager of new mail arrival.

The queue manager ignores incomplete queue files whose mode is 0600, as these are still being written by cleanup.

The queue manager scans the incoming and deferred queues bringing any new mail into the "active" queue if the active queue resource limits have not been exceeded. By default, the active queue accommodates at most 20,000 messages. Once the active queue message limit is reached, the queue manager stops scanning the incoming (and deferred) queue.

Under normal conditions the incoming queue is nearly empty (Has only mode 0600 files), with the queue manager able to import new
messages into the active queue as soon as they become available.
The incoming queue grows when the message input rate spikes above the rate at which the queue manager can import messages into the active queue.

 

Factors that affect the performance of this Queue
  • I/O Performance
    If the problem is I/O starvation, consider striping the queue over more disks, faster controllers with a battery write cache, or other hardware improvements. At the very least, make sure that the queue directory is mounted with the "noatime" option if applicable to the underlying filesystem.
  • Lookups for Queuing and Routing
    If the queue manager is routinely not keeping up, consider not using "slow" look up services (MySQL, LDAP, ...) for transport look ups or speeding up the hosts that provide the look up  service.
  • in_flow_delay Parameter
    In addition to I/O and look up performance the in_flow_delay parameter is used to clamp the input rate when the queue manager starts to fall behind. The cleanup service will pause for  $in_flow_delay seconds before creating a new queue file if it cannot obtain a "token" from the queue manager.Since the number of cleanup processes are limited in most cases by the SMTP server concurrency, the input rate to the system can exceed the output rate of the system by at most:

    "SMTP connection count" / $in_flow_delay messages per second

    warning With a default process limit of 100, and an in_flow_delay of 1s, the coupling is strong enough to limit a single run-away injector to 1 message per second, but is not strong enough to deflect an excessive input rate from many sources at the same time. If a server is being hammered from multiple directions, consider raising the in_flow_delay to 10 seconds, but only if the incoming queue is growing even while the active queue is not full and the trivial-rewrite service is using a fast transport look up mechanism.

Active Queue

The active queue is somewhat analogous to an operating system's process run queue. Messages in the active queue are ready to be sent (runnable), but are not necessarily in the process of being sent (running). Messages in the "maildrop", "hold", "incoming" and "deferred" queues do not occupy memory; they are safely stored on disk waiting for their turn to be processed. The envelope information for messages in the "active" queue is managed in memory, allowing the queue manager to do global scheduling, allocating available delivery agent processes to an appropriate message in the active queue.

Within the active queue, (multi-recipient) messages are broken up into groups of recipients that share the same transport/next-hop combination; the group size is capped by the transport's recipient concurrency limit.Multiple recipient groups (from one or more messages) are queued for delivery grouped by transport/next-hop combination. The destination concurrency limit for the transports caps the number of simultaneous delivery attempts for each nexthop. Transports with a recipient concurrency limit of 1 are special: these are grouped by the actual recipient address rather than the next-hop, yielding per-recipient concurrency limits rather than per-domain concurrency limits. Per-recipient limits are appropriate when performing final delivery to mailboxes rather than when relaying to a remote server.

warning Most administrators think of the "active" queue as a directory on disk, while there is an active queue on disk, the real "active" queue is a set of data structures in the memory space of the queue management process. It is extremely important to remember this when working with Postfix.

Whenever the queue manager is restarted, there may already be messages in the active queue directory, but the "real" active queue that is in memory will be emptied. In order to recover the in-memory state, the queue manager moves all of the messages back into the incoming queue, then uses its normal incoming queue scan to refill the active queue. The process of moving all the messages back and forth, redoing the transport table (trivial-rewrite resolve service) look ups, and re-importing the messages back into memory is expensive. At all costs, avoid frequent restarts of the queue manager (e.g. via frequent execution of "postfix reload").

 

Factors that affect the performance of this Queue
  • Congestion occurs in the active queue when one or more destinations drain slower than the corresponding message input rate.
    Input into the active queue comes both from new mail in the "incoming" queue, and retries of mail in the "deferred" queue. Should the "deferred" queue get really large, retries of old mail can dominate the arrival rate of new mail. When a destination is down for some time, the queue manager will mark it dead, and immediately defer all mail for the destination without trying to assign it to a delivery agent. In this case the messages will quickly leave the active queue and end up in the deferred queue (Postfix ≥ 2.4 this is done via the "retry" delivery agent).When the destination is instead simply slow, or there is a problem causing an excessive arrival rate the active queue will grow and will become dominated by mail to the congested destination. The only way to reduce congestion is to either reduce the input rate or increase the throughput. Increasing the throughput requires either increasing the concurrency or reducing the latency of deliveries.For high volume sites a key tuning parameter is the number of "SMTP" delivery agents allocated to the "SMTP" and "relay" transports. High volume sites tend to send to many different destinations, many of which may be down or slow, so a good fraction of the available delivery agents will be blocked waiting for slow sites. Also mail destined across the globe will incur large SMTP command-response latencies, so high message throughput can only be achieved with more concurrent delivery agents. The default "SMTP" process limit of 100 is good enough for most sites, and may even need to be lowered for sites with low bandwidth connections.
  • High Average Latency to the destination.
    When one finds that the queue is growing on an "idle" system (CPU, disk I/O and network not exhausted) the remaining reason for congestion is insufficient concurrency in the face of a high average latency. If the number of outbound SMTP connections (either ESTABLISHED or SYN_SENT) reach the process limit, mail is draining slowly and the system and network are not loaded, raise the "SMTP" and/or "relay" process limits. When a high volume destination is served by multiple MX hosts with typically low delivery latency, performance can suffer dramatically when one of the MX hosts is unresponsive and SMTP connections to that host timeout.

    For example, if there are 2 equal weight MX hosts, the SMTP connection timeout is 30 seconds and one of the MX hosts is down,the average SMTP connection will take approximately 15 seconds to complete. With a default per-destination concurrency limit of 20 connections, throughput falls to just over 1 message per second.

    The best way to avoid bottlenecks when one or more MX hosts is non-responsive is to use connection caching. Connection caching was introduced with Postfix 2.2 and is by default enabled on demand for destinations with a backlog of mail in the active queue. When connection caching is in effect for a particular destination, established connections are re-used to send additional messages, this reduces the number of connections made per message delivery and maintains good throughput even in the face of partial unavailability of the destination's MX hosts.

  • Another common cause of congestion is unwarranted flushing of the entire deferred queue.
    The deferred queue holds messages that are likely to fail to be delivered and are also likely to be slow to fail delivery (time out). As a result the most common reaction to a large deferred queue (flush it!) is more than likely counter-productive, and typically makes the congestion worse. It can also cause extreme load conditions or I/O Lock conditions. Do not flush the deferred queue unless you expect that most of its content have recently become deliverable !

warning Do not set aggressive concurrency limits to remote domains without coordinating with the administrators of the target domain.

Setting high concurrency limits to domains that are not your own may be viewed as hostile by the receiving system, and steps may be taken to prevent you from monopolizing the destination system's resources. The defensive measures may substantially reduce your throughput or block access entirely. If necessary, dedicate and tune custom transports for selected high volume destinations. The "relay" transport is provided for forwarding mail to domains for which your server is a primary or backup MX host. These can make up a substantial fraction of your email traffic.
Use the "relay" and not the "SMTP" transport to send email to these domains. Using the "relay" transport allocates a separate delivery agent pool to these destinations and allows separate tuning of timeouts and concurrency limits.

 

Deferred Queue

When all the deliverable recipients for a message are delivered, and for some recipients delivery failed for a transient reason (it might succeed later), the message is placed in the deferred queue. The queue manager scans the deferred queue periodically on its own. The scan interval is controlled by the queue_run_delay parameter. While a deferred queue scan is in progress, if an incoming queue scan is also in progress (ideally these are brief since the incoming queue should be short), the queue manager alternates between looking for messages in the "incoming" queue and in the "deferred" queue. This "round-robin" strategy prevents starvation of either the incoming or the deferred queues. Each deferred queue scan only brings a fraction of the deferred queue back into the active queue for a retry. This is because each message in the deferred queue is assigned a "cool-off" time when it is deferred.

The "cool-off" period is set on each messages by time-warping the modification time of the queue file to a future date and time. The queue file or message is not eligible for a retry if its modification time is not yet reached. The next retry time is set by doubling the message's age in the queue, and adjusting up or down to lie within the limits specified in the systems configuration. This means that young messages are initially retried more often than older messages.

If a high volume site routinely has large deferred queues, it may be useful to adjust the queue_run_delay, minimal_backoff_time and maximal_backoff_time to provide short enough delays on first failure (Postfix ≥ 2.4 has a sensibly low minimal back off time by default), with perhaps longer delays after multiple failures, to reduce the re-transmission rate of old messages and thereby reduce the quantity of previously deferred mail in the active queue. If you want a really low minimal_backoff_time, you may also want to lower queue_run_delay, but understand that more frequent scans will increase the demand for disk I/O.

Factors that affect the performance of this Queue
  • One common cause of large deferred queues is failure to validate recipients at the SMTP input stage.
    Since spammers routinely launch dictionary attacks from un-repliable sender addresses, the bounces for invalid recipient addresses clog the deferred queue (and at high volumes proportionally clog the active queue). Recipient validation is strongly recommended through use of the local_recipient_maps and relay_recipient_maps parameters. Even when bounces drain quickly they inundate innocent victims of forgery with unwanted email. To avoid this, do not accept mail for invalid recipients.
  • When a host with lots of deferred mail is down for some time, it is possible for the entire deferred queue to reach its retry time simultaneously.
    This can lead to a very full active queue once the host comes back up. The phenomenon can repeat approximately every maximal_backoff_time seconds if the messages are again deferred after a brief burst of congestion. Perhaps, a future Postfix release will add a random offset to the retry time (or use a combination of strategies) to reduce the odds of repeated complete deferred queue flushes.

warning Systems with more CPU, faster disks and more network bandwidth can deal with larger deferred queues, but as a rule of thumb the deferred queue scales to somewhere between 100,000 and 1,000,000 messages with good performance unlikely above that "limit". Systems with queues this large should typically stop accepting new mail, or put the backlog "on hold" until the underlying issue is fixed (provided that there is enough capacity to handle just the new mail).

 

Special Queues

Corrupt Queue

The system will automatically place damaged or corrupt Queue files and messages into this Queue for inspection by an administrator. This queue is not monitored or scanned, message here must be manually inspected.

Hold Queue

The administrator can define "SMTPD" access policies, or cleanup header/body checks that cause messages to be automatically diverted from normal processing and placed indefinitely in the "hold" queue. No periodic delivery attempts are made for messages in the "hold" queue. The postsuper command can be used to manually release messages into the "deferred" queue. messages can potentially stay in the "hold" queue longer than $maximal_queue_lifetime. If such "old" messages need to be released from the "hold" queue, they should typically be moved into the "maildrop" queue using "postsuper -r", so that the message gets a new timestamp and is given more than one opportunity to be delivered. Messages that are "young" can be moved directly into the "deferred" queue using "postsuper -H". The "hold" queue plays little role in Postfix performance, and monitoring of the "hold" queue is typically more closely motivated by tracking spam and malware, than by performance issues.

warning Messages placed in the "hold" queue stay there until the administrator intervenes.

Queue Manager

qmgr_clients.jpgThe qmgr daemon awaits the arrival of incoming mail and arranges for its delivery via Postfix delivery processes.

The Queue Manager scans for mail in the incoming queue and deferred queue.

  • Schedules messages for delivery and moves mail into the “real” active queue.
  • It delegates message routing to the TRIVIAL-REWRITE (Resolver) daemon.
  • Mail addressed to the local double-bounce address is logged and discarded. This stops potential loops caused by undeliverable bounce notifications and message probes.

 

Clients

Local

The local daemon processes delivery requests from the Postfix queue manager to deliver mail to local recipients. Each delivery request specifies a queue file, a sender address, a domain or host to deliver to, and one or more recipients. This program expects to be run from the master process manager. The local daemon updates queue files and marks recipients as finished, or it informs the queue manager that delivery should be tried again at a later time. Delivery status reports are sent to the bounce, defer or trace daemon as appropriate.

Smtp & Lmtp

The Postfix SMTP+LMTP client implements the SMTP and LMTP mail delivery protocols. It processes message delivery requests from the queue manager. Each request specifies a queue file, a sender address, a domain or host to deliver to, and recipient information. This program expects to be run from the master process manager. The SMTP+LMTP client updates the queue file and marks recipients as finished, or it informs the queue manager that delivery should be tried again at a later time. Delivery status reports are sent to the bounce, defer or trace daemon as appropriate. The SMTP+LMTP client looks up a list of mail exchanger addresses for the destination host, sorts the list by preference, and connects to each listed address until it finds a server that responds. When a server is not reachable, or when mail delivery fails due to a recoverable error condition, the SMTP+LMTP client will try to deliver the mail to an alternate host.

 

Common issues

Log Files

On most installations it should be at /var/log/maillog.

Postfix stops randomly on OpenVZ or Virtuzzo

Postfix makes a lot of local socket connections between its various daemons, and the number of sockets opened is proportional to the activity level of the mail server (more messages = more sockets). This is better illustrated or better understood when you look at the way in which Postfix is designed to operate. The basic message flow diagram shows you that many of the task are broken apart and assigned to other daemons which handle those specific task. If you are running openVZ or Virtuizzo you may need to increase the value of "numothersock".

When this limit is reached, Postfix will fail completely and will show as "stopped":

$ service postfix status

Check /proc/user_beancounters and check the current numothersock usage and if it has any failures. If so, raise the "numothersock" parameter to something significantly higher (I like to use 768 or 1024 ) and then restart Postfix to solve the issue.

This is something you will see on Virtualized systems which limit sockets rather than dedicated servers. The socket limits are generally far higher though it is still something that should be considered in dedicated server environments that run Postfix as it may indicate a bottleneck especially under heavy load conditions.

Enabling port 26

Open /etc/postfix/master.cf and add the following line under the first un-commented line (starts with "smtp inet"):

0.0.0.0:26  n - n - - smtpd

Restart Postfix to enable the changes. The commented "submission" line and the three -o lines immediately following can be un-commented to enable the standard SMTP submission port (587). Keep in mind that if you have other milters or recipent restrictions you may need to include those as well.

Viewing and Managing the Queue

Get the contents of the queue

To check a mail queue, use postqueue -p or mailq. To get a queue size, take the last line like mailq | tail -n1.

root@localhost [~]$ postqueue -p 
 
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient------- 
47E2611D880D9*  353152 Wed Oct 12 12:46:53  [email protected] 
                                            [email protected] 
 
7A1E511D880D3*  354656 Wed Oct 12 11:35:29  [email protected] 
                                            [email protected] 
 
-- 692 Kbytes in 2 Requests.

Note: The first string is the message ID, which may have a sigil attached to it for message status. A message flagged "*" is locked for delivery, while a message flagged "!" is frozen.

Apart from "-p" (prints complete queue to screen), there are also the "-s" and "-f" options. These will force the queue to deliver all mails for a particular site or for the entire server, respectively:

root@localhost [~]$ postqueue -s training.co.uk  
root@localhost [~]$ postqueue -f

Here's a cool bash snippet that will print the message IDs for any messages sent by a particular address:

root@localhost [~]$ postqueue -p | grep -v '^ *(' | awk "BEGIN { RS = \"\" } { if ($7 == '[email protected]') print $1 }"

General queue management

A very useful command that is bundled with Postfix is the "postsuper" command, which can only be run by root and is used to manage individual messages in the various Postfix queues. As a reminder the queues are as follows:

  • incoming
  • active (standard outgoing queue)
  • deferred
  • corrupt
  • hold

Delete a message

root@localhost [~]$ postsuper -d <message-ID|ALL> [queue-name]

Using "ALL" (must be in all caps) in place of the message ID will remove all mail from the queues (or the specified queue). This option also applies to other queue operations.

Examples:

root@localhost [~]$ postsuper -d 3D0AA9A7825F 
postsuper: 3D0AA9A7825F: removed 
postsuper: Deleted: 1 message 
 
root@localhost [~]$ postqueue -p | grep -F [email protected] | egrep -o '^[0-9A-F]+' | postsuper -d - 
postsuper: A248E9A783A7: removed 
postsuper: ADA129A783D3: removed 
postsuper: AFC039A78201: removed 
postsuper: Deleted: 3 messages 
 
root@localhost [~]$ postsuper -d ALL 
postsuper: 0A7A09A782D5: removed 
postsuper: 0C8029A78383: removed 
postsuper: 0AF599A78280: removed 
postsuper: 0BCFD9A78227: removed 
postsuper: 0BB569A782F1: removed 
postsuper: 0B90C9A78375: removed 
postsuper: Deleted: 6 messages

For other options see the Postfix Command Reference.

Hold (freeze) a message

Holding messages in the queue means that no attempts to deliver this particular message will be made.

root@localhost [~]$ postsuper -h <message-ID>

To put messages from [email protected] on hold:

root@localhost [~]$ postqueue -p | awk 'BEGIN { RS = "" } { if ($7 == "[email protected]" ) print $1 }' | tr -d '!*' | postsuper -h -

For other options see the Postfix Command Reference.

Release (thaw) a held message

Thawing messages in the queue means that the message will be released from the Hold queue and delivery of the message will proceed normally through the queue.

root@localhost [~]$ postsuper -H <message-ID>

For other options see the Postfix Command Reference.

Re-queue a deferred/held/message

Re-queuing a message is effectively the same thing as thawing messages. It releases the lockout on a message and returns it to the incoming queue to progress normally through the queue system.

root@localhost [~]$ postsuper -r <message-ID> [-r <message-ID-2>] [-r <message-ID-3>] ... ...

View the contents of a message

To pull a single message out of the queue, you'd use postcat -q ID. This will give you the message info as well as the headers as received. The "sender: " or "named_attribute: sasl_username=" lines under the Envelope Records will tell you how it was authenticated.

root@localhost [~]$ postcat -q <message-ID>

Example:

root@localhost [~]$ postcat -q 061139A78271 
 
*** ENVELOPE RECORDS active/061139A78271 *** 
message_size:         157119            537             1              0 
message_arrival_time: Wed Dec 28 19:11:48 2011 
create_time: Wed Dec 28 19:11:48 2011 
named_attribute: rewrite_context=remote 
sender: [email protected] 
named_attribute: log_client_address=14.96.5.190 
named_attribute: log_message_origin=unknown[14.96.5.190] 
named_attribute: log_helo_name=asusx52f 
named_attribute: log_protocol_name=ESMTP 
named_attribute: client_name=localhost.localdomain 
named_attribute: reverse_client_name=localhost.localdomain 
named_attribute: client_address=127.0.0.1 
named_attribute: helo_name=tra.training.com 
named_attribute: client_address_type=2 
named_attribute: dsn_orig_rcpt=rfc822;[email protected] 
original_recipient: [email protected] 
recipient: [email protected] 
*** MESSAGE CONTENTS active/061139A78271 *** 
Received: from holidays.co.in (localhost.localdomain [127.0.0.1]) 
       by training.com (Postfix) with ESMTP id 061139A78271 
       for <[email protected]>; Wed, 28 Dec 2011 19:11:48 -0600 (CST) 
Received: from asusx52f (unknown [14.96.5.190]) 
       by tra.training.com (Postfix) with ESMTP 
       for <[email protected]>; Wed, 28 Dec 2011 19:11:47 -0600 (CST) 
MIME-Version: 1.0From: "Drewal Cars" <[email protected]> 
Reply-To: [email protected] 
To: [email protected] 
Subject: New Year Greetings from Drewal Rent a Car 
Content-Type: multipart/related; 
       type="text/html"; 
       boundary="----=_NextPart_001_5F35_540E1F85.228A7EEF" 
X-Mailer: SendBlaster.1.6.0 
Date: Thu, 29 Dec 2011 06:41:38 +0530 
Message-ID: <3708696088961442125487@asus-x52f> 
 
 
------=_NextPart_001_5F35_540E1F85.228A7EEF 
Content-Type: text/html 
Content-Transfer-Encoding: quoted-printable 
 
...

For more information, see the man pages for "postcat", "postqueue", and "postsuper" or the Postfix Command Reference.

Further reading

Kyle Dent's Postfix FAQ

Command Reference

Postfix Reference