我们正在使用 exim(通过 WHM 配置)发送邮件。使用完全相同的配置,似乎大多数时候 exim 都会发送正确的 AUTH LOGIN 用户名和密码,但有时它会省略此部分,并且 sendgrid 会拒绝并出现以下错误:
host smtp.sendgrid.net [158.85.10.138]
SMTP error from remote mail server after MAIL FROM:<info@*******.net> SIZE=2048:
550 Unauthenticated senders not allowed
深入研究后,我可以使用以下命令重现该问题(并非每次都是,有时):
# exim -v **@****.com
From: **@****.com
To: **@****.com
Subject: Test exim
This is an exim test.
这些是 exim 配置设置:
部分:AUTH
sendgrid_login:
driver = plaintext
public_name = LOGIN
client_send = : ******** : **************
部分:ROUTERSTART
send_via_sendgrid:
driver = manualroute
domains = ! +local_domains
transport = sendgrid_smtp
route_list = "* smtp.sendgrid.net::587 byname"
host_find_failed = defer
no_more
部分:TRANSPORTSTART
sendgrid_smtp:
driver = smtp
hosts = smtp.sendgrid.net
hosts_require_auth = smtp.sendgrid.net
hosts_require_tls = smtp.sendgrid.net
authenticated_sender_force = true
当它工作时,这是日志:
LOG: MAIN
cwd=/home/** 3 args: exim -v **@****.com
From: **@****.com
To: **@****.com
Subject: Test exim
This is an exim test.
LOG: MAIN
<= **@****-**.com U=jf P=local S=354 T="Test exim"
**@****-** [~]# LOG: MAIN
cwd=/var/spool/exim 4 args: /usr/sbin/exim -v -Mc 1ZjWZy-0005re-S3
delivering 1ZjWZy-0005re-S3
Transport port=25 replaced by host-specific port=587
Connecting to smtp.sendgrid.net [198.37.144.212]:587 ... connected
SMTP<< 220 ismtpd-064 ESMTP service ready
SMTP>> EHLO **.****-**.com
SMTP<< 250-**.***.26.157
250-SIZE 20480000
250-STARTTLS
250-AUTH PLAIN LOGIN
250-8BITMIME
250-PIPELINING
250 AUTH=PLAIN LOGIN
SMTP>> STARTTLS
SMTP<< 220 Begin TLS negotiation now
SMTP>> EHLO **.****-**.com
SMTP<< 250-**.***.26.157
250-8BITMIME
250-SIZE 20480000
250-AUTH=PLAIN LOGIN
250-AUTH PLAIN LOGIN
250 PIPELINING
SMTP>> AUTH LOGIN
SMTP<< 334 VXNlcm5hbWU6
SMTP>> ****
SMTP<< 334 UGFzc3dvcmQ6
SMTP>> ********************
SMTP<< 235 Authentication successful.
SMTP>> MAIL FROM:<**@****-**.com> SIZE=1388 AUTH=**@****-**.com
SMTP>> RCPT TO:<**@****.com>
SMTP>> DATA
SMTP<< 250 Sender address accepted
SMTP<< 250 Recipient address accepted
SMTP<< 354 Continue
SMTP>> writing message and terminating "."
SMTP<< 250 Delivery in progress
SMTP>> QUIT
LOG: MAIN
=> **@****.com R=send_via_sendgrid T=sendgrid_smtp H=smtp.sendgrid.net [198.37.144.212] X=TLSv1.2:AES128-GCM-SHA256:128 A=sendgrid_login C="250 Delivery in progress"
LOG: MAIN
Completed
特别注意该线SMTP>> AUTH LOGIN
以及该线下方的六个数字,以该235 Authentication successful.
线结尾。
以下是一个失败的例子:
LOG: MAIN
cwd=/home/** 3 args: exim -v **@****.com
From: **@****.com
To: **@****.com
Subject: Test exim
This is an exim test.
LOG: MAIN
<= **@****-**.com U=jf P=local S=340 T="Test exim"
**@****-** [~]# LOG: MAIN
cwd=/var/spool/exim 4 args: /usr/sbin/exim -v -Mc 1ZjWjO-0006T8-Eq
delivering 1ZjWjO-0006T8-Eq
Transport port=25 replaced by host-specific port=587
Connecting to smtp.sendgrid.net [198.37.144.225]:587 ... connected
SMTP<< 220 ismtpd-078 ESMTP service ready
SMTP>> EHLO ****-**.com
SMTP<< 250-**.***.157
250-SIZE 20480000
250-STARTTLS
250-AUTH PLAIN LOGIN
250-8BITMIME
250-PIPELINING
250 AUTH=PLAIN LOGIN
SMTP>> STARTTLS
SMTP<< 220 Begin TLS negotiation now
SMTP>> EHLO ****-**.com
SMTP<< 250-**.***.26.157
250-8BITMIME
250-SIZE 20480000
250-AUTH=PLAIN LOGIN
250-AUTH PLAIN LOGIN
250 PIPELINING
SMTP>> MAIL FROM:<**@****-**.com> SIZE=1374
SMTP>> RCPT TO:<**@****.com>
SMTP>> DATA
SMTP<< 550 Cannot receive from specified address <**@****-**.com>: Unauthenticated senders not allowed
SMTP<< 503 Must have sender before recipient
SMTP<< 503 Must have valid receiver and originator
SMTP>> QUIT
LOG: MAIN
** **@****.com R=send_via_sendgrid T=sendgrid_smtp H=smtp.sendgrid.net [198.37.144.225] X=TLSv1.2:AES128-GCM-SHA256:128: SMTP error from remote mail server after MAIL FROM:<**@****-**.com> SIZE=1374: 550 Cannot receive from specified address <**@****-**.com>: Unauthenticated senders not allowed
LOG: MAIN
cwd=/var/spool/exim 8 args: /usr/sbin/exim -v -t -oem -oi -f <> -E1ZjWjO-0006T8-Eq
LOG: MAIN
<= <> R=1ZjWjO-0006T8-Eq U=mailnull P=local S=1383 T="Mail delivery failed: returning message to sender"
LOG: MAIN
cwd=/var/spool/exim 4 args: /usr/sbin/exim -v -Mc 1ZjWjn-0006TR-BX
delivering 1ZjWjn-0006TR-BX
LOG: MAIN
Completed
LOG: MAIN
=> ** <**@****-**.com> R=localuser T=local_delivery
LOG: MAIN
Completed
请注意,SMTP>> AUTH LOGIN
它的下面六行没有被调用……?
问题是,为什么 exim 会省略SMTP>> AUTH LOGIN
请求的实际部分,但只是有时?它使用完全相同连接配置(您可以在两个日志中看到它的引用R=send_via_sendgrid T=sendgrid_smtp
)。
答案1
编辑于2015年11月8日:
解决方案是使用
hosts_require_auth = <; $host_address
hosts_require_tls = <; $host_address
代替
hosts_require_auth = smtp.sendgrid.net
hosts_require_tls = smtp.sendgrid.net
这种语法看起来不寻常,<;
是因为主机名解析为 IPv6 地址(因为听起来 IPv6 地址中的冒号可能会破坏其他东西)。$host_address 变量用于解决主机名解析为的 IP 地址发生变化的情况(例如,在这种情况下,smtp.sendgrid.net 解析为多个 IP,有时在处理过程中解析为不同的 IP)——我认为它可以防止再次查找(另请参阅smtp 传输)。 信用配置 Exim 以使用 Gmail 作为智能主机还有 OP 和@wurtel。
上一个答案/如何测试和重现::
我认为 @wurtel 对 IP 地址更改问题的评论是正确的,因为我可以使用脚本快速更改 smtp.sendgrid.net 解析的 IP,从而可靠地重现此问题。我还确认,如果 hosts 文件中没有任何条目,当我每 5 秒发送一封电子邮件时,此问题至少每 2 小时发生一次,但当我将 IP 硬编码到 /etc/hosts 中时,我以该发送频率连续 8 小时没有出现任何错误,所以这是我目前使用的临时解决方法。
以下是我重现此问题的方法。注意:这是截至 2015 年 10 月底的最新情况 - 如果您在此之后尝试,IP 可能会有所不同,因此请运行dig smtp.sendgrid.net
并使用两个 IP,它会返回结果。
将其添加到 /etc/hosts
108.168.190.108 smtp.sendgrid.net
将其保存到 PHP 文件中,替换[电子邮件保护]使用您控制的电子邮件地址。
#!/usr/local/bin/php
<?php
while (true) {
mail('[email protected]', 'Test email deletethiswithafilter', 'test ' . time());
usleep(500000);
}
将其保存到 PHP 文件中,并在上述程序运行时运行它。每隔 5 毫秒 - 15 毫秒,它将在 smtp.sendgrid.net 的 hosts 文件中的条目在其解析的两个 IP 之间切换,这两个 IP 是 158.85.10.138 和 108.168.190.108
#!/usr/local/bin/php
<?php
while (true) {
passthru('new_hosts_file_contents=`cat /etc/hosts | sed \'s/108.168.190.108/ip108/g\' | sed \'s/158.85.10.138/ip158/g\' | sed \'s/ip108/158.85.10.138/g\' | sed \'s/ip158/108.168.190.108/g\'`; echo "$new_hosts_file_contents" > /etc/hosts 2>&1');
usleep(10000 + rand(-5000,5000));
}