Amazon Route 53 以外のドメインレジストラ (お名前.com) を使って Amazon SES の SPF, DKIM, DMARC を設定してみる

お名前.com を使って Amazon SES の SPF, DKIM, DMARC を設定する
2020.10.06

はじめに

おはようございます、もきゅりんです。

前回ブログのAmazon SES でメール送信するときのベストプラクティスまとめ(2020年10月) では、 SESのEメール認証を Amazon Route 53 を用いて行いました。

当たり前ですが、同じAWSのサービスで連携するととてもスムーズに設定ができました。

では、 Route53 ではないドメインレジストラで対応するとどうなのか。

本稿では、SESと同じAWSアカウントの Route53 ではない、別ドメインレジストラで対応するとどんな作業になるか、をまとめてみました。(もちろん、ドメインレジストラ毎に仕様は異なるはずなので、あくまで一参考例にしかなりませんが。)

別ドメインレジストラとして、お名前.com を利用します。

なお、本稿では改めて SPF, DKIM, DMARC の詳しい説明はしません。(SPF, DKIM, DMARC は被害が後を絶たない、なりすましメールの対策に有効な手法となる「送信ドメイン認証」の方法です。それぞれ異なった技術の認証方式であり、どれかではなく、組み合わせて行うことが重要になります。)

email_authentication

仕組みの概要については下記のようなページで参照下さい。

送信ドメイン認証(SPF / DKIM / DMARC)の仕組みと、なりすましメール対策への活用法を徹底解説

4-2 送信ドメイン認証: 迷惑メール相談センター

やること

  1. Amazon SES でドメインの承認(およびDKIM署名の設定)
  2. ドメインレジストラ(お名前.com)でDNSレコードの追加
  3. Amazon SES でカスタム MAIL FROM ドメインの設定
  4. メール送信して確認

前提

  • 別ドメインレジストラ (お名前.com) でDNS購入済みであること

1. Amazon SES でドメインの承認(およびDKIM署名の設定)

SES Home から Verify a New Domain を押下して 対象とする (別レジストラで登録している) ドメインを入力します。 Generate DKIM Settings を忘れずチェックします。

aws_verify_domain

すると、DNSレコードが4つ表示されます。

domain_verify_dkim

内訳として以下となります。

  • _amazonses.YOUR_DOMAIN_NAME: ドメイン検証用のTXTレコード
  • hogehoge_domainkey.YOUR_DOMAIN_NAME: DKIM設定用のCNAMEレコード3つ
  • YOUR_DOMAIN_NAME: メール受信用のMXレコード

これらを別ドメインレジストラ (お名前.com) のDNSレコードに追加する必要があります。(本稿ではメール受信を対応しないので、MXレコードの追加は必要ありません。)

補足ですが、SES で DKIM を使用して Eメールを認証する場合、3つの方法があります。

最も簡単なのが、今回対応している EasyDKIM です。

その他、独自の公開鍵と秘密鍵のペアを使用してDKIM認証ができる Bring Your Own DKIM(BYODKIM) 、手動でDKIM署名して SendRawEmail API でメールを送信する方法もあります。

詳細は、Authenticating Email with DKIM in Amazon SES を確認下さい。

2. Route 53 以外のドメインレジストラ(お名前.com)でDNSレコードの追加

説明は後述するとして、先に必要なものを列挙します。

追加するレコードとしては、前節の4つのレコード (TXTレコード + 3つのCNAMEレコード) に3つ加えて、計7つになります。

  • _amazonses.YOUR_DOMAIN_NAME: ドメイン検証用のTXTレコード
  • hogehoge_domainkey.YOUR_DOMAIN_NAME: DKIM設定用のCNAMEレコード3つ
  • カスタム MAILFROM ドメイン用の MX, TXT レコード2つ
  • ドメインの DMARC 設定用のTXTレコード1つ

追加された結果のイメージです。

onamae_dns_records

追加される3レコードの内容が以下です。

カスタム MAILFROM ドメインのレコード設定

カスタム MAILFROM ドメインの設定では、ドメインがメールプロバイダーから送信されたバウンスと苦情の通知を受信できるように、MXレコードを公開する必要があります。また、Amazon SESがドメインからのメール送信を許可されていることを証明するために、SPFレコードを公開する必要があります。

Name Type Value
subdomain.domain.com MX 10 feedback-smtp.region.amazonses.com
subdomain.domain.com TXT v=spf1 include:amazonses.com ~all

ドメインに既存のSPFレコードがない場合は、次の値でTXTレコードを公開します。DNSサービスに応じて、レコードの名前を空白または@にすることができます。

"v=spf1 include:amazonses.com ~all"

ドメインにすでにSPFレコードがある場合は、次の形式を使用して Amazon SESのステートメントを追加できます。

"v=spf1 include:YOUR_DOMAIN_NAME include:amazonses.com ~all"

一部の DNS プロバイダーの管理コンソールには、レコードの [値] とレコードの [Priority (優先度)] に別々のフィールドがあります。​ これが DNS プロバイダーである場合は、[Priority (優先度)] 値に 10 を入力し、[値] に受信メールエンドポイント URL を入力します。​

onamae_mx_record

DMARC のレコード設定

DMARCの設定を行うには、ドメインの DMARC 設定を指定するTXTレコードを含める必要があります。

Name Type Value
_dmarc.example.com TXT v=DMARC1;p=quarantine;pct=25;rua=mailto:dmarcreports@example.com

カスタム MAIL FROM ドメイン、DMARCの設定の詳細についてはそれぞれ下記を確認下さい。

3. Amazon SES でカスタム MAIL FROM ドメインの設定

2 で設定したカスタム MAIL FROM ドメインと同一のドメイン名を入力します。

set_mail_from_domain

2 で設定した カスタム MAIL FROM ドメイン用の MX, TXTレコードが表示されます。

aws_custom_mail_from_domain

ドメイン検証の完了およびカスタムMAILFROMドメインが正常に設定されることを通知するEメー​​ルが届くのを待ちます。

1時間くらいで対応完了します。

verify_ses_domain

verify_custom_domain

4. メール送信して確認

コンソールからテストしてみる

コンソールからテスト送信してみます。

send_test_email_console

結果をメッセージのソースから確認します。

message_result_from_console

ちゃんと設定できています。

Lambda を使って SendEmail API でテストしてみる

まあ、コンソールでやってることは同じなのですが、 Python で SendEmail API を実行してみます。

先に 実行する Lambda 関数に設定する IAM Role を作成します。

信頼されたエンティティは Lambda です。

entity_lambda

ロールにアタッチするポリシーはAWS管理ポリシーの下記としました。

  • AWSLambdaBasicExecutionRole
  • AmazonSESFullAccess

今回実行するポリシーとしては、SESFullAccess ではなく、これでも十分です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail"
            ],
            "Resource": "*"
        }
    ]
}

ロール名は適当で構いません。

Lambdaを一から作成します。関数の名前も適当で Python3.8 を選択します。

先ほど作成したロールを使用して関数を作成します。

lambda_roll

Sending email using AWS SDKs からコード例は拝借します。外に出せるものは環境変数として設定します。

import boto3
import os
from botocore.exceptions import ClientError

# Replace sender@example.com with your "From" address.
# This address must be verified with Amazon SES.
SENDER = os.environ['SENDER']

# Replace recipient@example.com with a "To" address. If your account 
# is still in the sandbox, this address must be verified.
RECIPIENT = os.environ['RECIPIENT']

# If necessary, replace us-west-2 with the AWS Region you're using for Amazon SES.
AWS_REGION = os.environ['AWS_REGION']

# The character encoding for the email.
CHARSET = os.environ['CHARSET']

# The subject line for the email.
SUBJECT = "Amazon SES Test (SDK for Python)"

# The email body for recipients with non-HTML email clients.
BODY_TEXT = ("Amazon SES Test (Python)\r\n"
             "This email was sent with Amazon SES using the "
             "AWS SDK for Python (Boto)."
            )
            
# The HTML body of the email.
BODY_HTML = """<html>
<head></head>
<body>
  <h1>Amazon SES Test (SDK for Python)</h1>
  <p>This email was sent with
    <a href='https://aws.amazon.com/ses/'>Amazon SES</a> using the
    <a href='https://aws.amazon.com/sdk-for-python/'>
      AWS SDK for Python (Boto)</a>.</p>
</body>
</html>
            """            

def send_email(sender, recipient, charset, subject, body_html, body_text):

    # Create a new SES resource and specify a region.
    client = boto3.client('ses',region_name=AWS_REGION)
    
    # Try to send the email.
    try:
        #Provide the contents of the email.
        response = client.send_email(
            Destination={
                'ToAddresses': [
                    recipient,
                ],
            },
            Message={
                'Body': {
                    'Html': {
                        'Charset': charset,
                        'Data': body_html,
                    },
                    'Text': {
                        'Charset': charset,
                        'Data': body_text,
                    },
                },
                'Subject': {
                    'Charset': charset,
                    'Data': subject,
                },
            },
            Source=sender,
        )
    
    # Display an error if something goes wrong.	
    except ClientError as e:
        print(e.response)
        return e.response['Error']['Message']
    else:
        print(response)
        return "Email sent! Message ID:" + response['MessageId']

    
def lambda_handler(event, context):
    res = send_email(SENDER, RECIPIENT, CHARSET, SUBJECT,BODY_HTML, BODY_TEXT)
    return res

念のため注意としては、環境変数 SENDER には設定したカスタム MAIL FROM ドメインをそのまま入れてはいけません。

{'Error': {'Type': 'Sender', 'Code': 'InvalidParameterValue', 'Message': "Missing final '@domain'"} というエラーが発生します。

When you verify an entire domain, you are verifying all email addresses from that domain, so you don't need to verify email addresses from that domain individually. For example, if you verify the domain example.com, you can send email from user1@example.com, user2@example.com, or any other user at example.com.

Verifying domains in Amazon SES には記載されているので、確認されたドメインで適当なメールアドレスを設定する必要があります。

それではテストしてみます。

lambda_ses_api_result

ちゃんとできました。

最後に

Amazon Route53 以外のドメインレジストラ (お名前.com) を使って Amazon SES の SPF, DKIM, DMARC を設定してみました。

Route53 に比べるとちょっとだけ手間がかかりますが、それでも簡単に設定できますね。

簡単に設定できるので、信頼性が高く、受信者に優しいメールを送るようにしましょう!

以上です。

どなたかのお役に立てば幸いです。

参考