【メール入門 第5回】送信ドメイン認証 前編 ― なりすましの手口とSPF・DKIM・DMARCの仕組み

メールサーバー
スポンサーリンク
スポンサーリンク

「社長の名前で『至急振り込んで』というメールが届きました。差出人のアドレスは、うちのドメインなんです」

こんな相談を受けたことはありませんか。メールの差出人は、送信者が自由に書けるものです。自社のドメインを名乗るメールが、自社から来たとは限りません。

それを確かめるのが送信ドメイン認証(SPF・DKIM・DMARC)です。第5回(前編)では、なりすましの手口と3つの仕組みの基本を、第6回(後編)では、レポート、転送の問題、導入の手順といった運用を扱います。


なりすましメールの仕組み

SMTPには、送信者を確かめる仕組みがもともとありません。エンベロープFrom(MAIL FROM)もFromヘッダーも、送信者が自由に書けます(第3回)。利用者が目にするのはヘッダーFromと表示名で、エンベロープFromは普段は見えません。

エンベロープFromがbounce@attacker.example.net、ヘッダーFromが代表取締役 山田 ceo@example.jpのメールが受信者の画面では表示名だけ見えることと、主な手口4つ(①ヘッダーFromを詐称、②封筒は自分のドメインで便箋だけ詐称、③似たドメイン、④表示名だけ偽装)のうちSPF・DKIM・DMARCで防げるのは①②で、③④は注意の表示や別の手段での確認が要ることを示す図

主な手口は次の4つです。

  1. ヘッダーFromを詐称:ceo@example.jp をそのまま書く
  2. 封筒は自分のドメイン:エンベロープFromは自分のドメインにしてSPFを通し、ヘッダーFromだけ正規のドメインにする
  3. 似たドメイン:example-jp.com のようなドメインから送る
  4. 表示名だけ偽装:表示名を「代表取締役 山田」とし、アドレスは攻撃者のフリーメールにする

送信ドメイン認証で防げるのは1と2だけです。3と4には、外部からのメールへの注意の表示や、送金の依頼を別の手段で確かめる運用を組み合わせます。

ポイント
認証が守るのはドメイン名。人が読む表示名までは守らない。


SPFの仕組みと評価の流れ

SPF(RFC 7208)は、ドメインの管理者が「このドメインのメールを送ってよいサーバーのIPアドレス」をDNSのTXTで宣言し、受信側が接続元のIPと照らし合わせる仕組みです。

送信側MTA 203.0.113.25がMAIL FROM:bounce@example.jpで接続し、受信側MXがexample.jpのTXTを引いてv=spf1のレコードを左から照合し、最初に一致したip4で pass が確定することと、結果がpass・fail・softfail・neutral・none・permerror・temperrorの7種類であること、便箋のFromは見ないことを示す図
  1. MAIL FROMのエンベロープFromのドメインのTXTを引く
  2. v=spf1のレコードの機構を左から評価する
  3. 最初に一致した機構の限定子で結果(pass・fail・softfailなど7種類)を決める

重要なのは、SPFが見るのはエンベロープFromで、利用者が目にするヘッダーFromではない点です。攻撃者が自分のドメインをエンベロープFromにすればSPFはpassするため、SPFだけではなりすましを防げません。ヘッダーFromとの一致は、この後のDMARCで確かめます。また、IPで判断するため転送に弱いです(第6回)。


SPFの書き方と制限

example.jp. 3600 IN TXT "v=spf1 ip4:203.0.113.25 ip6:2001:db8::25 include:spf.protection.outlook.com include:_spf.saas.example.net ~all"
$ dig +short TXT example.jp | grep spf1
PS> (Resolve-DnsName example.jp -Type TXT).Strings | Select-String 'v=spf1'
  • 限定子:+(省略時)pass、- fail、~ softfail、? neutral。最後のallは「それまでに一致しなかったすべて」
  • SPFのレコードは1つの名前に1つ(連載「DNS入門」第6回)。2つあるとpermerrorになる。ptrは非推奨

DNSを引く回数は10回まで

SPFでつまずきやすいのが、この制限です。

v=spf1のレコードで、ip4とallは数えず、mx・include・aとinclude先の中のincludeを1回ずつ数えると、使っていないincludeを含めて合計11回になりpermerrorになることを示す図
  • DNSを引く機構(include・a・mx・ptr・exists・redirect)は合計10回まで。include先の中の参照も数え、超えるとpermerror(SPFが無いのと同じ扱い)になる。SaaSを足し続けると超えやすい
  • void lookup(答えが空やNXDOMAINになる参照)は2回まで(RFC 7208の推奨)。使わなくなったサービスのincludeを残さない

~all か -all か

DMARCを使うなら~allが無難です。-allだと、DKIMでDMARCに合格できたメールまで、SMTPの段階でSPFのfailだけを理由に拒否されうるからです(RFC 9989)。一方、メールを送らないドメインはv=spf1 -allにします。


DKIMの署名と検証の流れ

DKIM(RFC 6376)は、送信側がメールに電子署名を付け、受信側がDNSの公開鍵で検証する仕組みです(電子署名は連載「証明書入門」第2回)。

送信側MTAが本文のハッシュ(bh=)とヘッダーに秘密鍵で署名(b=)してDKIM-Signatureを付け、受信側MTAがd=とs=からs202609._domainkey.example.jpのTXTの公開鍵を引いて検証することと、転送で内容がそのままならDKIMはpass、メーリングリストが件名に(ML)を足すとfailになることを示す図
  • 送信側は、①本文のハッシュを計算し、②From・Subjectなど選んだヘッダーと①を合わせて秘密鍵で署名し、③DKIM-Signatureヘッダーとして付ける
  • 受信側は、④署名のd=(ドメイン)とs=(セレクター)からセレクター._domainkey.ドメインのTXTを引いて公開鍵を得て、⑤署名を検証する

成功すれば、d=のドメインが責任を持つメールで、途中で書き換えられていないと分かります。

IPに依存しないため、転送されても内容が同じなら成功するのがSPFとの違いです。一方、メーリングリストが件名や本文を書き換えると署名は壊れます(第6回)。なお、DKIMもd=とヘッダーFromの一致は見ません。


DKIM-Signatureと鍵の運用

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.jp; s=s202609;
  t=1790380800; h=from:from:to:subject:date:message-id:list-unsubscribe:list-unsubscribe-post;
  bh=(本文のハッシュ、省略); b=(署名、省略)
$ dig +short TXT s202609._domainkey.example.jp
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..." "...IDAQAB"
PS> (Resolve-DnsName s202609._domainkey.example.jp -Type TXT).Strings -join ''
  • 主なタグ:d= 署名したドメイン、s= セレクター、h= 署名したヘッダー、bh= 本文のハッシュ、b= 署名、c= 正規化(relaxedは空白の違いなどを許す)、t= 署名した時刻
  • h=にfromを2回書く(オーバーサイン)と、Fromヘッダーを後から足す改ざんを防げる。l=(署名する本文の長さ)は、後ろに本文を足されるので使わない
  • 鍵:RSAは2048ビット(1024ビットは最低限。SHA-1は禁止、RFC 8301)。Ed25519(RFC 8463)は短く速いが、検証できない受信側もあるため、RSAと2つ署名する
  • 鍵の更新はセレクターを変えて行う:新しい鍵を別のセレクターでDNSに載せる → 署名を切り替える → 古い鍵は数日〜数週間後に消す。M3AAWGは少なくとも半年ごとの更新を推奨。Microsoft 365やSESはCNAMEで事業者に向け、更新を任せられる(連載「DNS入門」第6回)

DMARCの仕組みとアラインメント

SPFもDKIMも、利用者が目にするヘッダーFromとは結び付いていませんでした。それを結び付けるのがDMARC(RFC 9989)です。

自社のサーバーから送ったメールはSPFのsmtp.mailfrom=mail.example.jpとDKIMのd=example.jpがヘッダーFrom ceo@example.jpと一致してDMARC pass、SaaSから設定なしで送ったメールはSPF・DKIMともsaas.example.netでpassしても不一致でDMARC failになることを示す図

受信側は_dmarcのTXTを引き、次のどちらかを満たせばpassとします。

  1. SPFがpassし、エンベロープFromがヘッダーFromと一致する
  2. DKIMがpassし、そのd=がヘッダーFromと一致する

これをアラインメントと呼びます。既定のrelaxedは組織ドメインが同じなら一致(mail.example.jp と example.jp)、strictは完全な一致です。満たさなければfailです。

ここで注意したいのがSaaSです。事業者のドメインでSPF・DKIMがpassしても、DMARCはpassしません。自社ドメインでDKIM署名させるか、エンベロープFromを自社のサブドメインにします。

ポイント
SPFかDKIMが「passかつFromと一致」ならDMARCはpass。SaaSには自社ドメインのDKIM署名かMAIL FROMの設定が要る。

SaaSを自社ドメインとして合格させる設定の例

; DKIM:SaaS に自社ドメイン(d=example.jp)で署名させる。公開鍵は CNAME で事業者に向ける
s1._domainkey.example.jp.  3600 IN CNAME  s1.dkim.saas.example.net.
; SPF:エンベロープ From(MAIL FROM)を自社のサブドメインにし、そこで SaaS の IP を許可する
bounce.example.jp.         3600 IN MX 10  feedback.saas.example.net.
bounce.example.jp.         3600 IN TXT    "v=spf1 include:_spf.saas.example.net ~all"
  • 名前や値は事業者ごとに違うので、管理画面の指示どおりに登録する。上は形の例
  • DKIMを設定すれば、転送にも強いDKIMでDMARCに合格できる。どちらか1つならDKIMを優先する
  • エンベロープFromをサブドメイン(bounce.example.jp)にしても、relaxedなら組織ドメインが同じなので一致する

3つの仕組みを比べる

SPFDKIMDMARC
確かめるもの送信 IP が許可されているか署名が正しく、途中で書き換えられていないかSPF・DKIM で認証されたドメインとヘッダー From の一致
見るドメインエンベロープ From(MAIL FROM)署名の d=ヘッダー From
DNS に置くものドメインの TXT(v=spf1)セレクター._domainkey の TXT(公開鍵)_dmarc の TXT
転送されると壊れる(IP が変わる)内容が同じなら残るDKIM が残れば pass
メーリングリストでは壊れる件名・本文の変更で壊れるfail になりやすい
単独での限界ヘッダー From を見ないヘッダー From を見ないSPF か DKIM の合格が前提

SPFとDKIMは「認証されたドメイン」を作り、DMARCはそれが「利用者の見るFromと同じか」を確かめる、という役割分担です。3つそろって、はじめてヘッダーFromの詐称を防げます。


DMARCのタグとポリシー

タグ意味値・既定
v版(先頭に置く)DMARC1(必須)
p失敗したメールの扱いの希望none(監視のみ)・quarantine(隔離)・reject(拒否)。省略時は none
sp存在するサブドメインのポリシー省略時は p と同じ
np存在しないサブドメインのポリシー省略時は sp、それも無ければ p
adkim・aspfDKIM・SPF のアラインメントr(relaxed、既定)・s(strict)
rua・ruf集計レポート・失敗レポートの送り先mailto: の URI(第6回)
tテストモードy なら1段階弱めて適用。既定は n
psd・fo公開サフィックスの宣言・失敗レポートの条件一般のドメインでは通常使わない
_dmarc.example.jp. 3600 IN TXT "v=DMARC1; p=reject; sp=reject; np=reject; rua=mailto:dmarc-rua@example.jp"
PS> Resolve-DnsName _dmarc.example.jp -Type TXT
  • ポリシーは受信側への「希望」で、最終的な扱いは受信側が決める。quarantineは迷惑メールフォルダーへ入れる扱いが一般的
  • ruaの送り先が別のドメイン(集計サービス等)なら、送り先のドメインに許可のレコード(example.jp._report._dmarc.example.net)が必要(RFC 9990)

いきなりp=rejectにするのは危険です。安全に進める手順は、第6回で扱います。


考えてみよう

  1. 自社ドメインのSPFレコードは、DNSを何回引いていますか。include先の中まで数えると、10回に収まっていますか。使っていないサービスのincludeは残っていませんか。
  2. 自社で使っているSaaS(メール配信、CRM、ヘルプデスクなど)から送るメールは、SPFとDKIMのどちらで、自社ドメインとして合格していますか。
  3. 冒頭の「社長の名前の振込依頼」が、似たドメインや表示名だけの偽装だった場合、DMARCをp=rejectにしていても防げません。どんな対策を組み合わせますか。

ヒント:この記事の「DNSを引く回数」の図、アラインメントの図、なりすましの4つの手口が手がかりです。レコードはdig +short TXT example.jpやResolve-DnsNameで確かめられます(第9回)。


まとめ

  • エンベロープFromもヘッダーFromも送信者が自由に書ける。認証で防げるのは正規ドメインの詐称だけ
  • SPFは送信IPの宣言。見るのはエンベロープFrom。DNSの参照は10回まで
  • DKIMは電子署名。転送に強く、書き換えに弱い。鍵は2048ビット、セレクターで更新
  • DMARCは、SPF・DKIMの結果とヘッダーFromの一致(アラインメント)を見る
  • SaaSには自社ドメインのDKIM署名かMAIL FROMの設定が要る

次回(後編)は、RFC 9989で変わったこと、集計レポートの読み方、転送とメーリングリストの問題、BIMI、そしてp=noneからp=rejectへの段階的な導入を扱います。


連載「メール入門」全12回

  1. メールが届くまで
  2. SMTPのやり取り
  3. メッセージの構造
  4. ポートと暗号化・認証
  5. 送信ドメイン認証 前編(この記事)
  6. 送信ドメイン認証 後編
  7. 迷惑メール対策と配信
  8. MTAの運用
  9. コマンドで調べる
  10. クラウドと現代のメール
  11. メールのトラブルシュート
  12. メールの設計演習

コメント

タイトルとURLをコピーしました