Назад | Перейти на главную страницу

Пересылка электронной почты с постфиксом через AWS SES

У меня есть сервер с установленным postfix MTA, который принимает почту для моего домена, далее @ example.com. Мне нужно настроить переадресацию для определенных писем по адресу emails@example.com на другие письма. например @ gmail.com, и это необходимо сделать с помощью транспорта SMTP через SES.

У меня есть производственный доступ к SES и пара логин / пароль, которая активна и имеет разрешения IAM, я проверил. Я подтвердил определенные Из: обращайтесь в СЭС. Если я отправлю электронное письмо с этим именем пользователя / паролем SMTP напрямую через SES из сценария PHP, все будет работать нормально. Это означает, что пара логин / пароль и Из: все в порядке.

Теперь мне нужно переписать Из: для электронных писем, которые приходят извне и должны быть переадресованы. Например, письмо отправлено с адреса @ gmail.com -> user@example.com. Входящий пользователь установлен в virtual_alias_maps и должен перейти на другой @ gmail.com. Чтобы переписать Из: заголовок, следующие 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. Это тот же адрес электронной почты, который я использую при тестировании с помощью PHP-скрипта, который напрямую использует SES, то есть без перезаписи заголовка.

Когда я отправляю что-то с @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

после этого шага я могу пересылать электронное письмо изнутри сервера клиенту ->

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>

Похоже, ваша первоначальная цель с header_checks сохраняет первоначального отправителя и заменяет его разрешенным отправителем Amazon SES.

Проблема вашего подхода выше - это Из: заголовок стал нестандартным из-за нескольких кавычек.

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

Даниэль Р. Тобиас упомянул об этом в своей статье: Сайт формата почты Дэна | Заголовки | От / К / CC / BCC

Одна вещь, которая подвергнет вас риску того, что ваша почтовая программа добавит нестандартные строки заголовка к вашим сообщениям, - это попытка включить кавычки в ваше имя, например Джесси "Тело" Вентура. Если вставить прямо в заголовок в двойных кавычках, вы получите "Джесси" Тело "Вентура", который фактически разбирается на две строки в кавычках, "Джесси" и "Вентура", с участием Тело сидит посередине с неопределенной целью.

Таким образом, вы можете положиться на этот нестандартный заголовок, чтобы обойти проверку Amazon SES.


Один из подходов к решению этой проблемы - разделить две указанные выше цели на две header_checks, header_checks и smtp_header_checks. Первые header_checks сохранят исходного отправителя в другом настраиваемом заголовке (например, X-Original-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-оригинал-от: заголовок будет добавлен в каждое входящее письмо. Но действие замены будет выполнено только для исходящей почты.


Другой способ - использовать pcre для исключения цитаты из оригинала. Из: заголовок. К сожалению, сейчас у меня нет времени проверять некоторые идеи. Может быть, позже ... Я дополню этот ответ другим обходным путем.

Перезапись адреса отправителя конверта

Вышеупомянутые части - это еще половина пути. Чтобы пройти Amazon SES, вам также необходимо переписать адрес отправителя конверта.

За исключением адресов, содержащих метки (см. Ниже), вы должны подтвердить каждый адрес электронной почты (или домен адреса электронной почты), который вы будете использовать в качестве адреса «От» или «Обратного пути» для своих сообщений. Пока ваша учетная запись не находится в изолированной программной среде Amazon SES, вы также должны проверять адрес электронной почты каждого получателя, кроме получателей, указанных симулятором почтового ящика Amazon SES.

См. Различия между адресом конверта и адресом заголовка сообщения в Эта статья.

Я объяснил некоторые шаги, чтобы переписать отправителя в этой похожей цепочке: AWS SES: ошибка «Адрес электронной почты не подтвержден» с ретранслятором Postfix. В основном вам нужно поместить этот параметр в 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 используется для сохранения исходного адреса отправителя конверта.