Exim 并不总是发送 AUTH LOGIN 用户名/密码

Exim 并不总是发送 AUTH LOGIN 用户名/密码

我们正在使用 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));
}

相关内容