我确信这个问题的变体已经被问过,如果这是重复的,我深表歉意,但我似乎无法找到在我的处境下有效的东西而不会破坏其他东西。
我将 VPS 用作网络服务器,我需要网站上的联系表单才能通过服务器发送邮件。我安装了 sendmail,基本上可以正常工作。但是,邮件未能通过许多 SPF 测试。我向每个域添加了 SPF 条目,但当我检查邮件标头时,我注意到很多:
ARC-Authentication-Results: i=1; mx.google.com;
spf=neutral (google.com: 123.45.67.89 is neither permitted nor denied by best guess record for domain of [email protected]) [email protected]
Return-Path: <[email protected]>
起初,我只是将盒子的主机名(以及在其中添加条目/etc/hosts
)更改为我的主 FQDN。我这样做是因为我include:foo.com
在 SPF 条目中使用了它。
这有一些副作用,所以我撤消了更改并恢复了本地框名称。
我阅读并实施了这个问题通过编辑sendmail.mc
附加define(`confDOMAIN_NAME', `foo.com')dnl
然后,我尝试从我自己的网站(位于同一主域上)提交联系表单,并收到来自 Contact Form 7 的错误。我尝试了一个客户端站点(同一服务器,不同的 FQDN),它成功了。所以我删除了该自定义条目并重建了 sendmail.mc 文件。
让 sendmail 从 FQDN 创建邮件头而不干扰其他内容的正确方法是什么?我是否应该再次尝试 sendmail.mc 但创建一个mail.foo.com
子域?
我很困惑 - 我只是希望我的邮件头中不再包含本地域,这样 SPF 就不必进行最佳猜测,并且会将邮件作为有效邮件传递,因为我已经有 SPF 记录,专门允许发送 IP 和域(就像我已经做的那样)。
编辑:这是我/etc/hosts
现在的文件:
127.0.0.1 localhost localhost.localdomain
127.0.0.1 example.com mail.example.com
127.0.1.1 myboxname.localdomain myboxname
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
输出为sendmail -bt -d0.1 root
:
Version 8.15.2
Compiled with: DNSMAP IPV6_FULL LDAPMAP LDAP_REFERRALS LOG MAP_REGEX
MATCHGECOS MILTER MIME7TO8 MIME8TO7 NAMED_BIND NETINET NETINET6
NETUNIX NEWDB NIS NISPLUS PIPELINING SASLv2 SCANF STARTTLS
TCPWRAPPERS USERDB USE_LDAP_INIT XDEBUG
============ SYSTEM IDENTITY (after readcf) ============
(short domain name) $w = myboxname
(canonical domain name) $j = mail.example.com
(subdomain name) $m = localdomain
(node name) $k = myboxname
========================================================
答案1
我遇到了同样的问题 - 我们的中继拒绝了 ctladdr,confDOMAIN_NAME 不起作用,更改主机名会影响其他程序。我使用的是 CentOS 6.x,但我相信这些也适用于 Ubuntu。我找到了两个适用于 mail() 和 sendmail 的解决方案。我们的最终解决方案是使用 CodeIgniter 的电子邮件类,因为它更适合我们的软件设置。
方法一:域别名
在设置别名之前,我的主机名如下所示
[root@devbox ~]# hostname --fqdn
devbox.ourlocalnetwork.lan
[root@devbox ~]# sendmail -bt -d0.1 </dev/null
...
============ SYSTEM IDENTITY (after readcf) ============
(short domain name) $w = devbox
(canonical domain name) $j = devbox.ourlocalnetwork.lan
(subdomain name) $m = ourlocalnetwork.lan
(node name) $k = devbox
========================================================
我将此行添加到 /etc/hosts 并重新启动网络
127.0.0.1 devbox.ourlocalnetwork.lan mail.myrealdomain.com
Sendmail 提取别名并使用该域名发送电子邮件
[root@devbox ~]# hostname --fqdn
devbox.ourlocalnetwork.lan
[root@devbox ~]# sendmail -bt -d0.1 </dev/null
...
============ SYSTEM IDENTITY (after readcf) ============
(short domain name) $w = mail
(canonical domain name) $j = mail.myrealdomain.com
(subdomain name) $m = myrealdomain.com
(node name) $k = devbox
========================================================
我使用网络表单发送了一封电子邮件,结果显示在 /var/log/maillog 中,现在 ctladdr 已正确设置
Feb 6 17:03:45 devbox sendmail[6854]: w16M3irS006852: to=<[email protected]>, ctladdr=<[email protected]> (48/48), delay=00:00:01, xdelay=00:00:01, mailer=esmtp, pri=120567, relay=mx1.ourrelayprivder.com. [relay_ip_redacted], dsn=2.0.0, stat=Sent (Ok: queued as 2445F140071)
方法 #2:mail() additional_parameters
mail($to, $subject, $message, $headers, "-f ".$email)
使用 additional_parameters 更改发件人和回复字段。此方法更简单,但您必须更加注意清理用户输入,如该页面上的评论。
这也会将在日志文件中产生警告
Authentication-Warning: devbox.ourlocalnetwork.lan: apache set sender to [email protected] using -f
我不喜欢这个代码的味道,所以我们采用了下一个方法
方法#3:使用不同的电子邮件库/框架
这是我们实际的解决方案。我们对 mail() 的使用是在遗留代码中。当我在处理 sendmail 时,我的同事使用 CodeIgniter 重写了这段代码。这是我们网站设置中最干净的解决方案,所以我们就使用了它。