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 配置設定:

部分:驗證

sendgrid_login:
  driver = plaintext
  public_name = LOGIN
  client_send = : ******** : **************

部分:路由器啟動

send_via_sendgrid:
  driver = manualroute
  domains = ! +local_domains
  transport = sendgrid_smtp
  route_list = "* smtp.sendgrid.net::587 byname"
  host_find_failed = defer
  no_more

部分:運輸開始

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) - I認為它可以防止再次尋找它(另請參閱SMTP 傳輸)。信用配置 Exim 以使用 Gmail 作為智慧主機還有 OP 和@wurtel。

先前的答案/如何測試和重現::

我相信 @wurtel 對 IP 位址更改問題的評論是正確的,因為我可以透過使用腳本快速更改 IP smtp.sendgrid.net 解析來可靠地重現此問題。我還確認,如果主機檔案中沒有任何條目,當我每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 毫秒,它將在解析為 158.85.10.138 和 108.168.190.108 的兩個 IP 之間切換 smtp.sendgrid.net 的主機檔案中的條目。

#!/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));
}

相關內容