通过AWS SES使用postfix转发电子邮件

我有一台安装了postfix MTA的服务器,它接受我的域名的邮件,下面是@ example.com。 我需要设置转发某些[email protected]到其他电子邮件。 例如@ gmail.com,这需要通过SES使用SMTP传输完成。

我有SES生产访问和login/密码对,这是积极的,并具有IAM的权限,我检查。 我已经在SES确认了From: address。 如果我直接通过SES从PHP脚本发送带有这些SMTP用户名/密码的电子邮件,一切正常。 这意味着login名/密码对和From:都可以。

现在我需要重写From:用于从外部发送并且需要被转发的电子邮件。 例如,一封电子邮件是从@ gmail.com – > [email protected]发送的。 input用户在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" <[email protected]> 

[email protected]在SES确认。 这是我在使用直接使用SES的PHP脚本进行testing时使用的同一封电子邮件,即没有标题重写。

当我从@gmail向[email protected]发送一些信息时,以下是日志中发生的事情:

 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=<[email protected]>, 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" <[email protected]>: From: " "User" <[email protected]>" <[email protected]> Apr 8 15:04:07 ip-10-191-106-25 postfix/smtp[32551]: 3252A2415D: to=<[email protected]>, orig_to=<[email protected]>, 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=<[email protected]> 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=<[email protected]>, 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" <[email protected]>: From: " "User" <[email protected]>" <[email protected]> 

告诉我们它实际上已经。

我意识到我需要在发送到AWS服务器之前查看重写的整个邮件正文,但我不知道如何debugging它。

这里是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是保留原始的发件人,并取而代之的允许的发送者的亚马逊SES。

您的方法上面的问题是由于报头变成非标准,因为在那里多引号。

 From: " "User" <[email protected]>" <[email protected]> 

Daniel R. Tobias在他的文章中提到了这个问题: Dan的邮件格式网站| 标题| 自/至/ CC / BCC

有一件事会让你的邮件程序在你的邮件中添加非标准标题的风险是试图在你的名字中加上引号,如Jesse“The Body”Ventura 。 如果直接插入标题,在双引号内,你会得到“杰西”身体“文图拉” ,其实际上分析成两个引用的string, “杰西”“文图拉”身体坐在中间以不确定的目的。

所以您可以依靠这个非标准头来绕过Amazon SES检查器。


解决这个问题的一个方法是将上述两个目标分成两个header_checks, header_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: <[email protected]> 

由于这个模式, X-Original-From:头将被添加到每个传入的电子邮件中。 但是replace动作只会在外发电子邮件上执行。


另一种方法是使用pcre排除原始From:标题中的引号。 不幸的是,我现在没有时间去testing一些想法。 也许以后…我会用其他解决方法更新这个答案。

信封发件人地址重写

以上部分还是半程。 要通过亚马逊SES,您也需要重写信封发件人地址。

除了包含标签的地址(见下文)之外, 您必须validation您将用作邮件的“From”或“Return-Path”地址的每个电子邮件地址(或电子邮件地址的域)。 在您的帐户不在Amazon SES沙箱之前,您还必须validation除Amazon SES邮箱模拟器提供的收件人以外的每个收件人的电子邮件地址。

请参阅本文中的信封地址与邮件标题地址之间的差异。

我已经解释了一些在这个类似的线程中重写发件人的一些步骤:使用Postfix中继的AWS SES:“电子邮件地址未validation”错误 。 基本上你需要把这个参数放在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中添加

 /.*/ [email protected] 

在/ etc / postfix / sender_access中,添加

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

/etc/postfix/sender_access用于保留原始信封发件人地址。

在这一步之后,我的工作能够将服务器内部的电子邮件转发给客户 – >

 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添加

 /.*/ [email protected] 

/etc/postfix/sender_access添加

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