何もかもわからない人間によるAmazon SESメールのドメイン認証学習記録

## 経緯
シャチョー「うちのドメイン使ってメール送信したいからSES使って」
ぼく「はい」
シャチョー「Googleの規制強くなるっぽいからSPFとDKIM認証してDMARCもやっといて」
ぼく「何語やねん（はい）」

## 目標
・なんとな～～～く使ってきたメールの仕組みや設定について1割くらいは理解したい
・メールの認証？っぽいのがこの世には存在するらしいのでそれも調べてみる

## はじめに
今回の記事では沢山の記事を参考にさせていただきました。
その中で用いられている図も参考に引用させて頂いております。
もし何か問題等ございましたらご一報ください…

## メールってなんだ（哲学）
そもそもメールってひとことで表現しているけど、ドブエンジニアの僕にはSMTPサーバーから送られる？みたいなふわっと知識しかない。
たしかに迷惑メールに振り分けとかされているのを見ると何かしら「健全なメール」か「怪しいメール」みたいな判断基準がありそう。

このメール（概念）をより具体化していきたいと思う。

## メールが送信される仕組み
https://www.kagoya.jp/howto/it-glossary/mail/mailserver/

https://blastmail.jp/blog/mail-delivery/send-and-receive-mail

とりあえず図を追って流れを確認してみよう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/93b3106e-6c3f-fc18-5444-dc1ba447c01c.png)

この図でいくと
1.私が何かしらのアプリからメール送信ボタンをポチっとすると自社のSMTPサーバーにメールが送られる
2.自社SMTPサーバーがDNSサーバーに問い合わせをする。ん？
3.相手先のSMTPサーバーにメールが送られる
4.POPでメールをダウンロードするかIMAPでサーバー上のメールを読みにいくなどをする

らしい。DNSサーバーに問い合わせをするってなんだろう？

>user001@cd835.co.jpにメールを送ると、「cd835.co.jp」の住所情報を管理しているDNSサーバーに問い合わせ、ドメインに紐づいているメールサーバー情報（IPアドレス）を取得します。

なるほど、ドメイン（@以降の文字列）がどこのIP（住所）かわからないと相手のメールサーバーに届かないもんな。
で、**このDNSサーバーって何者？どこにいて誰が立てて運用してるの？**

https://www.gmo.jp/security/brandsecurity/dns/blog/dns-server/

https://ryonotes.com/where-is-route-dns-server/

https://www.ntt.com/bizon/glossary/e-d/dns-server.html

どうやらDNSサーバーは**この世に沢山存在していて皆で協力プレイをしているらしい**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/55e702e9-318d-582a-855d-62ccecff8978.png)

今回ドメインはValuedomainで取得したんだけど、じゃあそのドメインの情報はValuedomainに入るって感じなのかな？ジピえも〜ん教えて！

```:chatGPT
そうだね！ ValueDomainのようなドメイン登録サービスを使ってドメインを取得した場合、
そのサービスの提供するDNSサーバーにドメインの情報が登録されるんだ。

具体的な流れはこんな感じだよ：

1.ドメインの登録: まず、ValueDomainでドメインを登録すると、
　その情報はインターネットの全体的なDNSレコードに追加されるんだ。
2.DNSレコードの設定: ドメインに関連する各種レコード（A、MX、CNAMEなど）を
　ValueDomainのDNS管理ツールを通じて設定するよ。
　これにより、ドメイン名にアクセスした際にどのサーバーにルーティングするかが決まるね。
3.権威DNSサーバー: ValueDomainが提供するDNSサーバーは「権威DNSサーバー」として機能する。
　つまり、あなたのドメインに関する正式な情報を保持しているということだ。
4.DNSクエリの処理: インターネット上のユーザーやサーバーがあなたのドメイン名をクエリすると、
　最終的にはValueDomainのDNSサーバーに到達して、そこから必要な情報を得ることになるんだ。
5.キャッシュ: DNS情報は各所の再帰的DNSサーバーにキャッシュされるため、全てのクエリが
　毎回ValueDomainのサーバーに到達するわけではないよ。
　一度キャッシュされれば、その情報はTTL（Time To Live）が切れるまで再帰的DNSサーバーに保持されるんだ。
```
見た事ない単語がいくつかあるけど後で登場すると見越して一旦無視しよう。
とりあえずさっきの図の権威DNSサーバーに該当すると考えて良いかな！
（この記事は間違ってたらスミマセンの情報が跋扈するので本当にスミマセン）

これで相手のSMTPサーバーの居場所がわかってメール送信して届けられるね。メール送信の流れは一旦OK。

## レッツSES！
もうメールについて完全に理解したのでSESで登録してみよう！
![スクリーンショット 0006-02-07 18.38.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/4e279cd6-a0f3-c389-4fe3-6b7400fb2106.png)




![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/8270b61b-1f90-6c9e-8292-b7d24c2f40cc.png)

## SPF！DKIM！DMARC！
馬鹿か俺は…メールの流れがわかったところで肝心の「メールの中身」は何もわかってないんだ…
「送信元メールアドレスの正当性検証」がどう行われているかについて調べよう。

https://miraitranslate-tech.hatenablog.jp/entry/aws-ses-sender-domain-authentication

SMTPの要素についての説明があった。
![スクリーンショット 0006-02-07 18.46.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/0fee0a70-38fb-0f3c-2c46-f2961811a8f1.png)

・Envelope：送信元と送信先の情報を持っている。
・Header：送信元とか書いてあるけど別に嘘でもいい（よくない）
・Body：本文

メールを郵便に例えると、**封筒がEnvelope、中の手紙がHeader**とよく表現されている。

https://baremail.jp/blog/2021/05/25/1377/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/44f66677-784c-60ec-66d7-356001d391b2.png)

なるほどね。つまり封筒の中の手紙で「**あなたは一兆円当選しました！ロト6より**」って書いてあっても封筒の差出人に「**全日本詐欺協会**」って書いてある感じか。

でもこれ、全日本詐欺協会の人がロト6って書いて手紙送っちゃう（=EnvelopeFromを偽装する）と本当か嘘かわからないのでは？
というのを**SPF**とかで認証するらしい。ふむ

## SPF
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/0775bd20-9c07-71aa-7efa-a0973c19e476.png)
なるほどつまり、ロト6の社員と証明できない黒フード被った不審者が送信したものは弾いて、事前に社員登録してあるロト6社員（IP）からは通すってことか！この例えは本当に合ってるのか？

で、そのEnvelopeFromのドメインとIPをSPFレコードとしてDNSサーバーに事前に登録すると。
なるほどわからん。

### どうやって登録するの？
https://qiita.com/K5K/items/dad9119d448d4d969fae

https://tech.nri-net.com/entry/setting_up_dkim_spf_dmarc_amazon_ses_route_53

えっ！？ドメインのネームサーバーにRoute53を使っていたら勝手にやってくれるんですか！？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/53f0abdf-d0cc-94cd-efbc-feb0db9a1157.png)

これで登録するとRoute53で

![スクリーンショット 2024-02-07 194421.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/6ec0c645-83b4-e32a-39ec-c69eb8db7bea.png)
こんな感じで入る。おお～
…あれ？IPと紐づけるって話はどこにいったんだ？と思ったけど、今までの参考画像は送信メールサーバーを自社で持ってるとかそういう話なのかな。
今回SESを使うのでメールサーバーはamazonのIPになって、それはamazonses.comのSPFレコードに含まれているからinclude:amazonses.comって書き方でOKらしい…？あっなんかふわっと理解になったけど仕方ない！次いこう！

## DKIM
SESの設定画面をちょっとスクロールしたらドメインの検証って項目がありまして

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/4ee85b14-4ccc-6d0c-2d12-71fb84b0201e.png)

OKOK、意味わかんないから順を追っていくぜ

https://miraitranslate-tech.hatenablog.jp/entry/aws-ses-sender-domain-authentication

(この記事先ほども紹介したのですが本当にわかりやすかったです…圧倒的感謝…！)

>DKIM (DomainKeys Identified Mail)は、メールの内容に対する電子署名をメールヘッダに付与して、メールの内容になりすましや改ざんがないかどうかを検知します。この電子署名を検証するための公開鍵を、HeaderFromドメインのサブドメインとしてDNSで公開します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/54b8937e-cb99-1bc8-42f2-133c02ab9110.png)

お？なんか文章も心なしか理解できるようになってきたぞ？
さっきEasyDKIMとBYODKIMって2つ選択があったけど、後者は自分で鍵用意するってことらしい。Bring Your Own DKIMだって。opensslとかで作るのかな？今回はEasyでいいや。

https://docs.aws.amazon.com/ses/latest/dg/creating-identities.html#verify-domain-procedure

そしてさっきのSES「ドメインの検証」画像の下にあったけど、ここでもRoute53への発行を自動で行ってくれるらしい！うっひょ～！

Route53を確認してみる

![スクリーンショット 2024-02-07 200900.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/93d936d9-1377-a687-2f17-f2fd92b275ed.png)

レコード名が「~~~~._domainkey.kaisyano_domain.jp」、タイプがCNAME、ルーティング先が「~~~~.dkim.amazonses.com」のものが登録されている。
うん、CNAMEってなんだ？

https://wa3.i-3-i.info/word12290.html

https://powerdmarc.com/ja/what-is-a-dns-cname-record/

 「キャノニカルネームレコード」らしい。別名付ける的なイメージでいいかな…
 で、さっきのレコードを見ると_domainkeyと.dkimの後ろにトークンが付けられてる。
 SESを使ってメールを送信する時、自動的にメールにDKIM署名が追加されるらしい。この署名はSESが保持している秘密鍵を使って生成されるとのこと。
 で、受信したサーバーが_domainkey.kaisyano_domain.jpのCNAMEレコードを通して公開鍵にアクセスして、DKIM署名を検証する、という流れ。
さっきのトークンは公開鍵にアクセスするための識別子ってところらしい。うん、ふしぎ文字ってことか。

## MXレコード
ところで見逃してたけど、こいつ何者なんだ？
![スクリーンショット 2024-02-07 202707.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/78df5f7c-a14a-620c-73cf-1ba945610d05.png)

MX…東京メトロポリタン？

https://am.arara.com/blog/026

MXレコードにはメール送信先の住所が書いてあるらしい。いや、自分から見たら「自分宛のメールはこのサーバーに届けてね」っていう受信用の設定って考えたほうがわかりやすいかな。
mail.kaisyano_domain.jpにメールを送ったら東京リージョンのSMTPに届けてね、的な。
小学校の頃皆で遊ぶ時「じゃあ吉野公園集合な！」とは言ってたけど、「じゃあ神奈川県横浜市○○区○○の○○公園集合な！」とは言わないからね。ちなみに吉野公園はすぐ隣に吉野君が住んでいたので友達間でそう呼ばれていたのと、多分この例は間違っています。

## DMARC
さあ最後にDMARCだ。SESでEnvelopeFrom設定する時にこっそり書いてあったね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/f46592a6-9c58-775d-fad0-e39c8d1614d4.png)
（カスタムMAILFROMドメインがEnvelopeFromを指している…はず…）

AWS使ってていつも思うんだけど、この説明で理解するのは無理では？いや略語広げて説明しました感出されても…ってなりません？
いや、きっと公式のリファレンスには丁寧な解説があるに違いない。ちゃんと公式も読んでみよう。

https://docs.aws.amazon.com/ja_jp/ses/latest/dg/send-email-authentication-dmarc.html
>DMARC (Domain-based Message Authentication, Reporting and Conformance) は、SPF (Sender Policy Framework) およびドメインキーアイデンティファイドメール (DKIM) を使用してメールスプーフィングを検出するためのメール認証プロトコルです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/34ebf535-2f1d-9d0f-f1c4-8989f860e476.png)


はい

https://www.nic.ad.jp/ja/basics/terms/dmarc.html

https://frauddetection.cacco.co.jp/media/knowhow/8609/

DMARCは「SPFとDKIMの認証に失敗したとき、受信側がそのメールをどう処理するかを指示したポリシー」で、例えば認証失敗したら「none（そのまま受信するよう指示する）」「quarantine（隔離するように指示する）」「reject（受信を拒否するよう指示する）」の3パターンを指示できるみたい。

うーん？
これって「受信者側が拒否するかどうか選べる」わけじゃなくて「送信者側が受信者に拒否させるか受け入れさせるか選べる」ってことだよね。
じゃあ悪意ある送信者は絶対noneに設定するんじゃないの？なんかあんまり存在意義がわからないな…
という訳で先生、教えてください。
```:chatGPT
none、quarantine、reject の選択肢があることについての疑問は理解できるよ。
実際、悪意のある送信者が自分のメールでDMARCを使用する場合、
noneを選択することで、SPFやDKIMの検証に失敗してもメールが受信されるようにすることができる。
しかし、DMARCの真の価値は、正当なドメイン所有者が
自分のドメインからのメール送信を保護するために使う点にあるんだ。
```
ほう
```:chatGPT
ここで重要なのは、DMARCはドメインの所有者が自分のドメインから送信されるメールに対する
ポリシーを公開することを可能にするということだよ。
つまり、正当なドメイン所有者は、自分のドメインからのメールがSPFとDKIMの両方、
またはいずれかの検証に合格することを期待している。
DMARCレコードにrejectやquarantineを設定することで、
他人がそのドメインを偽装してスパムやフィッシングメールを送ることを防ぐことができるんだ。

たとえば、rejectポリシーを公開することによって、ドメインの所有者は
「このドメインからのメールがSPFやDKIMの検証に合格しない場合は、それを拒否してください」
と受信側に伝えている。
これにより、そのドメインの評判を保ち、不正なメールが届かないようにすることができるんだ。
```
なるほどなるほど
```:chatGPT
DMARCをnoneで使用する理由は、通常、ドメイン所有者がDMARCを導入し始めたばかりで、
どのようなメールが失敗しているかを監視し、調整を行うためだよ。
これは実質的なリスク軽減策ではなく、主に情報収集のために使用される。
時間をかけて、ドメイン所有者はDMARCポリシーをquarantineやrejectに移行していくことが
一般的だね。
```
つまり、なりすましメールとかを受信者に届けさせないようにするための仕組みってところで、やっぱりnoneじゃなくて最終的にはrejectとかにする必要があるってことか。納得しました。

閑話休題
さっそくSESでDMARCの設定をしてみよう。TXTレコードの追加で設定するみたい。
```
名前: _dmarc.kaisyano_domain.jp
タイプ: TXT
値: "v=DMARC1; p=none; pct=100; rua=mailto:postmaster@kaisyano_domain.jp"
```
各パラメータを見ていこう。
v=DMARC1：このレコードがDMARCレコードだよって示す呪文。DMARCのバージョン番号らしい
p=none：これがquarantineとかrejectとか設定するところ。
pct=100：このポリシーを適用する割合。
rua：レポートを受け取るメールアドレス。

割合って全部100でいいじゃん…と思ったそこの僕！

https://powerdmarc.com/ja/what-is-the-dmarc-pct-tag/

>pctタグは、オンラインビジネスでの展開期間を短縮するために、DMARCポリシーを徐々に適用する方法として設計されました。その意図は、以下のケースのように、メールストリーム全体に完全に導入する前に、まず少量のメールバッチに導入できるようにすることです。 
v=DMARC1; p=reject; pct=50; rua=mailto:rua@example.com。
このDMARCのDNSレコードでは、DMARCの拒否ポリシーはメールの50％のみに適用され、残りの半分のボリュームには、2番目に厳しいポリシーであるDMARCの検疫ポリシー(quarantine)が適用されます。 

いきなり全部に適用させると大変なことになるかもしれないから段階を踏んで適用させたい時に使うんだね。賢いなぁ

あとruaの設定でレポートってのが貰えるらしいけど、どんな感じなのかしら？

https://baremail.jp/blog/2023/11/28/3595/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/82f5f199-34a3-bf23-ba36-de23beb8f861.png)

グロッ
あ、でもxmlか…上の参考サイトにも書いてあるけど、ちゃんとわかりやすく可視化してくれるサービスもあるみたい。

## ちょっと理解できた気がする
実際のSESの画面やレコードを見ながら、そして数多の参考サイトを読み解いていった結果、ちょびっとだけメールについて詳しくなれた気がした。
というか、レコードって色々設定できるんだ。すっげー便利だなーって思いました（ドブ）

 ## 余談
 この際なのでジピえもんにレコードの種類を聞いてみよう。なんかよく使われるレコードタイプ教えてくれ～！
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505768/e3e9bf21-08d9-0326-2ca2-892e2f4e0468.png)

今日もお世話になりました。おつかれ！