Python 使用smtplib发送邮件时DKIM失败

Python 使用smtplib发送邮件时DKIM失败,python,smtplib,dkim,Python,Smtplib,Dkim,我试着用smtplib发送电子邮件,他们似乎很好。唯一的问题是DKIM失败,邮件通常直接进入垃圾邮件文件夹 在我的共享主机上启用了DKIM(主机是a2hosting,如果有帮助的话),当使用Thunderbird发送个人电子邮件时,该过程工作正常,DKIM通过,这表明问题出在我这边 我甚至尝试使用dkimpy使用私钥对电子邮件进行显式签名,但在ARC身份验证结果下,我仍然得到dkim=fail。 我提到的一些帖子和答案建议使用“登录”作为解决方案,但我已经使用SMTP.login()登录,正如我

我试着用smtplib发送电子邮件,他们似乎很好。唯一的问题是DKIM失败,邮件通常直接进入垃圾邮件文件夹

在我的共享主机上启用了DKIM(主机是a2hosting,如果有帮助的话),当使用Thunderbird发送个人电子邮件时,该过程工作正常,DKIM通过,这表明问题出在我这边

我甚至尝试使用dkimpy使用私钥对电子邮件进行显式签名,但在ARC身份验证结果下,我仍然得到dkim=fail。 我提到的一些帖子和答案建议使用“登录”作为解决方案,但我已经使用SMTP.login()登录,正如我前面提到的,电子邮件正在发送

我提到的一个答案提到,对电子邮件进行签名是服务器的工作,值得一提的是,原始电子邮件输出包括DKIM签名,即使没有使用dkimpy对其进行显式签名,也表明服务器正在按预期进行签名

但问题仍然是DKIM失败会影响电子邮件的可交付性,原始输出没有提供任何关于域DKIM失败原因的详细信息

我使用以下代码片段发送电子邮件

msg=MIMEMultipart()
msg['From']='myemail@mydomain.tld'
msg['To']='someemail@gmail.com'
msg['Subject']=“Subject”
msg.attach(MIMEText(“SomeText”、“plain”))
s=smtplib.SMTP_SSL(“mydomain.tld:465”)
s、 登录(“myemail@mydomain.tld“,“我的密码”)
s、 发送邮件(“myemail@mydomain.tld", 'someemail@gmail.com,msg.as_string())
我试着在邮件上签名如下

headers=[“To”,“From”,“Subject”]
以open(“cert.pem”)作为fh:
dkim_private=fh.read()
sig=dkim.sign(
message=msg.as_string().encode(“ascii”),
选择器=str(dkim_选择器)。编码(“ascii”),
domain=“robogyan.tech”。编码(“ascii”),
privkey=dkim_private.encode(“ascii”),
包含_头=头,)
msg[“DKIM签名”]=sig.decode(“ascii”).lstrip(“DKIM签名:”)
原始输出确实反映了具有上述代码的签名,但DKIM仍然失败

由于服务器回复“身份验证成功”,因此身份验证似乎没有任何问题

编辑:

DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;

    d=mydomain.tld; s=default; h=Subject:To:From:MIME-Version:Content-Type:

    Sender:Reply-To:Date:Message-ID:Cc:Content-Transfer-Encoding:Content-ID:

    Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc

    :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:

    List-Subscribe:List-Post:List-Owner:List-Archive;

    bh=giCDGo/0duFr1Ex65l7Ixc3N45EAULK+gw5cHV8pO0k=; b=DR08Q+CjgOLqo8WkLJs/XROfTw

    Z7+ph+qnzi5p49cT3+UwQolcL1CKIVPk7XRkL8WZ3FFa9hZuc6TumquRSiYd5uR0AC5Z3lopEfnQe

    fdbOOTRnks2ZzoOnQusy/gmydUttypu8wTthFhy7vTWXMFcdI29X/HkrokCtiGKCoD2u2kWBtn2sm

    3/aP83lBbMpcWsNbvo3HTsL71o8QPd6bVKpqRGyAy89cAwMLwP4dnJ9WcCxxNzowlJNPQja3o5W16

    t3rG/KizcRehjaDUXhPPRF/4RdYUSIi/SGNwmIPwvkZNc17k3wQpszKeG6/Ujgax/i7Li7V7dLJBT

    Fu/x6xDA==;

Signed-by: myemail@mydomain.tld

Expected-Body-Hash: giCDGo/0duFr1Ex65l7Ixc3N45EAULK+gw5cHV8pO0k=


下面是失败电子邮件的DKIM,如果有帮助的话。预期的正文哈希和接收的正文哈希也匹配。我不确定问题出在哪里。

经过大量研究和暴力手段,我终于找到了问题的解决方案。 我还需要在标题中包含消息ID和日期。 在代码中添加以下行有助于我通过验证

msg['Date']=email.utils.formatdate()
msg['Message-ID']=email.utils.make_msgid(domain='mydomain.tld')

重要提示:您需要将smtp客户端的计算机IP地址添加到
InternalHosts
列表中,因为OpenDKIM将使用检查客户端的权限

您需要将此行添加到
/etc/opendkim.conf

InternalHosts    file:/etc/opendkim/TrustedHosts   # or any location you want
/etc/opendkim/TrustedHosts
的内容可能如下所示:

127.0.0.1
::1
localhost
<server_ip>
hostname.example1.com
example1.com
hostname.example2.com
example2.com
...
许多MTA都有(WHM/CPanel/SpamExperts)模块,这些模块添加丢失的消息Id头,从而使在此之前创建的DKIM签名无效。
$ sudo service opendkim restart