Manage Postfix Mail Server Queues like a Pro

 

Manage Postfix Mail Server Queues through shell

By running a Postfix mail server, you need to know some commands to manage Postfix mail queues. With this knowledge, you can manage queues and write simple scripts to accomplish larger tasks.

First, I will list the most relevant commands you need for your daily business. Then we will build up real-life examples to understand how these commands work, how to use them, and when they can harm.

Postfix Mail Queue Commands

Postfix has several commands to manage the queues. I list the most important of them and the most used options.

Postqueue

Postqueue is the so-called Postfix queue control. We can use this command to display postfix queues in different formats, list enqueued mails, and force Postfix to deliver single deferred emails or all emails at once.

$ postqueue -p # list all enqueued emails in sendmail-style
$ postqueue -j # List all queues with messages in JSON format
$ postqueue -f # Flush the queue: attempt to deliver all queued mail.
$ postqueue -i <ID> # Schedule immediate delivery of deferred mail with the specified queue ID.
$ man postqueue # show manual/help of postqueue command

Postcat

Postcat is used to access queue file contents. You can access the email messages by their ID, which can be listed using postqueue command.

postcat -q <ID> # show the content of the email message with ID

Postsuper

Postsuper alias Postfix superintendent is a tool to manage jobs on the Postfix queue. I use this command only to delete single messages from the queue:

postsuper -d <ID> # delete an email message with ID

Mailq

Mailq is a Postfix to Sendmail compatibility interface. I use it to simply display current queue status.

$ mailq

Review Postfix Queues

To check Postfix mail queues, you have two commands, which show very similar results:

$ mailq
Mail queue is empty

$ postqueue -p
Mail queue is empty

If you have nothing in the queues, it’s not very interesting, so let’s add an email to the queue, which can’t be delivered, and try again:

$ mail -s 'testing message subject' someone@gsmail.com <<< 'testing message body'
$ mailq
-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------
929564780073      257 Fri Feb 12 13:48:24  root
                                         someone@gsmail.com

$ postqueue -p
-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------
929564780073      257 Fri Feb 12 13:48:24  root
                                         someone@gsmail.com

Now we can see an enqueued email with the corresponding Queue ID, which we will need to access, process, and delete single emails inside the queue.

Hint: As this email can’t be delivered, please check the section on how to delete emails from queues.

Hint: To visually monitor Postfix queues, you can use the postfix_mailqueue Munin plugin.

View single message in Postfix queue by ID

To access or view a single enqueued message files, we use Postcat:

$ postcat -q <ID>

As the queues are mostly empty, we can enqueue a message, which can’t be delivered and check its content:

$ mail -s 'testing message subject' someone@gsmail.com <<< 'testing message body'

$ mailq
-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------
C4CDF478008B      257 Fri Feb 12 14:00:34  root
                                         someone@gsmail.com

$ postcat -q 57E69478008D
postcat -q C4CDF478008B
*** ENVELOPE RECORDS deferred/C/C4CDF478008B ***
message_size:             462             210               1               0             462               0
message_arrival_time: Fri Feb 12 15:00:17 2021
create_time: Fri Feb 12 15:00:17 2021
named_attribute: rewrite_context=local
sender_fullname: root
sender: root@mail.yourserver.com
*** MESSAGE CONTENTS deferred/C/C4CDF478008B ***
Received: by mail.yourserver.com (Postfix, from userid 0)
	id C4CDF478008B; Fri, 12 Feb 2021 15:00:17 +0100 (CET)
To: someone@gsmail.com
Subject: testing message subject
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Message-Id: <20210212140017.C4CDF478008B@mail.yourserver.com>
Date: Fri, 12 Feb 2021 15:00:17 +0100 (CET)
From: root@mail.yourserver.com (root)

testing message body
*** HEADER EXTRACTED deferred/C/C4CDF478008B ***
named_attribute: encoding=8bit
named_attribute: dsn_orig_rcpt=rfc822;someone@gsmail.com
original_recipient: someone@gsmail.com
recipient: someone@gsmail.com
*** MESSAGE FILE END deferred/C/C4CDF478008B ***

Attention: Don’t use this function to check the emails of other people. Respect privacy to be respected. Maybe read SYSTEM ADMINISTRATORS' CODE OF ETHICS @usenix.org.

Delete queued mail from the Postfix queue

Sometimes we need to delete emails from Postfix queues as account(s) were hacked and someone tried to abuse them by sending a massive amount of emails. Sometimes we need to get rid of some test emails a developer or a person attempted to send.

Postsuper alias Postfix superintendent is a tool to manage jobs on the Postfix queue:

postsuper -d <ID> # delete an email message with ID

To delete a message, we need first to create a message, to get its Queue ID, and then delete it:

$ mail -s 'testing message subject' someone@gsmail.com <<< 'testing message body'

$ mailq
-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------
E15284780083      462 Fri Feb 12 14:21:19  root@mail.your-server.com
(Host or domain name not found. Name service error for name=gsmail.com type=MX: Host not found, try again)
                                         someone@gsmail.com

$ postsuper -d E15284780083
postsuper: E15284780083: removed
postsuper: Deleted: 1 message

Delete queued messages from a specific email

As mass sending emails can built-up queues with thousands of emails, it is hard to delete them by ID. We can use the commands we have used before to do this automatically.

The basic idea is to get all enqueued emails, then select the relevant ones and delete them one by one. We will use the Sender/Recipient to get the relevant Queue IDs.

First, we will add three emails and then delete them through the example:

$ mail -s 'testing message subject' someone@gsmail.com <<< 'testing message body'
$ mail -s 'testing message subject' someone@gsmail.com <<< 'testing message body'
$ mail -s 'testing message subject' someone@gsmail.com <<< 'testing message body'

$ mailq
-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------
9CB0F4780083      462 Fri Feb 12 14:32:17  root@mail.your-server.com
(Host or domain name not found. Name service error for name=gsmail.com type=MX: Host not found, try again)
                                         someone@gsmail.com

74078478008B      462 Fri Feb 12 14:32:18  root@mail.your-server.com
(Host or domain name not found. Name service error for name=gsmail.com type=MX: Host not found, try again)
                                         someone@gsmail.com

D5E104780090      462 Fri Feb 12 14:32:22  root@mail.your-server.com
(Host or domain name not found. Name service error for name=gsmail.com type=MX: Host not found, try again)
                                         someone@gsmail.com

$ mailq|awk ' /root@mail.your-server.com/ {print $1}' | tr -d '*' | xargs -rn1 postsuper -d
postsuper: 9CB0F4780083: removed
postsuper: Deleted: 1 message
postsuper: 74078478008B: removed
postsuper: Deleted: 1 message
postsuper: D5E104780090: removed
postsuper: Deleted: 1 message

$ mailq
Mail queue is empty

The deletion can be done through a domain name too, as the sender may be forged for a given domain:

$ mailq | awk ' /^[0-9A-F][0-9A-F]*.*some-domain.com$/ {print $1}' | tr -d '*' | xargs -rn1 postsuper -d

Delete all queued messages

Attention: Never use this command on production systems, as you can and at some point will delete valid emails, which are in the queue!

Sometimes you run a test system and therefore can delete all enqueued emails. You can delete them through Postsuper by running:

$ postsuper -d ALL

Send all deferred messages

Sometimes you need to send (flush) all enqueued emails at once. Enqueueing a larger amount of emails can happen on wrongly configured DNS, getting mails stuck in the outbound queue. Then use Postqueue to send them all at once:

$ postqueue -f

There is no output. So don’t run this command over and over again. Just give Postfix some time to resend all enqueued emails - especially if there are many of them.

Attention: Don’t run this command repeatedly to deliver emails to users inboxes. These retries can pretty fast hit limits, which may block your server or reduce reputation, which can be long time damage your IP address and your email server to recover from.

Summary

By using, understanding, and learning those view commands and their most important options, you can manage Postfix queues. Practice on a testing system to understand and get a feeling on possible tasks you have to do if your server is in trouble.

With these view commands, you have the right tools/scripts to take action on a growing queue or a hacked user account sending spam messages from your email server and growing queue. You can even use this know to build a queue monitoring script for your server(s).



Tags