使用Python和Postfix发送VERP合规邮件
我想在Python中发送电子邮件,这样我就可以处理退信。VERP(可变电子邮件回执地址)似乎是解决这个问题的方法。不过,当我把发件人地址(不是MIMEMultipart对象的“From”值)设置为包含VERP分隔符时,我没有收到退信通知。
我可以自己创建一个VERP发件人吗?比如说,如果我想发邮件给user@domain.com,我能把发件人地址设置为“mysender+user-domain-com.mydomain.com”吗?这样就能正常工作吗?还是说我需要配置postfix,以便它能正确解析失败的DSN(送达状态通知)?我的问题是如何收到失败通知,而不是如何把邮件送到有效的收件人那里。
也许举个例子会更清楚。
当我从myuser@domain.com发送邮件时,我能正常收到退信通知。
但是当我从myuser+verp_identifier@domain.com发送邮件时,我就收不到任何退信通知了。(不过,发送给正确地址的邮件,比如valid_user@gmail.com,都是能正常送达的。)Perl的邮件模块有一个VERP子模块,Python有没有类似的东西呢?
2 个回答
为了正确处理VERP,Postfix需要进行特别配置。smtpd_authorized_verp_clients
这个设置列出了哪些客户端可以使用VERP,它只配置了发送部分。实际上,它列出了可以使用XVERP命令的客户端,这个命令会自动在发件人地址后面加上+dest
。
但是在默认配置下,Postfix并不会自动把发送给sender+ext
的消息送到sender
那里。要让这个功能正常工作,你需要在main.cf
文件中添加(或者取消注释)recipient_delimiter = +
。在默认配置中,这一行是存在的,但被注释掉了。
所以,如果你能自己形成VERP发件人地址,比如说发件人地址是myuser+verpid@domain.com
,那么只要你有recipient_delimiter = +
,就不需要做其他事情:目标SMTP服务器会把退信发送到这个地址,而你的Postfix会正确地把它送到myuser@domain.com。
我不知道有没有哪个Python包可以自动添加XVERB命令。所以在我看来,如果你想让它自动使用,你应该按照Postfix VERP使用指南中描述的步骤来做:
你可以使用smtpd_command_filter功能来为旧软件的SMTP命令添加XVERP。这需要Postfix 2.7或更高版本。
/etc/postfix/main.cf:
smtpd_command_filter = pcre:/etc/postfix/append_verp.pcre
smtpd_authorized_verp_clients = $mynetworks
/etc/postfix/append_verp.pcre:
/^(MAIL FROM:<listname@example\.com>.*)/ $1 XVERP
你应该使用“Return-Path”而不是“FROM”作为退信的发送地址。用Postfix发送邮件时,设置退信地址并不需要特别的配置。
对于Postfix处理不同的入站邮件,可以使用地址中的“+”符号,因为“+”后面的内容通常会被忽略。所以,如果把Return-Path设置为joe+bounce@here.com,邮件会送到joe@here.com,而收件人地址仍然是joe+bounce@here.com。你可以通过在master.cf文件中添加一个过滤器来编程处理这些邮件。
在服务列表中加入这个:
smtp inet n - - - - smtpd
-o content_filter=filter:dummy
然后在这里定义过滤器:
filter unix - n n - 10 pipe
flags=Rq user=filter null_sender=
argv=/home/filter/InboundProcessor.py -f ${sender} -- ${recipient}
这样,InboundProcessor.py脚本就会通过管道接收所有入站邮件。如果收件人地址中包含“+”后面跟着某个退信的关键值,你可以把这个已经不再有效的地址在你的数据库中标记为不活跃。