我正在尝试找到一种方法,让我的 Postfix 服务器似乎拒绝来自特定信封发件人的电子邮件,同时仍将这些相同的电子邮件传递给其预期收件人。
Microsoft 的电子邮件服务器不断将我的邮件服务器的 IP 地址列入黑名单,拒绝来自我的服务器的电子邮件,并显示一条消息建议
请联系您的互联网服务提供商,因为他们的部分网络位于我们的阻止列表 (S3150) 上。
在过去的几个月里,我和我的托管提供商已三次验证,没有可疑活动源自我的低容量邮件服务器,并且它正确配置了反向 DNS、SPF 和 DKIM 记录,不会出现在任何公共场合黑名单,并且将邮件发送到其他大型电子邮件提供商域(例如 gmail 和 yahoo)没有问题。
到目前为止,我的提供商在跳过 Microsoft 的重重关卡并成功实现“缓解”方面提供了 3 次帮助,短暂地允许我再次与我经常在他们的某个域上发送电子邮件的人进行通信,但每次这种缓解都被证明是暂时的,并且这种情况很快就会重演。
由于我厌倦了玩这种毫无意义的游戏,我在我的邮件服务器上给了这位常客一个帐户,我们现在用它来交换电子邮件,从而将 MS 排除在外。
由于我的电子邮件历史记录显示这是我在过去几年中唯一与之通信过的 MS“客户”,因此我不想继续反复跳过 MS 的麻烦,而是希望以适当的方式拒绝来自 MS 邮件服务器的消息。拒绝邮件,让发件人知道我将无法回复他们,因为 MS 无缘无故地不断审查我的邮件服务器。
由于我无法回复任何此类电子邮件,这似乎是向他们提供该信息的唯一方法。但与此同时,我希望能够查看此类发件人所写的内容,以防我认识的人更换了电子邮件提供商或暂时失去联系。
那么,谁能告诉我使用 Postfix 是否可以实现这样的事情,如果可以的话,配置它的最佳方法是什么?
答案1
经过更多的研究和实验,我找到了一种迄今为止似乎有效的解决方案。
我遵循了描述的方法http://www.postfix.org/SMTPD_PROXY_README.html,如链接所示编辑 master.cf 并通过以下方式使用 socat:
socat tcp-l:10025,fork,bind=127.0.0.1 system:/path/to/filterscript.sh
监听 127.0.0.1:10025 并在每个连接上启动我编写的 bash 过滤器脚本的实例,该脚本发布在下面
根据 SMTPD_PROXY_README 的最后一部分,我的脚本只是将来自过滤器前 Postfix smtp 服务器的 smtp 命令和数据转发回位于 127.0.0.1:10026 的 Postix 过滤器后 smtp 服务器,然后返回(大部分)命令将从过滤器后服务器接收到的命令响应返回到过滤器前服务器。
但是,如果在此过程中脚本看到以“@hotmail.com”结尾的“MAIL FROM:”地址,则在邮件完成时不会将后过滤器服务器的 250 成功响应转发回预过滤器服务器,相反,它会向预过滤器服务器发送带有自定义消息的 550 拒绝代码。这会导致 Postfix 的预过滤器服务器向 hotmail 报告邮件被拒绝,即使后过滤器服务器实际上已传送该邮件。
这是我使用的脚本:
#!/usr/bin/bash
exec 4<>/dev/tcp/127.0.0.1/10026 # output back to postfix
export IFS='$\n'
function relay_smtp_responses {
while read -r -t 1 -u 4 rline; do
if [[ $rline == "221 "* ]]; then
Finished=true
else
echo "$rline"
fi
done
}
InDataMode=false
Finished=false
Reject=false
relay_smtp_responses # relay initial smtp greeting from after filter server back to before filter server
until "$Finished"; do
if ! read -r -t 5 line; then # fetch line from before filter smtp server
relay_smtp_responses
echo -e "QUIT\r" >&4
exit
fi
echo "$line" >&4 # relay line to after filter smtp server
if "$InDataMode"; then
if [[ ${line%$'\r'} == "." ]]; then
InDataMode=false
if "$Reject"; then
echo "550 5.7.1 Replies to you are blocked, see <insert link to customized error explanation here>"
else
relay_smtp_responses # relay post-filter's eom response back to pre-filter server
fi
fi
else
relay_smtp_responses # relay command response from after filter server back to pre filter server
if [[ ${line%$'\r'} == "MAIL FROM:"*"@hotmail.com>" ]]; then
Reject=true
elif [[ ${line%$'\r'} == "DATA" ]]; then
InDataMode=true
fi
fi
done
由于 bash 的读取命令不能很好地处理二进制数据,因此我还必须通过添加来禁用 BDAT 命令
smtpd_discard_ehlo_keywords = chunking
到 Postfix main.cf 文件。使用另一种语言可能会避免这种情况。
我还不确定我的脚本处理 8 位数据的效果如何,但目前尚未禁用 8BITMIME 或 SMTPUTF8,也没有遇到任何问题。
虽然到目前为止它正在做我想要的事情,但这个脚本仍然主要用于概念验证,我希望在更多测试后增强或替换它。
欢迎任何想法或建议,希望这些信息对某人有所帮助。
答案2
去过你所在的地方。放弃。建议您也这样做。
相反,我希望使用适当的拒绝消息来拒绝来自 MS 邮件服务器的邮件,让发件人知道我将无法回复他们,因为 MS 一直无缘无故地审查我的邮件服务器。
这很可能不会按照您想要的方式进行。
如果您的电子邮件服务器可以回复电子邮件,您也可以直接发送电子邮件。
所以,你能做的就是真正修改未能送达的原因;一线不能太长。
这只会导致微软自动生成一条信息,表明其客户的电子邮件无法发送给他们显示。如果我没记错的话,那封电子邮件将要包含拒绝原因 - 但没有人,包括我,阅读这些电子邮件。 “电子邮件无法发送”:很好。我需要考虑一下我是否有精力挖掘出不同的联系对方的方式。通常,事情没那么重要,而我写信的人根本不会得到我要提供给他们的信息。我当然不会向下滚动来弄清楚他们的电子邮件服务器是否配置错误、磁盘已满、满月时无法工作或拒绝名字有头韵的人。
你无法赢得与微软的扳手腕。这种权力动态并不是这样的。
关于技术可行性: 依靠。通常,您会将 postfix 配置为尽早拒绝,即一旦From:
传递到您的服务器,就无法发送电子邮件,因为那时它甚至还没有发送到您的服务器。
您可以进一步添加一个过滤器,在内部制作副本,拒绝原始邮件,并与当地的投递代理联系以仍然将电子邮件放入正确的收件箱中。据我所知,Postfix 不允许您执行“虽然被拒绝但仍交付”的操作 - 您需要自己编写该 postfix 插件。