Sysadmins of the North

Technical blog, where topics include: computer, server, web, sysadmin, MySQL, database, virtualization, optimization and security

How to delete all MAILER-DAEMON emails in Postfix queue

How to delete all MAILER-DAEMON emails from your Postfix queue, when it matches a sender or recipient email address condition. When a large scale spam run was sent through your mail servers, you need to clean up and remove those spam messages. Doing so guarantees normal, valid email messages being sent quickly, and the spam messages never leave your queue. In Postfix, there are various similar commands to delete messages from the Postfix mail queue. Based on the Message-ID and/or email address…

Postfix logo

Postfix logo

How to delete all emails from a Postfix queue when it matches an address condition

Here is how you can delete mail from the mail queue in Postfix, based on a condition. For example all MAILER-DAEMON emails or spam, by sender or recipient address.

I use this regularly to remove spam from my Postfix SMTP server mail queue.

If you want to delete emails from your Postfix queue based on a sender address – spammer@example.com for example – you need to feed the mailq output to awk. The result is fed to postsuper for deletion:

mailq | tail -n +2 | awk  'BEGIN { RS = "" }
{ if ( $7 == "spammer@example.com" ) print $1 }
' | tr -d '*!' | postsuper -d -
mailq | tail -n +2 | awk  'BEGIN { RS = "" }
{ if ( $7 ~ "@example.com" ) print $1 }
' | tr -d '*!' | postsuper -d -

Here, $7 represents the sender address (7th awk field), either full (spammer@example.com) or matched by regular expression (~ @example.com).

This may interest you:   Recursive scp and symlinks

Do you want to delete message sent to a particular address? Use $8 or $9 as they represent recipient addresses:

mailq | tail -n +2 | awk  'BEGIN { RS = "" }
{ if ( $8 == "spammer@example.com" ) print $1 }
' | tr -d '*!' | postsuper -d -
mailq | tail -n +2 | awk  'BEGIN { RS = "" }
{ if ( $8 == "spammer@example.com" && $9 == "" ) print $1 }
' | tr -d '*!' | postsuper -d -
mailq | tail -n +2 | awk  'BEGIN { RS = "" }
{ if ( $8 == "spammer@example.com" || $8 == "spammer2@example2.com" ) print $1 }
' | tr -d '*!' | postsuper -d -

and so on.

But what if those spam mails already left your system? And can’t be delivered? Then you’re stuck with hundreds of thousands MAILER-DAEMON messages. Of course you can delete all those mails from your Postfix queue: just use MAILER-DAEMON as sender address in the above scripts.

But doing so, you probably also delete other, possibly valid MAILER-DAEMON mails informing you about undeliverable emails. Therefore you need to build in a condition.

The following shell script scans through the Postfix mail queue – using the mailq command – looking for messages sent by MAILER-DAEMON, or any other email address you provide as argument. Of those message-id’s it scans to see if the recipient condition is matched.

This may interest you:   Generate pseudo-random passwords with OpenSSL

Those messages are then deleted from the queue by executing postsuper -d -.

The following example script takes the recipient email address as input, and deletes all mails where MAILER-DAEMON is the sender:

#!/bin/bash
EMAILADDY=$1

if [ -z "$EMAILADDY" ]
then
  echo "Usage: $0 <email adres>"
  exit
fi

echo "Delete all emails addressed to $EMAILADDY, and sent by MAILER-DAEMON, from our Postfix queue."

mailq | tail -n +2 | grep -v '^ *(' | awk -v "address=$EMAILADDY" 'BEGIN { RS = "" }
  { 
    # example conditions:
    #   if ( $7 == "MAILER-DAEMON && $8 == address && $9 == "" )
    #   if ( $7 == "MAILER-DAEMON && $8 == "" && $9 == address )
    #   if ( $7 == "MAILER-DAEMON && $8 == address || $9 == address )
    if ( $7 == "MAILER-DAEMON && $8 == address )
      print $1 
  }
' | tr -d '*!' | postsuper -d -

Call your script on the command line providing a recipient email address:

sh ./delete-mail-from-queue.sh spammer@example.com

Postfix, delete all mails from the queue queue sent by spammer@example.com:

#!/bin/bash
EMAILADDY=$1

if [ -z "$EMAILADDY" ]
then
  echo "Usage: $0 <email address>"
  exit
fi

echo "Delete all emails addressed to $EMAILADDY from our Postfix queue."

mailq | tail -n +2 | grep -v '^ *(' | awk -v "address=$EMAILADDY" 'BEGIN { RS = "" }
  { 
    # example conditions:
    #   if ( $8 == address && $9 == "" )
    #   if ( $8 == address || $9 == address )
    if ( $8 == address )
      print $1 
  }
' | tr -d '*!' | postsuper -d -

Call your script on the command line providing an email address:

sh ./delete-mail-from-queue.sh spammer@example.com

To use a regular expression in Awk, suppose you want to match all emails from various @example.com addresses, change the line if ($8 == address) to:

# the sender is the 7th Awk field, thus $7
if ($7 ~ address)

and provide only example.com as a parameter:


sh ./delete-mail-from-queue.sh example.com

Again, use $8 and/or $9 to match recipients, assuming MAILER-DAEMON is the sender / $7.

Note: Always be careful when messing with mail queues, and especially regular expressions. Another easy usage example is to release Postfix hold queue.

2 Comments

  1. ./delete_spam.sh test@domain.com
    Delete all email addresses addressed to test@domain.com from our Postfix queue.
    delete_spam.sh: line 18: syntax error near unexpected token `newline'
    delete_spam.sh: line 18: `' | tr -d '*!' | postsuper -d -'
    • Hi testerblogersTest, and thank you for your comment (which I edited for syntax highlighting).

      Strange, you shouldn’t get a syntax error… I’ve checked and tested my own code, which works fine. Line 18 is exactly the same. Maybe a copy/paste or line-ending conversion error?

      Note: I’ve changed $8 (recipient) to $7 (sender):

      #!/bin/bash
      ADDRESS=$1
      
      if [ -z "$ADDRESS" ]
      then
        echo "Usage: $0 <address>"
        exit
      fi
      
      echo "Delete all email addresses addressed to $ADDRESS from our Postfix queue."
      
      mailq | tail -n +2 | grep -v '^ *(' | awk -v "address=$ADDRESS" 'BEGIN { RS = "" }
        {
          # if ($8 == address && $9 == "")
          if ($7 == address)
            print $1
        }
      ' | tr -d '*!' | postsuper -d -
      ./deleteMailerDaemon.sh spammer@example.com
      Delete all email addresses addressed to spammer@example.com from our Postfix queue.
      postsuper: 321C91820819: removed
      postsuper: 8DD6E1820DA3: removed
      postsuper: 7CFC21820D68: removed
      postsuper: 7B1931820DC6: removed
      postsuper: D91511820DA4: removed
      postsuper: DC9581820DC8: removed
      postsuper: D3A2E1820DE8: removed
      postsuper: 5DD41182064D: removed
      postsuper: C4E661820DBC: removed
      postsuper: C3A3D1820D7B: removed
      postsuper: 1133E1820D3C: removed
      postsuper: 4000F182067F: removed
      postsuper: 470D91820D7D: removed
      postsuper: 2138C182078C: removed
      postsuper: 2EB711820D3E: removed
      postsuper: 2E2121820CFF: removed
      postsuper: BD26B18207A3: removed
      postsuper: BD15B1820D66: removed
      postsuper: Deleted: 18 messages

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.