はじめに
この記事では、メール送信サーバーを設定時に、ほぼ必ず設定することになるSPF、DKIM、DMARCについて、知識の整理と共有のために概要や効果、設定方法を紹介します。
SPF
SPFは、Sender Policy Frameworkの略で、ドメインの所有者が「自分のドメインから送信を許可するメールサーバー(IPアドレスやホスト名)」をDNSに公開する仕組みです。
2006年にRFC4408で定義され、RFC7208で最新版が定義されています。
SPFの効果
SPFの仕組みを使うことで、以下の効果が得られます。
- 送信ドメインの正当性を受信側が検証できる
- 攻撃者が特定のドメインを偽装して送ったメールを、受信者のサーバにブロック/減点評価させることができる
- 送信元は自分が正しい送信元であることを証明することができ、受信側での検証をパスしやすくなり、メールの到達率が向上する
これらにより、送信側としては自社の「なりすまし(スプーフィング)」をした攻撃者のメールの到達率を減らすことができ、受信側は「迷惑メール」判定をしやすくなります。
システムの提供側からすると、結果的に、自社のユーザーがなりすましの被害に遭いにくくなり、また、自社のサービスのメールが迷惑メールとして判定されにくくなります。
SPFレコードの設定
SPFレコードは、DNSのTXTレコードとして以下のような文法で指定します。
v=spf1 <Qualifier1><Mechanism1>: 値 <Qualifier2><Mechanism2>: 値
| SPF構成要素 | 内容 |
|---|---|
| v=spf1 | バージョン識別子 |
| Qualifier |
|
| Mechanism |
|
設定例:
[ドメイン名] IN TXT ( "v=spf1 ip4:203.0.113.5/32 include:_spf.google.com -all" )
上記の例では、サーバーのIP (203.0.113.5/32)と Google Workspace 経由のみ許可(+を省略して設定)し、それ以外は拒否しています。
なお、同じドメイン名に対して、複数のTXTレコードを登録することは、SPFレコードの検証時にPermErrorが発生する仕様になっており、迷惑メール扱いになる可能性があります。
SPFを使った検証の流れ
SPFを使った受信側の検証は、以下のような流れで行われます。
- 送信ドメインの取得\
受信側 は SMTP セッションの
MAIL FROM/HELOなどからドメイン名を取得 - DNS へ SPF 問い合わせ\ そのドメインの TXT レコードを検索するため、DNS へクエリを送信
- SPF レコード取得\
DNS が返した
v=spf1 …レコード(または CNAME 追跡先のレコード)を受け取る - 評価して結果を反映\ 実際の送信 IP とSPFレコード内容を照合し、Pass/Fail などの判定
SendGridのAutomated Securityを利用する場合
システムからのメール送信でよく利用されるSendGridでは、Automated Securityという機能により、SPFレコードの登録を簡略化することができます。SPFレコードの設定では、同じ送信ドメインに対して複数レコードを登録するよくある間違いがあるため、そういった間違いを防ぐのが目的なのではないかと思われます。
Automated Securityを使う場合、ユーザーは以下のように自社のDNSにサブドメインのCNAMEレコードを登録します。
em123.example.com IN CNAME u123456.em123.sendgrid.net.
SendGrid側のDNSで、このu123456.em123.sendgrid.net に対して、適切なTXTレコードが登録されているため、SendGridのユーザーはCNAMEレコードの登録だけでSPFレコードの登録ができます。
SPF単体利用の弱点
SPFは、前述のフローでも記載したとおり、MAIL FROM / HELO などからドメイン名を取得するため、ヘッダーFromの詐称に対応できず、また、送信元が正しいかどうかだけしか判断しないため、内容の改ざんが行われているかは評価できません。
また、メールを転送してしまうと、転送サーバーがSPFレコードに定義されていないため、個人が転送した正当なメールやメーリングリストからの配信がFailする場合があります。
それらの問題を解決するために、SPFだけでなく、DKIMとDMARCが併せて使われます。
DKIM
DKIMは、DomainKeys Identified Mailの略で、公開鍵暗号方式を使ってメールの内容が送信元以外に改ざんされていないことを保証するための仕組みです。RFC6376で定義されています。
DKIMの効果
DKIMの仕組みを使うことで以下の効果を得ることが出来ます。
- 改ざん防止
- ヘッダーや本文が送信元以外の通信途中で変更されていないことを証明
これらにより、SPFの弱点であった部分を補完することができ、システムやサービスの提供元から送られたメールが、受信側で適切に判定されるようになります。
その結果として、システムやサービスの利用ユーザーが第三者の改ざんによる攻撃をうけたとしても迷惑メールとして判定しやすくなり、提供元から送信されたメールは正しくユーザーに届くようになります。
DKIMレコードの設定
DKIMは、DNSのTXTレコードとして以下のような文法で指定します。主要な部分だけ説明します。
[セレクタ名]._domainkey.[ドメイン名] IN TXT ( "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFA..." )
| DKIM構成要素 | 内容 |
|---|---|
| [セレクタ名] |
|
| [ドメイン名] | メール送信に使うドメイン |
| v=DKIM1 | バージョン識別子 |
| k=rsa | 鍵の種別。現在はrsaのみ。 |
| p | Base64でエンコードした公開鍵本体 |
DKIM-Signatureヘッダー例:
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=s1; c=relaxed/relaxed; q=dns/txt; t=1713900000; h=from:subject:date:to:mime-version; bh=PZC9zB...=; b=QfN18lz...=
DKIM-Signatureに含まれる主なタグの内容は以下の表の通りです。
| タグ | 内容 |
|---|---|
| d | 署名者ドメイン |
| s | セレクタ名 |
| h | 署名をしたヘッダーの一覧 |
| bh | 本文ハッシュ |
| b | 実際の署名値 |
DKIMを使った検証の流れ
DKIMを使った検証は以下のような流れで行われます。
- 送信時
- 送信元が選択したヘッダー・本文をハッシュ化
- 送信ドメインの秘密鍵で署名
- 署名結果を
DKIM-Signature:ヘッダーとして追加
- 受信時
- 受信側 が
DKIM-Signature:ヘッダーから セレクタ名 (s) とドメイン名 (d) を取得 [セレクタ名]._domainkey.[ドメイン名]の TXT レコードを DNS で取得
- 受信側 が
- 検証
- 公開鍵で署名を検証し、Pass / Fail / TempError / PermError を判定
SendGridのAutomated Securityを利用する場合
SendGridでは、SPFと同様に、Automated Securityという機能によって、CNAMEを使ったDKIMの設定をすることができます。
仕組みはSPFと同様で、以下のようなCNAMEレコードを自社のDNSに登録すると、SendGrid側で登録されているDKIM用のTXTレコードを参照させることができます。おそらく、これもSendGridユーザーが誤登録をするのを防ぐための機能と思われます。
s1._domainkey.example.com IN CNAME s1.domainkey.u123456.wl123.sendgrid.net.
DKIM単体利用の弱点
仮にDKIMだけを使って迷惑メールかどうかを評価をすると以下の問題が発生します。
- 改ざんされたメールでDKIMでPassしてしまう
- 送信されたメールを攻撃者が改ざんし、さらに、改ざん時に攻撃者が管理するドメインの署名を付けることで、DKIM-Signatureには、
d=attacker.comのようなタグで署名がつけられる。このとき、攻撃者がattacker.comのDNSに公開鍵を登録しておけば、改ざんされたメールのDKIM認証がPassし、迷惑メールと判定されずユーザーに到達してしまう
- 送信されたメールを攻撃者が改ざんし、さらに、改ざん時に攻撃者が管理するドメインの署名を付けることで、DKIM-Signatureには、
- メーリングリストなどでの転送時に、DKIMでPassしたメールがSPFでFailしてしまう
- メーリングリストで転送された場合など、内容が改ざんされていないことをDKIMで証明したとしても、SPFとDKIMのそれぞれで独立して評価を行うと、送信元が変わってしまったことでSPF判定がFailとなり、迷惑メールのように扱われてしまう
1つ目の問題の場合、改ざん時に送信元も差し替わっているはずなので、SPFの情報を併せて評価に使えれば、攻撃を検出しやすくなります。
2つ目の問題の場合、SPFでFailになった場合にDKIMの情報で補完すれば、攻撃による変更ではないことが評価可能です。
上記のような対応をするために、SPFとDKIMの情報を併せて評価するのがDMARCです。
DMARC
SPF、DKIMの判定結果を束ねて判断し、失敗時の処理とレポート方法をドメイン所有者側が宣言する仕組みです。RFC7489、RFC8616で仕様が定義されています。
DMARCの効果
前述のSPF、DKIMをそれぞれ単体で判定に使った場合と比べて、DMARCを使うことで以下の効果を得られます。
- 途中で内容が改ざんされ、しかし、DKIM単体ではPassしている場合でも、迷惑メールと判定することが可能
- メーリングリストで転送され、SPFがPassしない場合でもDKIMの情報に基づいて正しいメールと判定可能
- ユーザーへの影響を考慮しつつ少しずつ判定を強化していく運用が可能
DMARCレコードの設定
DMARCレコードは以下のようにTXTレコードをDNSに設定します。
_dmarc.[ドメイン名] IN TXT ( "v=DMARC1; p=quarantine; rua=mailto:dmarc@ops.example.jp; adkim=s; aspf=r; pct=100" )
| DMARC構成要素 | 内容 |
|---|---|
| v=DMARC1 | バージョン識別子 |
| p | ポリシー:none / quarantine / rejectの3つを指定可能。Passしない場合の挙動を定義する。 noneは、何もしない。quarantineは、SPAMとして隔離する。rejectは、SMTPレベルで拒否する。 |
| rua | 集計レポート送信先(複数可) |
| ruf | 詳細レポート送信先(任意項目) |
| adkim | DKIM Alignment:r=relaxed / s=strictrは、DKIMのdがメールFromのドメインのサブドメインであってもAlignment判定をPassさせることができる。sは、メールFromのドメインとDKIMのdが厳密に一致したときのみにAlignment判定をPassさせることができる。rでもsでもDKIMがPassしていること(=内容が改ざんされていないこと)が前提。 |
| aspf | SPF Alignment:r / sDKIMと同様。 |
| pct | pで指定したポリシーを全体どのくらいの割合に適用するかを定義。 この指定により、一部の受信者のみに少しずつポリシーを適用うる運用が可能になる。 |
| sp | サブドメイン用ポリシー。(省略時は、サブドメインでもpと同じ) |
adkimとaspfのAlignmentとは、文字通り「調整」の意味です。SPF、DKIMをどのような判定方法で強調動作に使うか、その調整方法を定義します。
DMARCを使った検証の流れ
- メール受信
- SPF と DKIM をまず評価
- Alignment 判定
- SPF Pass かつ SPF ドメイン≒From ドメインならSPF Alignment判定をPass
- DKIM Pass かつ 署名ドメイン≒From ドメインならDKIM Alignment判定をPass
- aとbのどちらかのAlignment判定をPassすればDMARCをPassと判定
- ポリシー適用 (
p=)- DMARC Fail なら
none / quarantine / rejectの指示に従う
- DMARC Fail なら
- レポート送信
- 集計レポート(RUA)
- 詳細レポート(RUF)
検証例:
以下のようなケースで、DMARCの検証がどのようになるかをまとめます。
- 途中で改ざん(DKIM単体はPass)
- 途中で内容が改ざんされ、しかし、改ざん者によるDKIM署名の公開により、DKIM単体ではPassしている場合
- 途中で転送(SPF単体はFail)
- メーリングリストで転送され、SPFがPassしない場合
上記のケースがDMARCの判定ではどうなるかをまとめると次の表のようになります。
攻撃者に途中で改ざんされた場合がFailになり、攻撃ではない転送がPassになるのが確認できます。
| ケース | SPF | SPF Alignment | DKIM | DKIM Alignment | DMARC |
|---|---|---|---|---|---|
| 途中で改ざん | Fail | Fail | Pass | Fail |
Fail |
| 途中で転送 | Fail | Fail | Pass | Pass | Pass |
DMARCポリシー運用のベストプラクティス
DMARCのポリシーは、たとえば、何の検証も行わずにすべてrejectにしてしまうと、予期しない悪影響が発生してしまいます。
その状況を緩和し、運用を少しずつ厳格化していくために、以下のような導入ステップが一般的にベストプラクティスとされています。
- SPF / DKIM を 設定する
_dmarcにp=none+rua=で 観測開始- レポートで Fail 要因を潰し、
pct=を使って一部トラフィックのみをquarantineへ変更して影響を確認 - 問題がなくなったら
p=reject+pct=100で 本格運用
DMARCでも防げない問題
DMARCを使ったとしても、たとえば、メーリングリストが転送時に本文やヘッダーの一部分に(悪意のない)転送時の軽微な情報の追加を行う場合は、DKIMの署名が無効化されて改ざん扱いになってしまい、DMARCにおけるDKIM AlignmentもPassしなくなってしまいます。
このようなケースでは、ARC (Authenticated Received Chain) を ML サーバーが付与するなどの方法がとられますが、この記事ではその詳細の説明を省略することにします。
本サイトの更新情報は、Xの株式会社プレセナ・ストラテジック・パートナーズエンジニア公式で発信しています。ご確認ください。