從 Asana 的寄信開 task 功能驗證失敗信初探 envelope address 與 mail address 與 smtp.mailfrom

  • 105
  • 0
  • 2023-08-17

最近一位同事想透過網頁伺服器寄信到 Asana 自動開票,但是在寄信時出現了驗證錯誤的回信。官方說明只給予了非常籠統的回應,說:「信封地址(envelope address)需要與 from 地址相同」,而論壇則是提供了較明確的說明,告訴大家不同的寄件系統該如何設定。

到底這些設定是要設定什麼?信封地址跟我們平常看到的 From 地址又有什麼不同?今天就來透過過實際的例子帶大家詳細理解

 We couldn't process your email because it was sent by amazonses.com but your email domain is example.com. Please contact your email admin to update your mail server's email settings.

閱讀本文前,建議需要的先備知識:


目錄:

SMTP 收信過程解析

envelope address 與 mail address 之間的差異

為什麼會 envelope address 與 mail address 會需要不同?

實際設定


SMTP 收信過程解析

當我們透過收信軟體或網頁(MUA,Mail User Agent,郵件使用者代理)寄出電子郵件時,實際上是請 MTA(Mail Transfer Agent,郵件傳送代理人)幫我們把信件寄給對方。MTA 會透過 MX 紀錄找到收信人網址的實際收信伺服器(MDA,Mail Delivery Agent)並寄出信件。舉個例子

在 a.org 的 Alice 想要寄信給在 b.org 的 Bob。於是 Alice 透過一個好用的收信軟體 Thunderbird 寄出信件。這時 Thunderbird 就會聯絡 a.org 的寄件伺服器(通常是 smtp.a.org),請他幫忙寄信。a.org 的寄件伺服器收到訊息後,會先透過 DNS MX 記錄詢問 b.org 實際的收信伺服器是誰。假設回傳的網址是 mx.b.org,a.org 的寄件伺服器就會直接去找 mx.b.org 並跟他說有封信要給在 b.org 的 Bob。這樣,一封信就寄送完成了。

從上面的舉例來看,Alice 用的 Thunderbird 寄件軟體就是 MUA,而 a.org 的寄件伺服器就會是 MTA,mx.b.org 就是 MDA。

那 MUA 怎麼跟 MDA 對話呢?目前主流是使用 SMTP 協定。SMTP 協定完整定義了兩方的溝通模式與格式,確保大家使用相同的語言對話。

一個 SMTP 的對話中,MUA 基本會有四個指令,HELO、MAIL FROM、RCPT 與 DATA

HELO:通常是 MUA 發送的第一個指令,後面會接上自己的身份(以前面的舉例:smtp.a.org)

MAIL FROM:告訴 MDA 是誰要寄信(以前面舉例:Alice@a.org)

RCPT:告訴 MDA 這封信要給誰(以前面舉例:Bob@b.org)

DATA:正式傳送信件的檔頭與信件本文

範例對話:S 是 smtp.b.org,C 是 smtp.a.org

S: 220 smtp.b.org ESMTP Postfix
C: HELO smtp.a.org
S: 250 smtp.a.org, I am glad to meet you
C: MAIL FROM:<alice@a.org>
S: 250 Ok
C: RCPT TO:<bob@b.org>
S: 250 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: "Alice Example" <alice@a.org>
C: To: Bob Example <bob@b.org>
C: Date: Tue, 15 Jan 2008 16:02:43 -0500
C: Subject: Test message
C: 
C: Hello Bob.
C: This is a test message with 5 header fields and 4 lines in the message body.
C: Your friend,
C: Alice
C: .
S: 250 Ok: queued as 12345
C: QUIT
S: 221 Bye

你注意到了嗎?在 MAIL FROM 指令時,smtp.a.org 其實就有告訴對方寄件者是誰了,但是到了 DATA 指令時,裡面的檔頭又寫了一次 From。沒錯,這就是我們今天的重頭戲。前面的 MAIL FROM 又稱做 envelope from address,而 DATA 中,做為信件標頭的 From 則叫做 mail from address。同樣的結論也適用在 RCTP 與 DATA 中的 To。

envelope address 與 mail address 之間的差異

envelope address 是給接收的伺服器看的地址;mail address 通常是給使用者看到的地址。兩者通常會相同,但有時候是會不同的。

Envelope to address 與 Mail to address 不同的常見例子:有一封寄到 mailing list 的信件,而你是 mailing list 的其中一員。

Envelope from address 與 Mail from address 不同的常見例子:有一封由其他第三方服務代為寄送的信件。我們熟知的電子報寄件服務 sendgrid、Amazon SES 就屬於此類。

使用任何收信軟體查看信件原始碼或是直接在 google 的寄件詳細資料中,就可以看到差異。

原始碼中,可以看到 smtp.mailfrom 中的 E-mail 地址與下方的 From 地址不同

從上圖我們可以看到,圖片上方 smtp.mailfrom 中的地址與圖片下方 From 的地址是不同的。smtp.mailfrom 就是 MAIL FROM 提供的地址,也就是 envelope address,而 From 則是我們平常所看到的地址,也就是 mail address。

gmail 的寄件人與寄件者不同

如果不習慣看這麼多密密麻麻的原始碼,也可以點一下 gmail 「寄給 X」旁邊的小箭頭,就可以發現寄件人與寄件者不同,寄件者就是 MAIL FROM 提供的網域,也就是 envelope address,而寄件人則是我們平常所看到的地址,也就是 mail address。

為什麼會 envelope address 與 mail address 會需要不同?

當信件發生錯誤,或是被收信人退信,亦或是收完信之後 MDA 才發現查無此人時,收信人的 MDA 就會寄一封信回去給跟寄信人說:「你的信件沒有寄成功!」,這時就會使用 envelope address 的地址作為收信地址。

當我們使用第三方服務寄送大量的電子報時,第三方服務為了避免服務被垃圾信濫用,會嚴格確保當收信人有抱怨時,他們可以收到這些抱怨。並且當抱怨或退信率過高時,提醒使用者調整。要做到這件事,同時又不希望調整 From 地址,就可以從 envelope address 下手。從上圖的例子就可以看到,Amazon SES 為了接收退信,提供了一個 UUID 地址,網域則是 us-west-02.amazonses.com 而不是 womany.net。

回到我們一開始的問題。為什麼 Asana 會拒絕收信,就是因為 envelope address 是 us-west-02.amazonses.com,而不是 womany.net,即便信件內容標頭中的 From 是 xxx@womany.net 也不認。

實際設定

我們已經知道問題的來源,也知道怎麼檢查了,那怎麼做才行呢?首先這邊 Asana 沒有說清楚的是,envelope address 不一定要與 mail address 完全相同,只要是原設定網域的子網域就可以了!

這很重要,因為根據 Amazon SES 的規定,envelope address 只能修改成原網域的子網域,不得同為寄件網域。以上面這封信來說,我們只能設定成 xxx.womany.net,但不能是 womany.net。有兩個原因:

  1. 避免 Amazon SES 設定了一個 envelope address 作為退信地址,結果剛好真的有這個使用者。退信時就真的退到了一個使用者手上,而沒有如原先設計,寄到 Amazon SES。
  2. Amazon SES 通常只用來寄信,收信通常是其他服務在處理(例如:Google Workspace),使用原本的網域就會讓退信跑到其他收信伺服器,而沒有如原先設計,寄給 Amazon SES。

以下將會以 Amazon SES 作為範例。(網域為 example.com,預計要設定 mail.example.com 作為 enevelope from address 地址)

  1. 到 Amazon SES 後台中的 Domains:Amazon SES 可以單獨為特定的電子郵件地址設定,如果你不希望網域下從 SES 的信件都用新的 envelope from address(這邊 Amazon SES 是用 MAIL FROM address),可以進到 Email Addresses 內設定。
     
  1. 找到底下的 MAIL FROM Address
     
  1. 設定一個你希望用來當作 MAIL FROM 的子網域名稱,這個網域盡量不要與其他的郵件伺服器同時使用(本範例:mail.example.com)。下方則是可以選擇,如果設定尚未完成時,要回溯使用原本的網址還是直接退信。Amazon 不會冒著無法回傳退信,降低評級的風險讓你寄信的XD
     
  1. 根據你使用的 DNS 供應商,照著設定即可(以下使用 cloudflare 作為範例)
     
  1. 這邊有個奇怪的點,雖然 Amazon SES 說,spf record value 要包含引號,但其實應該不用,其他的供應商也沒有類似的規定,但小問題應該無傷大雅。
     
  1. 設定完之後,需要大約五分鐘的時間讓 Amazon SES 驗證,驗證完畢後再寄一次測試信就會發現,網址已經變更了!