見出し画像

【初級エンジニア向け】メールソースの読み方・SPF/DKIM/DMARC確認方法

こんにちは。PIVOTのエンジニア、金杉です。
前回の「メールが届かない!? 迷惑メールフォルダに入ってしまう!?…差出人設定に要注意!」に引き続き、メールのお話です。今回は初級エンジニア向けに、メールソースの読み方、SPF/DKIM/DMARCの確認方法について記載します。

メールのソースを理解できると、テキストメールに見えるけど実はHTMLメールで表示文字とは異なる不正サイトへのリンクが仕込んである、なんてことが見抜けるようになります。
SPF/DKIM/DMARCの設定方法はほかによいサイトがたくさんあるので、ここでは記載しません。ググってくださいね。
長文のうえ、エンジニア以外の方にはわかりづらいかもしれませんが、ご一読いただけると嬉しいです。


メールのソースを表示する

代表的なOutlookとGmailですが、Outlookはブラウザではメールヘッダしか確認できず、メールソース全文は確認できません。Outlookアプリでは、以下の手順でメールのソースを確認できます。

Outlook アプリケーション (Microsoft Outlook for Mac ver.16.56の場合)
メールの一覧から対象メールを右クリックし、下の方にある「ソースの表示」をクリック

Gmail (PCブラウザ)
メールを開いて右上の「…」(三点は縦表示)をクリック
「メッセージのソースを表示」


メールのソースを理解する

紙のメール(はがきや手紙)と同じように、電子メールも、宛先などが記載されている部分(ヘッダ)と、本文(ボディ)に分かれます。
HTMLソースを読める方は、<head>ブロック、<body>ブロックを思い浮かべてください。

電子メールはインターネット初期からの技術で、ざっくりいうとテキスト形式、しかもASCII文字(英数半角+一部記号)のみで書かれています。
改行区切りで、ヘッダとボディの分かれ目は、最初の空行です。
規約をちゃんと理解したい方は、RFC5322を読んでください。

英数半角文字だけで、日本語のメールが届いたりファイル添付できるのはなぜなのか、それはこの記事を読んでいくとわかります。


① ヘッダの解読

ヘッダは、最初の空行まで、以下の順序で構成されています。
ヘッダを作成するときの各行の順序は規定されていませんが、サーバを経由するときに元の順序を変えてはいけないので、大枠は決まっています。

【メールサーバが追加するtrace情報】
Recievedなど、経由するメールサーバが追加していく情報。
SPFやDKIM、DMARCもここで確認しています。
Fromなどの上に、経由するサーバごとに追加されていきます。

【宛先や件名などのメール本文情報】
From(差出人)、To(宛先)、Subject(件名)など、メールの送信時に
作成される情報。
メールごとに一意となるMessage-IDは、送る側のサーバが作成します。

【オプション情報】
Content-Type(形式)もオプション情報です。
Gmailはオプション情報が少なくContent-Typeくらいでヘッダが終わりますが、Outlookは「X-*」という独自の情報をずらずら〜っと追加していて、
メール本文情報のブロックが真ん中となり、見つけづらいです。


大枠について理解されたところで、ヘッダでの日本語の扱いを見てみましょう。Gmail(PCブラウザ)は、ソースを表示するときにデコードされるので、ある意味では親切ですが(解析したいときに不便…)、Outlookではそのまま表示されるので、なんかよくわからない「=?」「?=」で囲まれた英数半角文字になっています。

これは、日本語を扱うためにMIME形式でエンコードされています。
「=?」「?=」で囲まれた部分を、「=?」部分を含めてコピーし、MIMEデコードのサイトを探してデコードしてみてください。日本語に変換されます。
「MIME形式である」という情報もヘッダの1行として「MIME-Version: 1.0」と書かれます。


② ボディの解読

ボディは、まずテキスト形式か、マルチパート形式かを判定します。
ヘッダの「Content-Type」に書かれています。

【テキスト形式】
例1) Content-Type: text/plain; charset="iso-2022-jp"
例2) Content-Type: text/plain; charset=utf-8

charsetに、文字コードが記載されます。
たいてい「iso-2022-jp」か「utf-8」です。前回の「メールが届かない!? 迷惑メールフォルダに入ってしまう!?…差出人設定に要注意!」で文字コードを決めると記載しているのは、ここを決めるためです。

また、テキスト形式を解読するには、ヘッダの「Content-Transfer-Encoding」も必要です。
charsetとContent-Transfer-Encodingにより、ボディ部の日本語がエンコードされ、英数半角文字に変換されて送受信されています。
Webのデコードサービスでボディ部のソースを日本語にデコードする場合は、「Content-Transfer-Encoding」の方で検索すると見つかります

【HTML形式】
例) Content-Type: text/html; charset="utf-8"

テキスト形式と同様で、ヘッダの「Content-Transfer-Encoding」も必要です。HTMLメールに対応していないメーラでは、ソースがそのまま表示されるか、表示できません。

【マルチパート形式】
例) Content-Type: multipart/alternative;
              boundary="----=_Part_122747418_1581565200.1625785821471"

boundaryに、区切り行の文字列が書かれます。
区切り行で区切られた内容がまた、空行区切りでヘッダとフッタに分かれ、ヘッダ部に「Content-Type」「Content-Transfer-Encoding」などが書かれます。

HTML形式のメールに対応していないメーラのためにテキスト形式をつけたり、添付ファイルがある場合は、このマルチパート形式が使われます。
添付ファイル1つずつが、マルチパートの1パートになります。

メールのソースの読み方がわかったところで、いよいよドメイン認証の仕組みを見ていきます!


送信ドメイン認証 SPF (Sender Policy Framework)

いちばんコストのかからない、必須設定というべきものがSPFレコードです。下記のサイトで「pivot.jp」を検索してみてください。https://www.cman.jp/network/support/nslookup.html
ホスト名(FQDN) : pivot.jp
オプション(任意) : TXT :テキスト情報
「nslookup実行」

ごちゃごちゃ結果が出ますが、注目すべきはココ↓

pivot.jp text = "v=spf1 +ip4:54.248.109.19 +ip4:211.9.57.242 +ip4:52.196.248.203 +ip4:39.110.205.198 +ip4:203.135.195.80 +ip4:164.70.0.166 +ip4:52.68.94.140 include:_spf.google.com include:spf.protection.outlook.com include:_spf.bownow.jp ~all"

これが、2021/12/20現在のpivot.jpのSPFレコードです。
Webサイトでの検索でしたが、このサイトで実行して表示される内容は、
みなさんのPCに入っているコマンド「nslookup」または「dig」でも、同じ内容です。(変更直後は、ネットワーク間の反映の時間差で異なるときもあります)

ヘッダの解読でも書きましたが、メールのヘッダには、どのサーバを経由して送られたか、経路がすべて書かれています。
送る側がつなぐ最初のメールサーバ(Fromなどのすぐ上のReceivedに記載)がこのSPFレコードに宣言されていれば、受け取り側のメールサーバがチェックし、送信ドメイン認証をおこないます。

SPFレコードの" "内を読み解いていきましょう。

v=spf1
SPFレコード宣言(textレコードはSPF以外も設定できる)

ip4:54.248.109.19 +ip4:211.9.57.242 +ip4:52.196.248.203 +ip4:39.110.205.198 +ip4:203.135.195.80 +ip4:164.70.0.166 +ip4:52.68.94.140

オフィスのサーバやクラウドのサーバのIPアドレス。IPv6も同様。

include:_spf.google.com
GmailのSPFサーバ (※)

include:spf.protection.outlook.com
OutlookのSPFサーバ (※)

include:_spf.bownow.jp
メルマガサービスのSPFサーバ (※)

~all
これらすべての送信を許可

(※) 世界中にメールサーバがあるようなサービスは、SPFサーバをいくつか
経由して再帰的にincludeします。

新規に構築したサーバからメール送信するときや、メルマガの差出人を変更するときは、この設定を確認しましょう。
変更するときに設定を間違えると、いままで問題がなかったサーバからの
送信も迷惑メールになってしまうかもしれないので、注意して作業しましょう。


送信ドメイン認証 DKIM (DomainKeys Identified Mail) - 電子署名

電子署名は、DKIMというしくみを使います。
前々回の記事 HTTPSって結局なんなの? と似ていて、鍵を使います。
SPFと同じようにDNSを用いますが、SPFより少し複雑です。

メールヘッダの「DKIM-Signature」に電子署名が記載されています。

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=azgjp.onmicrosoft.com; s=selector2-azgjp-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=WgToJvdHzqbhRGsE3egGl74K9KEajQUMmZo8R68KhaA=; b=EITsxdri4b0j+SWsCuQMVvaFlzz3WNei0c3sS6xyKFkjmeFzJJS1bbNweZh5WfGTPMohs5h5S4zWA1OAE2PkDmB0vJrlFTnYmvDDu+gzBVjEiTaQiAnVLleZ7JAj098E8aKkug7X5yEzmrIJs6CYa9XCaUJkMZbe3PKIUw5i3fY=

電子署名は、送る側のメールサーバが、ヘッダに記載されている情報や本文の一部などを使ってハッシュを作成し、鍵をかけて付加します。
ハッシュの作成には、メールヘッダや本文の一部が含まれていることを覚えていてください。

この電子署名が正しいか、DNSのDKIMレコードに記載されている公開鍵を使って確認します。
今度は、以下の情報で検索してください。

https://www.cman.jp/network/support/nslookup.html
ホスト名(FQDN) : selector2-azgjp-onmicrosoft-com._domainkey.azgjp.onmicrosoft.com
※太字部分は、メールヘッダDKIM-Signatureのsとdから取得
オプション(任意) : TXT :テキスト情報
「nslookup実行」

selector2-azgjp-onmicrosoft-com._domainkey.azgjp.onmicrosoft.com text = "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIbLXoN2lBxOmUVHwnvc9ypMojo6yiU0I4TjB5csvq6Ly+/sqiSlDb+eKSIoK5AboQlwWw3+0Fz4zIImlWAFP3zNe4yrHFbS6XpcYrPzmImp2q9yxmLSBlbtrsjhRevYltchubX/+phX8vtLFW8kOfhU5riCTP9qg3AZmhK86kswIDAQAB;"

DKIMレコードの" "内を読み解きます。

v=DKIM1
DKIMレコード宣言(DKIM1 固定です)

k=rsa
電子署名の作成に利用できる鍵の形式、DKIMではRSAのみ

p=…
公開鍵データ

さて、メールを検証する準備ができました。受け取り側は
(1) DNSから取得した公開鍵で、電子署名からハッシュを取り出します。
(2)メールヘッダの「DKIM-Signature」の「h=」部分に記載されている内容をメールから取り出し、送り側と同じようにハッシュを作成します。
(3) (1)と(2)が一致すればPASS

送り側がつけた電子署名のハッシュも、受け取り側で作成するハッシュも、メールヘッダや本文の一部を含むため、一致しなければ、経路のどこかで本文などが改ざんされたことになります。

DKIMで利用できるタグは、一般財団法人インターネット協会の技術解説が詳しいです。


DMARC(Domain-based Message Authentication, Reporting, and Conformance)

最後に、送信ドメイン認証に失敗したときメールをどうするか、受け取り側のサーバに指示する設定DMARCについて見ていきます。
DMARCは弊社では設定していないため、google.comの設定をお借りしましょう。
下記のサイトで「_dmarc.google.com」を検索します。https://www.cman.jp/network/support/nslookup.html
ホスト名(FQDN) : _dmarc.google.com
オプション(任意) : TXT :テキスト情報
「nslookup実行」

_dmarc.google.com text = "v=DMARC1; p=reject; rua=mailto:mailauth-reports@google.com"

DMARCレコードの" "内を読み解きます。

v=DMARC1
DMARCレコード宣言(DMARC1固定です)

p=reject
none(なにもしない) / quarantine(隔離) / reject(拒否)
google.comさんは、拒否するよう指示しています。これにより、100%認証に成功したメールのみが受信トレイに到達し、それ以外はその場で削除されます。

rua=mailto:mailauth-reports@google.com
DMARCの「集計レポート」の送信先の指定です。

DMARCの設定については、SendGridさんのDMARCとは?がわかりやすかったです。


まとめ

初級エンジニア向けと題しましたが、ご理解いただけましたでしょうか。
いまご理解いただけなくとも、実際にメールサーバを構築するときなど、
そういえばなんかごちゃごちゃPIVOTのnoteで説明してる人がいたなーと思い出して参考にしていただければ幸いです。


この記事が気に入ったらサポートをしてみませんか?