邮件中添加“From”头部

3

我制作了一个简单的程序,可以自动为我发送电子邮件。

但是,当我从riseup.net或protonmail发送电子邮件时,有时会发送失败,因为gmail需要“from”头部信息。

以下是错误信息:

This is the mail system at host mx1.riseup.net.

I'm sorry to have to inform you that your message could not be delivered to one or more recipients. It's attached below.

For further assistance, please send mail to postmaster.

If you do so, please include this problem report. You can delete your own text from the attached returned message.

The mail system

: host aspmx.l.google.com[74.125.142.27] said: 550-5.7.1 [198.252.153.129 11] Our system has detected that this message is 550-5.7.1 not RFC 5322 compliant: 550-5.7.1 'From' header is missing. 550-5.7.1 To reduce the amount of spam sent to Gmail, this message has been 550-5.7.1 blocked. Please visit 550-5.7.1 https://support.google.com/mail/?p=RfcMessageNonCompliant 550 5.7.1 and review RFC 5322 specifications for more information. 62si8602934pjo.111 - gsmtp (in reply to end of DATA command)

我查了如何添加邮件头部但是出现了问题,无法使其工作。

这是我的代码:

def send_mail():
    context = ssl.create_default_context()
    with smtplib.SMTP(smtp_server, 587) as server:
        server.starttls(context=context)
        server.login(susername, spassword)
        server.sendmail(semail, recipient, message)
        print("Email has been sent!")

编辑:当我使用浏览器发送电子邮件时,Riseup会自动添加此标题,但是当我使用Python登录到他们的SMTP服务器时,它不会添加。

你能展示一下你尝试添加头部的方法吗? - dspencer
@dspencer 我尝试过使用 server.sendmail(semail[header], recipient, message) 和 server.sendmail(semail, recipient, message[header]),因为我在网上看到过这样的用法。 - victorbrowser
请在问题中添加您的尝试,最好附带来源(您在网上找到的地方)。这将使我们更容易帮助您。 - dspencer
我在 @dspencer 这里做了如下事情,这是我阅读过的页面链接:https://dev59.com/K4zda4cB1Zd3GeqPnID0、https://pymotw.com/2/smtplib/、https://docs.python.org/3/library/email.examples.html - victorbrowser
semail = config['victorlean']['sender_email'] spassword = config['victorlean']['sender_password'] susername = config['victorlean']['sender_username'] uemail = "victorlean@riseup.net" - victorbrowser
显示剩余2条评论
2个回答

2
我遇到了同样的问题。我通过在消息正文中显式添加一个 From: 字段来解决它。例如,下面的消息正文将起作用:
message = """From: <your email address>
To: <receiver's email address>\n
Subject: <your subject>\n

Hi, this is a test mail! """

我从你评论中的链接得到了灵感: 在Python中为server.sendmail()添加主题头


0

我不能给出一个确定的答案,但或许可以提供一些指导方针。

你写道在转发时不修改返回路径。然而,更重要的是知道你是否保留了信封。以下假设你至少没有修改信封发件人。

首先,让我们看一下SPF:

如果没有特殊措施,谷歌将把这些邮件视为垃圾邮件。SPF 的工作原理如下(过于简化):

当一封邮件到达时,接收服务器从信封地址中提取假装的发件人域名(因为信封很容易被伪造),然后询问该域名的 DNS 服务器,当前通信伙伴的 IP 地址是否被授权代表该域名发送电子邮件。如果没有,那么该邮件很可能被视为垃圾邮件。

这就是在没有 SRS 的情况下发生的事情。原始信封发件人域名的 DNS 服务器可能没有将你的 EXIM SMTP 服务器列入可以代表该域名发送电子邮件的主机列表中。除非你控制该 DNS 服务器,否则你无法对此进行任何操作。

SRS 理论上可以缓解这个问题,但它也有自己的问题。主要问题是每个涉及传输相应邮件的 SMTP 服务器都必须正确处理相应的头信息。

您描述了在打开SRS的情况下一切都正常工作,但几天前突然停止了。我个人猜测是因为涉及到一个额外的SMTP服务器来传输您转发的邮件,并且该服务器没有正确处理SRS。甚至在您的EXIM服务器接收到这些邮件之前可能会发生一些问题。

只要保留信封发件人地址,DKIM就不应该出现上述问题。

现在,我的第一个建议是从尽可能多的发件人域向您的EXIM服务器的特殊转发地址发送邮件。了解所有转发的邮件是否被拒绝或仅有少数被拒绝将非常有趣。结果可能会提示问题所在。您可能希望在此测试中启用SRS。

您还应检查到达您的EXIM服务器的特殊地址的邮件已经具有哪些授权。我对EXIM一无所知,因此无法告诉您它是否支持检查SPF或DKIM标头。但我可以肯定地说,这不会是原始发件人站点的某个人错误配置DKIM或SPF的第一次;在后一种情况下,当然不会有SRS的帮助。

至少在SPF的情况下,您可以在不重新配置EXIM的情况下自行检查情况。

首先,存储一个有问题的消息(除了或者替代转发它)。在该消息的头部中,您可以识别将该消息传递到您的EXIM服务器的SMTP服务器的IP地址。为了澄清:如果该消息通过多个SMTP服务器运行,则会有多个Received:头行;您需要找到指定直接连接到您的EXIM服务器以传递消息的最后一个SMTP服务器的那个头行。记下该服务器的IP地址。 接下来,识别信封发送者域。这可能有点困难,因为SMTP服务器通常不会将信封数据添加到头部中(再次提醒,关于EXIM我不知道)。也就是说,电子邮件客户端软件无法显示该数据。但是它应该在日志中。您确实需要从信封数据中获取发件人的域,而不是普通的消息头。 接下来,使用像host或dig这样的软件(或最终一些在线服务)来检查信封发送者域的DNS SPF条目。检查步骤1中的IP地址是否在允许的服务器列表中。 您可以测试的下一件事是完全关闭SPF和DKIM,并在转发消息之前过滤掉相应的头部。毕竟,最好根本不对消息进行身份验证,而不是以使接收者认为它已被篡改的方式对其进行身份验证。当然,这仅用于测试以获得进一步的见解。

最后,违反第二段的前提条件,您可以故意更改信封发件人(用您自己的电子邮件地址替换信封发件人,并将其域部分的DNS条目置于您的控制之下),并关闭SRS。这样,在转发消息时,接收服务器将向您的DNS服务器查询SPF检查。如果您已正确设置,就不会再出现SPF问题。在这种情况下,您应该过滤掉指定原始信封发件人的标头(如上所述,通常不在标头中,但我只知道sendmail,因此可能会有所不同)。

然而,当更改信封发件人时,您将遇到DKIM问题,因此在这种情况下,您应该删除DKIM标头。

祝您测试愉快,好运。

P.S. 如果您给出测试结果或更精确地解释是否更改了信封,我将最终更新答案并给出进一步的提示(如果我能够)。


虽然这很有信息量,但它并没有回答问题,实际上问题是“如何使用Python的smtplib包添加一个发件人头?” - snakecharmerb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接