在完全重新安装后,我们遇到配置问题:发件人地址错误,并且一些收件人(邮件服务器)拒绝了他们。
因此,有大量邮件滞留在 Postfix 队列中。
理想情况下,直接在排队的邮件中更改发件人地址,然后刷新队列是最佳的。
我试过这个答案解决了这个问题。但是在我的版本(2.11.0)中,消息似乎不容易修改。
例如,没有/var/spool/mqueue
目录,但是,/var/spool/postfix/...
active
bounce
corrupt
defer
deferred
dev
etc
flush
hold
incoming
lib
maildrop
pid
private
public
saved
trace
usr
感兴趣的目录是deferred
。我尝试修改那里的几个文件,将错误的域更改为正确的域(并小心确保只有那些被更改)。
但是后来,这些邮件被移至了corrupt
,这意味着简单的文本更改似乎不起作用(已完成vi
)。
还有其他更简洁的方法可以更改排队邮件中的发件人吗?
答案1
我试过这个答案r 解决了这个问题。但在我拥有的版本 (2.11.0) 中,消息似乎不容易修改。
例如,没有 /var/spool/mqueue 目录,但是有 /var/spool/postfix/...
我想要澄清两件事。
- 首先,该答案适用于 sendmail 而不是 postfix。
- 其次,根本不支持直接操作原始队列文件。
因此,您有多种选择
1. smtp_generic_maps 参数
这个答案的灵感来自于很好的答案。它会自动将旧地址重写为新地址。您可以定义文件将旧地址映射到新地址。
/etc/postfix/main.cf:
smtp_generic_maps = hash:/etc/postfix/generic
/etc/postfix/generic:
[email protected] [email protected]
别忘了postmap /etc/postfix/generic
跑postfix reload
- 优点:您不需要重新排队该消息
- 缺点:Postfix 将重写发送者和接收者解决匹配的问题
[email protected]
。
2. sender_canonical_address
为了克服第一种选择的缺点,您可以使用sender_canonical_maps
。此解决方案基于Postfix 作者建议。与第一个选项相同,您可以定义文件以将旧地址映射到新地址。
/etc/postfix/main.cf:
sender_canonical_maps = hash:/etc/postfix/sender_canonical
/etc/postfix/sender_canonical:
[email protected] [email protected]
运行postmap /etc/postfix/sender_canonical
然后运行postfix reload
。由于后缀队列的流动,您必须使用命令重新排队受影响的队列postsuper -r queueid
- 优点:Postfix 不重写收件人地址。
- 缺点:您必须重新排队所有受影响的消息。但您可以使用单个命令重新排队所有延迟的消息
postsuper -r ALL deferred
3. 直接操作 postfix 队列
这是手动修改队列以进行高级处理的旧方法。此答案来自postfix 用户邮件列表
简而言之
提取队列
# postsuper -h queueid # postcat -qbh queueid > tempfile.eml # vi tempfile.eml
重新提交队列并删除旧队列
# sendmail -f $sender $recipient < tempfile.eml # postsuper -d queueid
有关上述命令的文档,请参阅这一页
笔记:
原始解决方案来自postfix 用户邮件列表,用于postcat -q queueid >tempfile
提取队列。此命令将提取队列的头部、主体和元信息。正如下面 Azendale 所指出的那样,sendmail
将因元信息而拒绝发送此格式错误的电子邮件。
使用-bh
参数附加参数q
将使 postcat 仅过滤标题和正文的输出,而不包含元信息。这样做的一个附带好处是临时文件采用大多数电子邮件客户端可识别的 .eml 格式,允许您查看生成的(已编辑)消息。
答案2
写得很棒。我的邮件服务器出现了问题,它运行了几天,配置很差,因此有很多队列需要重新发送给新收件人。所以我创建了两个一行代码来循环遍历所有队列:
首先找到所有队列,将其搁置,将其保存为.eml 文件并重新发送:
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
第二步删除队列:
for ID in `mailq | awk '$1 !~/^$|[@\(^$-]/ { print $1 }' | tr -d \!`; do postsuper -d $ID; done
只需记住在运行最后这段代码之前检查没有未暂停的新队列即可。通过发出此代码并查找末尾没有“!”的队列 ID 来执行此操作:
mailq | awk '$1 !~/^$|[@\(^$-]/ { print $1 }'
我可以轻松地将这两个单行代码合并为一行,但我觉得在删除队列之前检查邮件是否真的收到,这样我可以更好地控制。
答案3
对于遇到此问题的人,我可以这样解决,谢谢你
for ID in `mailq | awk '$1 !~/^$|[@\(^$-]/ { print $1 }' | tr -d \!`; do postsuper -h $ID; postcat -qbh $ID | sed 's/[email protected]/[email protected]/' > tempfile$ID.eml; sendmail -t < tempfile$ID.eml; done