9

Following a complete re-installation we got a problem with the configuration: the sender address was wrong and some recipients (mail servers) rejected them.

So there is a bunch of mails stuck in the Postfix queue.

Ideally, a change of the sender address directly in the queued mails, and then flushing the queue would be optimal.

I tried this answer that addresses this very problem. But messages don't seem to be easily modifiable in the version I have (2.11.0).

For instance there is no /var/spool/mqueue dir, but, instead, /var/spool/postfix/...

active
bounce
corrupt
defer
deferred
dev
etc
flush
hold
incoming
lib
maildrop
pid
private
public
saved
trace
usr

and the dir of interest is deferred. I tried to modify a few files there changing the wrong domain with the correct one (and was careful to ensure only those were changed).

But then, those mails were moved to corrupt, meaning that a simple text change doesn't seem to work (done with vi).

Any other cleaner way to change the sender in queued mails?

Déjà vu
  • 5,408
  • 9
  • 32
  • 52

2 Answers2

21

I tried this answer that addresses this very problem. But messages don't seem to be easily modifiable in the version I have (2.11.0).

For instance there is no /var/spool/mqueue dir, but, instead, /var/spool/postfix/...

I want to clarify two things.

  • First, that answer was applied to sendmail NOT postfix.
  • Second, direct-manipulating-raw-queue-files was not supported at all.

So, you have several options here

1. smtp_generic_maps parameter

This answer inspired by this excellent answer. It will rewrite old-address to new-address automatically. You can define file to maps old-address to new-address.

/etc/postfix/main.cf:
    smtp_generic_maps = hash:/etc/postfix/generic

/etc/postfix/generic:
    account@localdomain.example.com       account@example.com

Don't forget to postmap /etc/postfix/generic and run postfix reload

  • Upside: You doesn't need to requeue the message
  • Downside: Postfix will rewriting sender and recipient address that matching account@localdomain.example.com.

2. sender_canonical_address

To overcome the downside of first option, you can use sender_canonical_maps. This solution based on Postfix author suggestion. Same as first option, you can define file to maps old-address to new-address.

/etc/postfix/main.cf:
    sender_canonical_maps = hash:/etc/postfix/sender_canonical

/etc/postfix/sender_canonical:
    account@localdomain.example.com       account@example.com

Run postmap /etc/postfix/sender_canonical then run postfix reload. Due the flow of postfix queue, you must re-queue the affected queue with command postsuper -r queueid

  • Upside: Postfix not rewriting recipient address.
  • Downside: You must requeue all affected message. But you can requeue all deferred with single command postsuper -r ALL deferred

3. direct manipulating of postfix queue

This is manual old ways to modify queue for advanced processing. This answer came from postfix-users mailing lists

In short

  • Extract queue

    # postsuper -h queueid
    # postcat -qbh queueid > tempfile.eml
    # vi tempfile.eml
    
  • Resubmit queue and delete old queue

    # sendmail -f $sender $recipient < tempfile.eml
    # postsuper -d queueid
    

For documentation of above command, refer to this page

Note:
Original solution from postfix-users mailing lists, use postcat -q queueid >tempfile to extract queue. This command will extract the header, body and meta-information of the queue. As pointed Azendale below, sendmail will refuse to send this malformed email because of meta-information.

Using -bh parameter in addition of q parameter will make postcat filter the output to header and body only, not including meta-information. A side benefit of this is the tempfile is in the format most email clients recognize as .eml format, allowing you to view the resulting (edited) message.

masegaloeh
  • 17,978
  • 9
  • 56
  • 104
  • 1
    I tried this, and at least with my version of postfix, it didn't seem to send the message until I used something like `postcat -qbh queueid >tempfile`. (Side benefit: it is in .eml format then.) If I just used `-q` it seemed to do nothing when I ran sendmail. Postfix version 2.8.4. Can anyone confirm this? If so, let's edit this answer. – Azendale Apr 15 '15 at 03:20
  • Hi @Azendale, I retest the third solution and yes we need use `qbh` to make it work. Adding the explanation in the updated answer... :) – masegaloeh Apr 15 '15 at 05:22
  • Thanks ! Was looking for a third solution like. it's just perfect ! – JazZ Oct 04 '17 at 13:45
1

Greate writeup. I had a problem with a mail server that had been running a few days with bad configuration and therefore there was a lot of queues that needed to be resent with new recipient. So I created two one liners to loop through all queues:

First one to find all queues, put them on hold, save them as .eml files and resend them:

for ID in `mailq | awk '$1 !~/^$|[@\(^$-]/ { print $1 }' | tr -d \!`; do postsuper -h $ID; postcat -qbh $ID > tempfile$ID.eml; sendmail -f $sender $recipient < tempfile$ID.eml; done

Second for deleting the queues:

for ID in `mailq | awk '$1 !~/^$|[@\(^$-]/ { print $1 }' | tr -d \!`; do postsuper -d $ID; done

Just remember to check that there are no new queues that are not on hold before running this last code. Do that by issuing this and look for queue id's without an '!' at the end:

mailq | awk '$1 !~/^$|[@\(^$-]/ { print $1 }'

On could easily put those two one liners into one, but I felt I had more control by checking that the mails actually were received before deleting the queues.

Jorn
  • 11
  • 1