Email

通過 AWS SES 轉髮帶有後綴的電子郵件

  • May 17, 2020

我有一個安裝了 postfix MTA 的伺服器,它接受我的域的郵件,以下稱為@example.com。我需要為某些 emails@example.com 設置轉發到其他電子郵件。例如@gmail.com,這需要通過 SES 使用 SMTP 傳輸來完成。

我有 SES 生產訪問權限和登錄名/密碼對,它是活動的並且有 IAM 權限,我檢查了。我已經在 SES 確認了某些**From:地址。如果我直接通過 PHP 腳本中的 SES 使用這些 SMTP 使用者名/密碼發送電子郵件,一切正常。這意味著登錄名/密碼對和From:**沒問題。

現在我需要重寫**From:用於從外部發送並需要轉發的電子郵件。例如,一封電子郵件是從@gmail.com -> user@example.com 發送的。入口使用者在 virtual_alias_maps 中設置,應該轉到另一個 @gmail.com。為了重寫From:**標頭,使用以下smtp_header_checks內容:

smtp_header_checks = pcre:/etc/postfix/header_checks

的內容/etc/postfix/header_checks如下:

/^From:(.*)/ REPLACE From: "$1" <root@example.com>

root@example.com 在 SES 得到確認。這與我在使用直接使用 SES 的 PHP 腳本進行測試時使用的電子郵件相同,即不重寫標題。

當我從@gmail 向 user@example.com 發送內容時,日誌中發生了以下情況:

Apr  8 15:04:05 ip-10-191-106-25 postfix/smtpd[32545]: connect from mail-wg0-f42.google.com[74.125.82.42]
Apr  8 15:04:06 ip-10-191-106-25 postfix/smtpd[32545]: 3252A2415D: client=mail-wg0-f42.google.com[74.125.82.42]
Apr  8 15:04:06 ip-10-191-106-25 postfix/cleanup[32550]: 3252A2415D: message-id=<CADLOpCq4ZFR5=xqTNxPO73-tVkF63urLt_9ueGBDrLSggy29MQ@mail.gmail.com>
Apr  8 15:04:06 ip-10-191-106-25 postfix/qmgr[32192]: 3252A2415D: from=<user@gmail.com>, size=1687, nrcpt=1 (queue active)
Apr  8 15:04:06 ip-10-191-106-25 postfix/smtpd[32545]: disconnect from mail-wg0-f42.google.com[74.125.82.42]
Apr  8 15:04:07 ip-10-191-106-25 postfix/smtp[32551]: 3252A2415D: replace: header From: "User" <user@gmail.com>: From: " "User" <user@gmail.com>" <root@example.com>
Apr  8 15:04:07 ip-10-191-106-25 postfix/smtp[32551]: 3252A2415D: to=<user2@gmail.com>, orig_to=<user2@example.com>, relay=email-smtp.us-west-2.amazonaws.com[54.149.142.243]:25, delay=1.3, delays=0.22/0.03/0.57/0.43, dsn=5.0.0, status=bounced (host email-smtp.us-west-2.amazonaws.com[54.149.142.243] said: 554 Message rejected: Email address is not verified. (in reply to end of DATA command))
Apr  8 15:04:07 ip-10-191-106-25 postfix/cleanup[32550]: 7FD75243F8: message-id=<20150408150407.7FD75243F8@example.com>
Apr  8 15:04:07 ip-10-191-106-25 postfix/qmgr[32192]: 7FD75243F8: from=<>, size=3700, nrcpt=1 (queue active)
Apr  8 15:04:07 ip-10-191-106-25 postfix/bounce[32552]: 3252A2415D: sender non-delivery notification: 7FD75243F8
Apr  8 15:04:07 ip-10-191-106-25 postfix/qmgr[32192]: 3252A2415D: removed
Apr  8 15:04:08 ip-10-191-106-25 postfix/smtp[32551]: 7FD75243F8: to=<user@gmail.com>, relay=email-smtp.us-west-2.amazonaws.com[54.69.81.169]:25, delay=0.67, delays=0.01/0/0.59/0.07, dsn=5.0.0, status=bounced (host email-smtp.us-west-2.amazonaws.com[54.69.81.169] said: 501 Invalid MAIL FROM address provided (in reply to MAIL FROM command))
Apr  8 15:04:08 ip-10-191-106-25 postfix/qmgr[32192]: 7FD75243F8: removed

這讓我知道 From: 標頭實際上並沒有被重寫。但是,該行:

Apr  8 15:04:07 ip-10-191-106-25 postfix/smtp[32551]: 3252A2415D: replace: header From: "User" <user@gmail.com>: From: " "User" <user@gmail.com>" <root@example.com>

告訴我們它實際上是。

我意識到在將其發送到 AWS 伺服器之前,我需要查看重寫的整個郵件正文,但我不知道如何調試它。

這是 main.cf 的內容:

# See /usr/share/postfix/main.cf.dist for a commented, more complete version


# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = example.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = example.com, ip-10-191-106-25.ec2.internal, localhost.ec2.internal, localhost, domain2.example.com
relayhost = email-smtp.us-west-2.amazonaws.com
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
default_transport = smtp
relay_transport = relay

smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_password
smtp_use_tls = yes
smtp_tls_security_level = encrypt
smtp_tls_note_starttls_offer = yes

smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt

smtp_header_checks = pcre:/etc/postfix/header_checks

virtual_alias_maps = hash:/etc/postfix/virtual

sender_canonical_maps = hash:/etc/postfix/canonical

#debug_peer_list=email-smtp.us-west-2.amazonaws.com 127.0.0.1
#debug_peer_level=5

看起來您的初始目標header_checks是保留原始發件人並將其替換為允許的 Amazon SES 發件人。

上述方法的問題是**From:**標頭由於其中有多個引號而變得非標準。

From: " "User" <user@gmail.com>" <root@example.com>

Daniel R. Tobias 在他的文章中提到了這個問題:Dan’s Mail Format Site | 標題 | 從/到/CC/BCC

讓您的郵件程序有可能在您的郵件上造成非標準標題行的一件事是嘗試在您的姓名中包含引號,例如Jesse “The Body” Ventura。如果直接插入到標題中,用雙引號括起來,你會得到**“Jesse “The Body” Ventura”,它實際上解析成兩個帶引號的字元串,“Jesse ““Ventura”,而The Body**坐在中間,目的不確定.

因此,您可以依靠此非標準標頭繞過 Amazon SES 檢查器。


解決此問題的一種方法是將上述兩個目標拆分為兩個 header_checksheader_checkssmtp_header_checks. 第一個 header_checks 將在另一個自定義標頭(例如 X-Original-From)中保留原始發件人。第二個將替換**From:**標頭。

#main.cf
header_checks = pcre:/etc/postfix/first_header_checks
smtp_header_checks = pcre:/etc/postfix/second_header_checks

#first_header_checks
/^From:(.*)/ PREPEND X-Original-From: $1

#second_header_checks
/^From:(.*)/ REPLACE From: <root@example.com>

由於這種模式,**X-Original-From:**標頭將添加到每封傳入的電子郵件中。但替換操作將僅在外發電子郵件上執行。


另一種方法是使用 pcre 排除原始**From:**標頭中的引號。不幸的是,我現在沒有時間測試一些想法。也許稍後……我會用其他解決方法更新這個答案。

信封發件人地址改寫

以上部分仍然是半程。要通過亞馬遜 SES,您還需要重寫信封發件人地址。

除了包含標籤的地址(見下文)外,**您必須驗證將用作郵件“發件人”或“返迴路徑”地址的每個電子郵件地址(或電子郵件地址的域)。**在您的賬戶退出 Amazon SES 沙箱之前,您還必須驗證每個收件人的電子郵件地址,但 Amazon SES 郵箱模擬器提供的收件人除外。

請參閱本文中的信封地址與郵件頭地址之間的區別。

我已經在類似的執行緒中解釋了一些重寫發件人的步驟:AWS SES: “Email address is not verify” error with Postfix relay。基本上你需要把這個參數放在main.cf

sender_canonical_maps = regexp:/etc/postfix/sender_canonical
sender_canonical_classes = envelope_sender
smtpd_data_restrictions = check_sender_access pcre:/etc/postfix/sender_access

在 /etc/postfix/sender_canonical 中,添加

/.*/    mysenderaddress@example.com

在 /etc/postfix/sender_access 中,添加

/(.*)/  prepend X-Envelope-MailFrom: <$1>

/etc/postfix/sender_access用於保存原始信封發件人地址。

引用自:https://serverfault.com/questions/681278