メールのなりすまし防止について(2014-09-09。更新:2017-03-21(図の追加))
そもそも、迷惑メールって †
簡単に作れます。
少し調べるだけで誰でも、好き放題なりすましメールを作れます*1
何らかの悪意のあるメールを送るとき(スパム*2、ウィルス、フィッシングetc...)
メールは届けば良いので(返信は期待していない)、
むしろなりすましメールで送った方が都合が良いです。
メールを受け取る側としては、
ウィルス対策ソフトである程度は防げるかもしれませんが、
このままでは正体不明 or 詐称したメールを
無尽蔵に受け取る羽目になりかねません。
それをメールサーバ間の認証で未然に防ぐ機能はないのか、
イメージ的には、偽物の手紙を送っても、
相手に届く前に郵便局で破棄してもらうので自宅には届かない、
というのが今回の話です。
補足:
これらを難しい言葉で言うと、
メール送受信者(OutlookやThunderdirdなどのメールソフト)はMUA(Mail User Agent)、
郵便局にあたるメールサーバをMTA(Mail Transfer Agent)と呼びます。
今回はすべてMTAの機能です。
検証の仕組み †
ここから先は DNS やSMTPの仕組みを知らないとついていけないかもしれません。。
SPF(Sender Policy Framework) †
メール送信元のドメインが詐称されていないか確認する仕組みです。
メールを受信したタイミングで DNSサーバに、
ドメイン名とIPアドレスが一致する(=詐称されていない)か問い合わせます。
以下(試験勉強用に)処理の流れをメモします。
- 送信元メールサーバは、あらかじめ自分のドメインを管理するDNSサーバ上に「SPFレコード」を設定する。
example.jp. IN TXT "v=spf1 ip4:192.0.2.1 -all"
または
example.jp. IN SPF "v=spf1 ip4:192.0.2.1 -all"
⇒訳:example.jpからのメールはIPアドレス192.0.2.1からのみ、送信される
⇒ip4 に加えて、ipv6 も必要に応じて設定しましょう。
- 送信元メールサーバが、送信先メールサーバへメールを送る。
- 送信先メールサーバで、ドメインの検証をする。
- SMTPの「MAIL FROM」コマンドで与えられたドメインについて、
DNSサーバへ、前述のSPFレコードを問合せる
- DNSサーバからの応答SPFレコード上のIPアドレスが、
送信元IPアドレスと一致していればOK。しなければ破棄する
いや、破棄するかはメールサーバの設定次第ですね。
(後述の SenderID や DKIM も同様)
なお、
通常はメールヘッダに認証結果が記載されています。
「Received-SPF: Pass (sender SPF authorized)」(=SPF検証に合格しました)とか。
メールヘッダの内容は、メールソフトの
「メールのプロパティ」等から見ることができます。
これらの情報は迷惑メール対策ソフトの判定に役立ちます。
なお、対策ソフトの実装例としては、
私の場合 SpamAssasin という対策ソフト を使いました。
Sender ID †
仕組みは前述の SPF と同じです。
ただし、確認する範囲が広い。
SPFが「MAIL FROM(エンベロープ)」の検証であるのに対して、
こちらはメールヘッダ(≒メールの中身の内容まで)を検証します。
- Resent-sender:
- Resent-from:
- Sender:
- From:
SPFは"v=spf1"、Sender IDが"v=spf2.0/pra" になります。
DKIM(ディーキム。DomainKeys Identified Mail) †
電子署名を用いることで、メール自体の正当性を確認する仕組です。
送信前にメールに署名して、
受信側でその署名が正しいものか検証します。
制約としてメーリングリスト等には使えません。
メーリングリストは「件名欄(Subject)」が自動的に書き換わってしまうのですが、
署名というのは「メール全体(件名欄含む)」の改竄を検証するからです。
以下で(試験勉強用に)処理の流れをメモします。
- 送信元メールサーバは、あらかじめ自分のドメインを管理するDNSサーバ上に
「DKIMに使う公開鍵」、「ADSPレコード」を設定する。
(ADSP:Author Domain Signing Practice。電子署名をどう扱うかの指示。)
DNSサーバへの記述例は以下。
セレクタ._domainkey.example.jp. IN TXT "v=DKIM1; k=rsa; p=公開鍵のデータ"
_adsp._domainkey.example.jp. IN TXT "dkim=discardable"
一行目は、送信する時はこのセレクタ&鍵の組み合わせを使うという宣言。
二行目は、example.jpから送信されたメールは、
もし正しい電子署名が得られないならば破棄(discardable)してくれという宣言。
他にも dkim=unknown などがあり、署名の扱いを指示する。
- 送信元メールサーバーが、メールに「DKIM-Signature」というヘッダーを追加する。
メール本文から秘密鍵で生成したデジタル署名などを付与している。
DKIM-Signature: v=1; a=rsa-sha256; d=example.jp;
s=セレクタ。DNSに公開鍵を取得するときに使う;
bh=メール本文のハッシュ値;
h=To:Sender:MIME-Version:Subject:From:Content-Type:
Content-Transfer-Encoding:Message-Id:Date;
b=電子署名データ
- 受信メールサーバは、DKIM-Signatureを検証する。
- 上記でいうd(ドメイン名)、s(セレクタ)でDNSサーバから公開鍵を取得する
- 取得した公開鍵でハッシュ値を取り出す
- 取り出したハッシュ値と、受信メールのハッシュ値が等しいか確認する
- また、DKIMの認証結果をどのように扱うべきか(ADSP)もDNSサーバから取得する。
- 確認結果をメールに追加する。例えば合格(pass)ならこんな風に。
Authentication-Results: (中略)dkim=pass (ok);
長い、わかりづらい、ごめんなさい。
・・・え~、秘密鍵や公開鍵の話は 公開鍵暗号 を参照。
セレクタや公開鍵の実装方法の具体例は、opendkimのインストール をご覧ください。
DMARC(Domain-based Message Authentication, Reporting, and Conformance) †
SPFとDKIMの両仕様に基づいて認証する方式です。
(詳細は dmarc.org を参照。英語ですが、OverViewにイメージ図があります。)
DNSサーバへの記述例は以下。
_dmarc.example.jp TXT "v=DMARC1; p=reject; pct=100; rua=mailto:postmaster@example.jp"
この例だと、DMRC1に基づいて(v=DMARC1)、
フィルタ率100%、つまり全メールを対象に(pct=100)、
認証失敗時は受信拒否してもらうように指示する(p=reject)。
そして、通常は一日一回のペースで、postmaster@ example.jp へ認証結果の統計を送信してくれ(rua)
という内容になります。
(rua 以外にもruf*3 とか、sp、adkim、aspf とタグは色々ありますが割愛するとして)
ポイントは最後の、「rua=mailto~」 で受信者からの情報を受け取ることで、
送信者 example.jp が、状況を把握し改善策を講じることができる点でしょうか。
例えば、受け取った情報から自分のドメインが拒否されてまくっていることを知って驚愕したり、
(たぶん、その場合は自分のドメインがスパムに利用されまくっているんでしょうね・・・)
それを踏まえてポリシーを p=reject からnone(なにもしない。ruaで統計だけ送信してもらう)に変更したり対策検討したり、とか。
情報の収集と改善のサイクルでより効果的な迷惑メール対策を行えます。
問題点 †
これらの各機能は送受信双方のメールサーバがこの機能に対応していないと使えないため、
特にDKIMは殆ど普及していないのが現状です。
また、迷惑メール送信者が自前のDNSサーバを用意した場合も検証結果は「OK」になるので、
これだけですべての迷惑メールを防げる訳でもありません。
対策の一例として、
JIPDEC(日本情報経済社会推進協会)がDKIMを利用したサービスを使っているのですが
(Google:JIPDEC 安心マーク)。
JIPDECで管理されている組織*4からくるメールについては「安心マーク」が表示されるとのこと。
つまり、「DKIM 認証 + JIPDEC の管理情報」という2つの条件の合わせ技で検証しています。
※ただし、安心マークに対応しているのは一部のWebメールのみです。
なお、総務省が出した統計 によると、
2016年 6月 現在でSPFの普及率が9割弱、DKIM認証の普及率が4割くらいみたいです。
メールサーバ/DNS自作するなら、SPFくらいはつけておいた方が良いかも?
今後はDKIMももっと流行ってくるのかもしれませんね。