今回はAWSのRoute53で取得したドメインを使ってSESからメールを配信できるようになるまでの手順を紹介したいと思います。
過去のZennのこの記事の再掲になります。
今回はAWS
のRoute53
で取得したドメインを使ってSES
からメールを配信できるようになるまでの手順を紹介したいと思います。
既にわかりやすく解説してくれている記事がいくつかありましたが(記事末尾の参考に載せてあります)、一部処理が端折られていたりしたので、それらを自分が噛み砕いてまとめた内容になります。
また、コンソールからではなく、AWS CLI
からの操作をメインとしていきます。
注意ですが、ドメインを実際に取得するのでお金がかかります。
検証の場合は安いTLD
を選択しましょう。
料金は下記の公式から参照できます。
https://aws.amazon.com/jp/route53/pricing/
まずはRoute53
で任意のドメインを取得します。
ドメインは以降のコマンド中でも頻繁に登場するので$domain
としておきます。
export domain=<取得したいドメイン>
まずはドメインが取得できるかを確認します。
一点注意なのですが、下記コマンドではリージョンをus-east-1
としています。
これは、ドメインの取得がこのリージョンでしか行えないためです(以下リンク参照)。
https://docs.aws.amazon.com/ja_jp/general/latest/gr/r53.html
aws route53domains check-domain-availability \
--region us-east-1 \
--domain-name $domain
以下のレスポンスとなれば取得可能です。
{
"Availability": "AVAILABLE"
}
ドメインを取得するにあたり「管理者」と「登録者」と「テクニカル担当」の3者の連絡先が必要になります。
これらは同一の連絡先でも問題ありませんので実際の運用に合わせてください。
以下のフォーマットでJSON
を作成します。
個々の値の選択可能な範囲については以下のリンクを参照してください。 https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/domain-register-values-specify.html#contact-type-field
{
"FirstName": "<First Name>",
"LastName": "<Last Name>",
"ContactType": "Person | Company",
"OrganizationName": "<Organization Name>",
"AddressLine1": "<Address 1>",
"AddressLine2": "<Address 2>",
"City": "<City Name>",
"State": "<State Name>",
"CountryCode": "JP",
"ZipCode": "<Zip Code>",
"PhoneNumber": "+81.NNNNNNNNNN",
"Email": "<Mail Address>",
"Fax": "",
"ExtraParams": [
]
}
3者の内容が異なる場合は3種類のJSON
を作成します。
今回は全て同じ連絡先として以下コマンドでドメインを取得します。
※念の為1年のみ、自動更新はなしとしています。
aws route53domains register-domain \
--region us-east-1 \
--domain-name $domain \
--duration-in-years 1 \
--no-auto-renew \
--admin-contact file://contact.json \
--registrant-contact file://contact.json \
--tech-contact file://contact.json
レスポンスとしてOperationId
が返って来れば登録の手続きが行われています。
しばらく待つと、登録した連絡先に確認のメールが届くので、その中のリンクを踏むことで登録が完了します。
不正にドメインを移管されないようにロック処理を行います。
aws route53domains enable-domain-transfer-lock \
--region us-east-1 \
--domain-name $domain
これでドメインの取得に関わる手続きは完了です。
早速取得したドメインを使ってSES
側で設定をしていきます。
SES
をCognito
に紐づける用途の場合、リージョンがus-east-1
,us-west-2
,eu-west-1
のいずれかである必要があります(下記参照)。
https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-email.html
そういった用途の場合、どのリージョンで作業を行うかに気をつけましょう。
ここまでの手順でドメインが正常に取得できたいた場合、ホストゾーンが自動で作成されているので、そのIDを取得します。 ホストゾーンは権威DNSサーバにおけるゾーンファイルのことです。
aws route53 list-hosted-zones
以下のようなレスポンスが得られます。
{
"HostedZones": [
{
"Id": "<Hosted Zone ID>",
"Name": "<Domain>",
"CallerReference": "<CallerReference>",
"Config": {
"Comment": "HostedZone created by Route53 Registrar",
"PrivateZone": false
},
"ResourceRecordSetCount": 2
}
]
}
このうちのHosted Zone ID
の値はこのあと頻繁に登場するので$hostedZoneId
としておきます。
export hostedZoneId=<Hosted Zone ID>
SES
でドメインを使うためにはいくつか踏むステップがあります。
まずドメインに対しての検証トークンを取得し、それをDNS
のTXT
レコードに決められた書式で記載する必要があります。
検証トークンの取得を行います。
aws ses verify-domain-identity --domain $domain
以下のレスポンスが返ります。
{
"VerificationToken": "<YOUR_VERIFICATION_TOKEN>"
}
取得したトークンをTXT
レコードに書き込みます。
書き込むフォーマットは以下のようになります。
参考:https://docs.aws.amazon.com/ses/latest/DeveloperGuide/dns-txt-records.html
Name | Type | Value |
---|---|---|
amazonses.<YOURVERIFICATIONDOMAIN>. | TXT | "<YOURVERIFICATIONTOKEN>" |
このフォーマットに合わせてJSON
を作成します。
ドメインとトークンは取得したものに置き換えてください。
{
"Comment": "Add TXT Record",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "_amazonses.<Domain>.",
"Type": "TXT",
"TTL": 1800,
"ResourceRecords": [
{
"Value":"\"<YOUR_VERIFICATION_TOKEN>\""
}
]
}
}
]
}
この内容で書き込みを行います。
aws route53 change-resource-record-sets \
--hosted-zone-id $hostedZoneId \
--change-batch file://record-txt.json
しばらく待った後で下記コマンドで登録の状態を確認しましょう。
aws ses get-identity-verification-attributes \
--identities $domain \
--query 'VerificationAttributes.*.VerificationStatus' \
--output text
この結果がSuccess
になっていれば成功です。
※いつ手続きが完了するかの明確な線引きはできませんが、30分経ってもPending
のステータスの場合、どこかで手順を誤っている可能性があります。
続いてDKIM
の設定を行います。
DKIM
は送信者のなりすましを防ぐ仕組みで、メールに対して署名を行います。
DNS
側に公開鍵を登録(CNAME
レコード)しておき、それを用いて認証を行います。
公開鍵となるDKIM
トークンを発行します。
aws ses verify-domain-dkim \
--domain $domain
レスポンスは以下のようになります。
{
"DkimTokens": [
"<_YOUR_DKIM_TOKEN_1_>",
"<_YOUR_DKIM_TOKEN_2_>",
"<_YOUR_DKIM_TOKEN_3_>"
]
}
DKIM
トークンをCNAME
レコードで書き込みます。
書き込むフォーマットは以下のようになります。
参考:https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-authentication-dkim-easy.html
Name | Type | Value |
---|---|---|
<YOURDKIMTOKEN1>.domainkey.<YOURVERIFICATIONDOMAIN>. | CNAME | <YOURDKIMTOKEN1_>.dkim.amazonses.com |
<YOURDKIMTOKEN2>.domainkey.<YOURVERIFICATIONDOMAIN>. | CNAME | <YOURDKIMTOKEN2_>.dkim.amazonses.com |
<YOURDKIMTOKEN3>.domainkey.<YOURVERIFICATIONDOMAIN>. | CNAME | <YOURDKIMTOKEN3_>.dkim.amazonses.com |
このフォーマットに合わせてJSON
を作成します。
ドメインとトークンは取得したものに置き換えてください。
今回は3件レコードを登録するので、3種類のファイル作成が必要です。
それぞれrecord-cname1.json
,record-cname2.json
,record-cname3.json
とします。
以下はrecord-cname1.json
の例です。
{
"Comment": "Add CNAME1",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "<_YOUR_DKIM_TOKEN_1_>._domainkey.<Domain>.",
"Type": "CNAME",
"TTL": 1800,
"ResourceRecords": [
{
"Value": "<_YOUR_DKIM_TOKEN_1_>.dkim.amazonses.com"
}
]
}
}
]
}
以下コマンドでレコードを登録します。
aws route53 change-resource-record-sets \
--hosted-zone-id $hostedZoneId \
--change-batch file://record-cname1.json
aws route53 change-resource-record-sets \
--hosted-zone-id $hostedZoneId \
--change-batch file://record-cname2.json
aws route53 change-resource-record-sets \
--hosted-zone-id $hostedZoneId \
--change-batch file://record-cname3.json
TXT
レコードの時と同様、しばらく待った後で下記コマンドを実行しSuccess
となっていれば設定は完了です。
aws ses get-identity-dkim-attributes \
--identities $domain \
--query 'DkimAttributes.*.DkimVerificationStatus'
DKIM
と同様にSPF
の設定を行います。
SPF
は用途としてはDKIM
と同じくなりすまし防止ですが、方法が異なります。
こちらはDNS
にIP
アドレスを書き込み、その値と送信側のIP
を比較します。
カスタム Mail Fromドメインの有効化を行います。 https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/mail-from.html
自分が参考にした元記事(以下)に倣い、bounce
というサブドメインを用います。
https://dev.classmethod.jp/articles/setting-up-aws-ses-with-aws-cli-1/
aws ses set-identity-mail-from-domain \
--identity $domain \
--mail-from-domain bounce.$domain
②や③の時と同様にレコードの登録を行います。
参考:https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/send-email-authentication-spf.html
今回は以下のように設定します。
Name | Type | Value |
---|---|---|
bounce.<YOURVERIFICATIONDOMAIN> | MX | 10 feedback-smtp.us-east-1.amazonses.com |
bounce.<YOURVERIFICATIONDOMAIN> | TXT | "v=spf1 include:amazonses.com ~all" |
今回は2レコードなので、2件作成します。
種別がMX
とTXT
と異なっている点に注意してください。
{
"Comment": "Add MX Record",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "bounce.<Domain>.",
"Type": "MX",
"TTL": 300,
"ResourceRecords": [
{
"Value": "10 feedback-smtp.us-east-1.amazonses.com"
}
]
}
}
]
}
{
"Comment": "Add TXT Record to use SPF",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "bounce.<Domain>.",
"Type": "TXT",
"TTL": 300,
"ResourceRecords": [
{
"Value": "\"v=spf1 include:amazonses.com ~all\""
}
]
}
}
]
}
以下コマンドで登録します。
aws route53 change-resource-record-sets \
--hosted-zone-id $hostedZoneId \
--change-batch file://record-mx.json
aws route53 change-resource-record-sets \
--hosted-zone-id $hostedZoneId \
--change-batch file://record-txt2.json
これまでと同様に一定期間待った後で、確認コマンドがSuccess
を返せばOKです。
aws ses get-identity-mail-from-domain-attributes \
--identities $domain \
--query 'MailFromDomainAttributes.*.MailFromDomainStatus'
最後に実際にメールが送信できるか確認します。
なおSES
はデフォルトではサンドボックスの状態です。
この状態だと送信回数や送信先に制限があります。
送信先を事前に登録する必要があるので、まずはそこから行いましょう。
なお、以降は送信先を$toAddress
とします。
export toAddress=<自分が保有しているメールアドレス>
下記コマンドで送信先の検証を行います。
aws ses verify-email-identity \
--email-address $toAddress
しばらく待つと送信先のメールアドレスに確認メールが届くので、その中の認証リンクを踏みます。
その上で以下の確認コマンドがSuccess
を返せばOKです。
aws ses get-identity-verification-attributes \
--identities $toAddress \
--query 'VerificationAttributes.*.VerificationStatus'
いよいよ送信の検証を行います。
取得したドメインを用いた任意のFrom
アドレスから、先ほど検証完了した送信先アドレスへメールを投げます。
aws ses send-email \
--from test@$domain \
--to $toAddress \
--subject "Subject Test" \
--text "Body Test"
これで入力した内容の通りにメールが届けば完了です。
今回はRoute53
でドメインを取得し、SES
を用いてメールを送信するところまでの手順をまとめました。
コンソール上でやると簡単ですがCLI
ベースだとパラメータの渡し方などでちょっと苦労するなぁというのが通しでやってみての感想です。
本来はここから、サンドボックスの解除などをした上で使っていくかと思います。 要望がありましたらその内容も記事にしたいと思います。
今回の内容が役立ちましたら幸いです。