Envelope Fromのためのアライメント

Amazon SESでSPFのDMARC Alignmentチェックを通過するためのEnvelope From設定方法

執筆
更新
著者: 竹洞 陽一郎

Amazon SESでは、DKIM認証についてはCNAMEの設定を行うことで、独自ドメインによる署名が可能になり、DMARCのAlignmentチェックをパスできます。
一方、SPF認証では「カスタムMAILFROM」設定を利用しても、自動的にEnvelope Fromが自社ドメインで設定されるわけではありません。
そのため、SPFのDMARC Alignmentチェックをパスするためには、送信時に認証済みの自社ドメインをEnvelope Fromに明示的に設定する必要があります。

補足: EnvelopeFrom はSMTPのMAIL FROMコマンドで指定される送信者アドレスです。
一方、Return-Pathは配送途中のMTAが付与するヘッダーで、送信時に必ずしも明示的に設定されるものではありません。
実際、多くのケースではEnvelopeFromの値がReturn-Pathにコピーされるため、同一視されがちですが、厳密には異なる概念です。

以下に、Envelope Fromを設定する方法を実装難易度の低い順に、6つご紹介します。
各方法はシチュエーションに応じてご利用ください。

方法1: AWS SDK for Python (Boto3) を使用したメール送信例

この例では、Amazon SES の send_email メソッドを利用し、ReturnPath パラメータに bounce@example.com を指定しています。
ReturnPath はバウンス・苦情通知の転送先アドレスを指定するパラメータで、指定した値は上書きされません。また、指定するアドレスは Amazon SES で検証済みである必要があります。
原典: Boto3 ドキュメント — SES.Client.send_email

実装コード例


import boto3

# SESクライアントの作成(リージョンは適宜変更してください)
ses_client = boto3.client('ses', region_name='us-east-1')

# メール送信リクエスト
response = ses_client.send_email(
    Source='sender@example.com',
    Destination={
        'ToAddresses': ['recipient@example.com']
    },
    Message={
        'Subject': {
            'Data': 'Test email'
        },
        'Body': {
            'Text': {
                'Data': 'This is a test email.'
            }
        }
    },
    # Return Pathを明示的に設定
    ReturnPath='bounce@example.com'
)

print(response)

方法2: AWS SDK for Python (Boto3) の send_raw_email を使用したメール送信例

send_raw_email メソッドを使用する場合、Source パラメータにアイデンティティのメールアドレスを指定できます。
Source パラメータを指定し、かつフィードバック転送が有効な場合、バウンス・苦情通知はこのアドレスに転送されます。これは生メッセージ内の Return-Path ヘッダーより優先されます(AWS 公式ドキュメントより)。
原典: Boto3 ドキュメント — SES.Client.send_raw_email

実装コード例


import boto3
from email.mime.text import MIMEText

# SES クライアントの作成(リージョンは適宜変更してください)
ses_client = boto3.client('ses', region_name='us-east-1')

# メッセージの作成
msg = MIMEText('This is a test email.')
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
msg['Subject'] = 'Test email'

# send_raw_email の Source パラメータでバウンス・苦情通知の転送先を指定
response = ses_client.send_raw_email(
    Source='bounce@example.com',   # バウンス・苦情通知の転送先(Return-Path ヘッダーより優先)
    Destinations=['recipient@example.com'],
    RawMessage={'Data': msg.as_bytes()}
)

print(response)

補足: send_raw_emailSource パラメータは、バウンス・苦情通知の転送先を指定するものです。フィードバック転送が有効な場合、生メッセージ内に Return-Path ヘッダーが含まれていても Source の値が優先されます。
なお、Source パラメータを指定しない場合は、生メッセージ内の From ヘッダーの値が使用されます。

方法3: Python の smtplib における sendmail の第1引数によるEnvelope From指定

smtplib を使用する場合、sendmail() の第1引数(from_addr)が SMTP の MAIL FROM コマンドに対応し、これが実際のEnvelope From(Return-Path)になります。
メールヘッダーへの Return-Path の追加とは独立して機能するため、Envelope Fromを確実に制御するには第1引数を正しく設定することが重要です。
原典: Python ドキュメント — smtplib.SMTP.sendmail()

実装コード例


import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

# SMTP サーバ設定(Amazon SES の SMTP エンドポイント)
SMTP_SERVER = "email-smtp.us-east-1.amazonaws.com"
SMTP_PORT = 587
SMTP_USER = "your-smtp-username"
SMTP_PASS = "your-smtp-password"

# メールの基本情報
from_email = "sender@example.com"
to_email = "recipient@example.com"
subject = "Test email"
body = "This is a test email."

# MIMEText オブジェクトの作成
msg = MIMEText(body)
msg['From'] = formataddr(('Sender Name', from_email))
msg['To'] = to_email
msg['Subject'] = subject

# SMTP サーバに接続してメール送信
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
    server.starttls()  # TLS 接続を開始
    server.login(SMTP_USER, SMTP_PASS)
    # sendmail の第1引数(from_addr)が SMTP の MAIL FROM コマンドになり、
    # 受信側で Return-Path ヘッダーとして記録される
    server.sendmail('bounce@example.com', to_email, msg.as_string())

方法4: Python の smtplib を使用したメール送信例(SMTP経由)

この例では、smtplib ライブラリを用いて SMTP サーバ経由でメールを送信し、メールヘッダーに Return-Path を追加しています。
注意: Amazon SES の SMTP インターフェースでは、SMTP の MAIL FROM コマンドがメール内の Return-Path ヘッダーより優先されます。そのため、実際のEnvelope From(Return-Path)を制御するには、前述の「smtplib における sendmail の第1引数」の方法を使用してください。
原典: Python ドキュメント — smtplib.SMTP.sendmail()

実装コード例


import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

# SMTPサーバ設定(Amazon SESのSMTPエンドポイント)
SMTP_SERVER = "email-smtp.us-east-1.amazonaws.com" 
SMTP_PORT = 587
SMTP_USER = "your-smtp-username" 
SMTP_PASS = "your-smtp-password" 

# メールの基本情報
from_email = "sender@example.com" 
to_email = "recipient@example.com" 
subject = "Test email" 
body = "This is a test email." 

# MIMETextオブジェクトの作成
msg = MIMEText(body)
msg['From'] = formataddr(('Sender Name', from_email))
msg['To'] = to_email
msg['Subject'] = subject

# Return-Pathヘッダーを追加(注意:SMTPのMAIL FROMとは別に、ヘッダー情報としても設定)
msg.add_header('Return-Path', 'bounce@example.com')

# SMTPサーバに接続してメール送信
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
    server.starttls()  # TLS接続を開始
    server.login(SMTP_USER, SMTP_PASS)
    server.sendmail(from_email, to_email, msg.as_string())

方法5: カスタム MAIL FROM ドメインの設定(SES コンソール / AWS CLI)

コードを変更せずにEnvelope Fromを自社ドメインに固定する方法として、Amazon SES の「カスタム MAIL FROM ドメイン」設定があります。
この設定を行うと、そのアイデンティティから送信されるすべてのメールのEnvelope Fromが、指定したサブドメインに自動的に設定されます。
設定後は送信コードを変更する必要がなく、ドメイン単位・メールアドレス単位のどちらにも適用できます。

設定手順(コンソール)

  1. Amazon SES コンソール → Configuration > Verified identities を開く
  2. 対象ドメインを選択 → MAIL FROM domain タブ → Edit
  3. サブドメイン(例: bounce.example.com)を入力して保存
  4. 表示される MX レコードと TXT レコードを自社の DNS に追加する

追加する DNS レコードは以下の形式です。


# MX レコード(バウンスメール受信用)
bounce.example.com  MX  10  feedback-smtp.us-east-1.amazonses.com

# TXT レコード(SPF レコード)
bounce.example.com  TXT  "v=spf1 include:amazonses.com ~all"

AWS CLI を使用して同じ設定を行う場合は、以下のコマンドを実行します。


aws ses set-identity-mail-from-domain \
  --identity example.com \
  --mail-from-domain bounce.example.com

注意: カスタム MAIL FROM ドメインは検証済みドメインのサブドメインである必要があります。また、MX レコードは必ず 1 件だけ公開してください。複数の MX レコードが存在すると設定が失敗します。
原典: Amazon SES デベロッパーガイド — カスタム MAIL FROM ドメインの使用 / AWS CLI リファレンス — set-identity-mail-from-domain

方法6: Terraform を使用したカスタム MAIL FROM ドメインの設定例

インフラをコードで管理している場合、Terraform の aws_ses_domain_mail_from リソースを使用して、カスタム MAIL FROM ドメインと必要な DNS レコードをまとめて設定できます。

実装コード例


# カスタム MAIL FROM ドメインの設定
resource "aws_ses_domain_mail_from" "main" {
  domain           = aws_ses_domain_identity.main.domain
  mail_from_domain = "bounce.${var.domain_name}"
}

# MX レコード(バウンスメール受信用)
resource "aws_route53_record" "mail_from_mx" {
  zone_id = var.route53_zone_id
  name    = "bounce.${var.domain_name}"
  type    = "MX"
  ttl     = 600
  records = ["10 feedback-smtp.${var.aws_region}.amazonses.com"]
}

# TXT レコード(SPF レコード)
resource "aws_route53_record" "mail_from_spf" {
  zone_id = var.route53_zone_id
  name    = "bounce.${var.domain_name}"
  type    = "TXT"
  ttl     = 600
  records = ["v=spf1 include:amazonses.com ~all"]
}

DNS に Amazon Route 53 を使用している場合は、上記のように Terraform で DNS レコードの作成まで自動化できます。Route 53 以外の DNS プロバイダを使用している場合は、コンソールまたは CLI で取得したレコード値を手動で登録してください。
原典: Terraform Registry — aws_ses_domain_mail_from

これらの方法を参考に、Return-Pathを正しく設定することで、SPFのDMARC Alignmentチェックをパスし、メールの信頼性を向上させることができます。