はじめに
NTTテクノクロス株式会社の渡邉洋平です。
今回はAWS CDKを使用して、「SPF、DKIM、DMARC設定を行ったAmazon SESを作成する方法」について解説します。
CDKでドメイン回りを設定するのは鬼門なのか、検索してもすぐに見つからない情報だったので、手を動かして実際に試してみました。
参考:SPF、DKIM、DMARC
送信元のなりすましを検出するための認証として「送信ドメイン認証」という技術が一般的にあります。
SPF、DKIM、DMARCの詳細は下記のような記事でも把握できるので割愛します。これら3つの対応をすべて実施することで、送信元の信頼性を高めることができます。
1. hostzoneの参照
※前提として、送信元メールアドレスを事前に同じアカウントのRoute53のホストゾーンに設定してあるものとします。
まずはじめに、指定済みのホストゾーンをCDKのコードから参照します。
- この例では、example.comがドメインとして定義されている既存のpublicHostZoneを参照(
fromLookup
)している。
const domainName: string = "example.com";
const hostedZone = route53.PublicHostedZone.fromLookup(
this,
"existHostZone",
{
domainName: domainName,
}
);
2. 適切なメール配信設定を行う
次に、Amazon SESの設定を行います。ここでは、ses.EmailIdentityを使用して、SESの設定を行っています。
const identity = new ses.EmailIdentity(this, 'Identity', {
identity: ses.Identity.publicHostedZone(hostedZone),
mailFromDomain: `bounce.${domainName}`,
});
SPF設定
Amazon SESとして必要な手順は以下の通りです。
CDKのL2 Constructとしては、上記のmailFromDomain
設定を入力した時点で完了です。ses.EmailIdentity
が自動的にホストゾーンを編集してくれます。これは非常に便利ですね!
DKIM設定
Amazon SESとして必要な手順は以下の通りです。
実はDKIM設定もCDKのL2 Constructとしては、デフォルト値としてEasy DKIMを有効にしてくれる設定(dkimSigning: true)なので、これで十分であれば特別な設定は要りません。
BYODKIMなどを実施したい場合はこちらを参考にすると指定できます。
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ses.DkimIdentity.html
DMARC
Amazon SESとして必要な手順は以下の通りです。
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/send-email-authentication-dmarc.html
こちらは現行のCDK(v2.75.0)のConstructでは未対応であるため、明示的にDMARC設定を行います。具体的にはroute53.TxtRecord
を使用して、DMARCのTXTレコードを作成します。
new route53.TxtRecord(this, 'DmarcRecord', {
zone: hostedZone,
recordName: `_dmarc.${domainName}`,
values: [`v=DMARC1; p=none; rua=mailto:dmarcreports@${domainName}`],
ttl: Duration.hours(1),
});
これで、Route53のホストゾーンでサブドメインを定義し、Amazon SESの設定とDMARC設定が完了しました。
コード
最後にこれまで説明したコードを改めて掲載します。
import { Duration, Stack, StackProps, RemovalPolicy } from "aws-cdk-lib";
import { Construct } from "constructs";
import * as route53 from "aws-cdk-lib/aws-route53";
import * as ses from "aws-cdk-lib/aws-ses";
export class Route53Stack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const domainName: string = "example.com";
const hostedZone = route53.PublicHostedZone.fromLookup(
this,
"existHostZone",
{
domainName: domainName,
}
);
const identity = new ses.EmailIdentity(this, "Identity", {
identity: ses.Identity.publicHostedZone(hostedZone),
mailFromDomain: `bounce.${domainName}`,
});
new route53.TxtRecord(this, "DmarcRecord", {
zone: hostedZone,
recordName: `_dmarc.${domainName}`,
values: [
`v=DMARC1; p=none; rua=mailto:dmarcreports@${domainName}`,
],
ttl: Duration.hours(1),
});
}
}
Appendix. to CloudFormation Template
理解を深めるため、CDKからDumpしたCloudformationテンプレートも記載します。(一部はマスク済)
Resources:
IdentityDkimDnsToken133E6CCBA:
Type: AWS::Route53::RecordSet
Properties:
Name:
Fn::GetAtt:
- Identity2D60E2CC
- DkimDNSTokenName1
Type: CNAME
HostedZoneId: XXXXXXXXXXXXXXXXXXXX
ResourceRecords:
- Fn::GetAtt:
- Identity2D60E2CC
- DkimDNSTokenValue1
TTL: "1800"
IdentityDkimDnsToken2AD0AA6D9:
Type: AWS::Route53::RecordSet
Properties:
Name:
Fn::GetAtt:
- Identity2D60E2CC
- DkimDNSTokenName2
Type: CNAME
HostedZoneId: XXXXXXXXXXXXXXXXXXXX
ResourceRecords:
- Fn::GetAtt:
- Identity2D60E2CC
- DkimDNSTokenValue2
TTL: "1800"
IdentityDkimDnsToken3A6A24F78:
Type: AWS::Route53::RecordSet
Properties:
Name:
Fn::GetAtt:
- Identity2D60E2CC
- DkimDNSTokenName3
Type: CNAME
HostedZoneId: XXXXXXXXXXXXXXXXXXXX
ResourceRecords:
- Fn::GetAtt:
- Identity2D60E2CC
- DkimDNSTokenValue3
TTL: "1800"
Identity2D60E2CC:
Type: AWS::SES::EmailIdentity
Properties:
EmailIdentity: example.com
MailFromAttributes:
MailFromDomain: bounce.example.com
IdentityMailFromMxRecord4D92B544:
Type: AWS::Route53::RecordSet
Properties:
Name: bounce.example.com.
Type: MX
HostedZoneId: XXXXXXXXXXXXXXXXXXXX
ResourceRecords:
- 10 feedback-smtp.us-east-1.amazonses.com
TTL: "1800"
IdentityMailFromTxtRecord8A2CF0BC:
Type: AWS::Route53::RecordSet
Properties:
Name: bounce.example.com.
Type: TXT
HostedZoneId: XXXXXXXXXXXXXXXXXXXX
ResourceRecords:
- '"v=spf1 include:amazonses.com ~all"'
TTL: "1800"
DmarcRecord17E400DB:
Type: AWS::Route53::RecordSet
Properties:
Name: _dmarc.example.com.
Type: TXT
HostedZoneId: XXXXXXXXXXXXXXXXXXXX
ResourceRecords:
- '"v=DMARC1; p=none; rua=mailto:dmarcreports@example.com"'
TTL: "3600"
まとめ
このようにAWS CDKを使用することで、SPF、DKIM、DMARC設定を実施したAmazon SESを簡単に作成することができました。
今回紹介したCDKコードを使用すれば、独自のドメインでメール配信を行う際に必要な設定を簡単に行うことができます。ぜひこのコードを参考に、自分のプロジェクトでCDKを活用してください!
Comments
Let's comment your feelings that are more than good