Closed17

DMARK レポートを自分で読んでみる

tmd45tmd45

用語

MTA

参考: https://baremail.jp/blog/2021/11/30/1746/

  • MTAとは「Mail Transfer Agent」の頭文字を取ったもので「メール転送エージェント」を意味する
  • MTAはメールサーバー内で動くソフトウェアのうちの一つで、メールの送受信において中心的な役割を担っている
  • エージェント
    • メールが届く仕組みを解説する上で「エージェント」という言葉がよく登場する
    • メールエージェントとは、メール送受信におけるそれぞれの機能を担うソフトウェア(プログラム)のこと
      • MUA(Mail User Agent):メールの確認や作成を行うユーザインタフェース
      • MTA(Mail Transfer Agent):メールの転送
      • MDA(Mail Delivery Agent):メールの配送(仕分け)

SPF

利用するドメインの TXT レコードに、送信元として許可するドメインを記述する。

SPFに対応したメール受信サーバは、 メールの受信時にそのメールの送信元となっているドメインのSPFレコードを、 DNSで問い合わせます。 送信元のサーバがSPFレコード中で許可されていない場合は、 送信ドメインの詐称が行われたと判断して、 受信を拒否するなどの処理を行います。
https://www.nic.ad.jp/ja/basics/terms/

SPFの例
example.com
v=spf1 include:hoge.mailsender.com include:fuga.transmail.net ~all

DKIM

サービス側で指定されたセレクター(サブドメインみたいな形のもの)に、公開鍵を含む TXT レコードを作成する。
{サービスが指定した値}._domainkey.example.com の形式。

DKIMは電子署名を利用し、 その電子署名の検証に必要となる公開鍵は送信元ドメインのDNSサーバで公開されます。 受信者は受け取ったメール中の署名者に関する情報からドメインを特定し、 そのDNSサーバへ問い合わせることで公開鍵を取得します。
https://www.nic.ad.jp/ja/basics/terms/

DKIMの例
abcdefghi._domainkey.example.com
v=DKIM1; k=rsa; p={公開鍵1}

1234567890123._domainkey.example.com
k=rsa; p={公開鍵2}

DMARC

SPF, DKIM での判定結果をもとにメールをどう処理させるかをメール送信者があらかじめ宣言しておく仕組み。
メール送信元になるドメイン _dmarc.example.com の TXT レコードとして作成する。

SPFおよびDKIMを用いて送信元ドメインを認証する際、 認証に失敗したメールをどのように取り扱うかは、受信者の判断に任せられています。(中略)DMARCでは、認証失敗時にどのようにメールを処理すればよいかを、 送信者が受信者に対してポリシーと呼ばれるレコードをDNS上で公開することで表明する仕組みになっています。 受信者は認証に失敗した場合に送信者のポリシーを参照し、 それに基づいてメールをどのように取り扱うかを決定します。
https://www.nic.ad.jp/ja/basics/terms/

DMARC の例
_dmarc.example.com
v=DMARC1; p=none; rua=mailto:superuser@example.com
tmd45tmd45

DMARC レコード(設定)の書き方は省略。今回の本題は DMARC レポートの読み方。
手元に DMARC レポート(xml)が添付されたレポートメールが届いたよ!ってところから。

tmd45tmd45

dmarc-report-converter の利用

https://github.com/tierpod/dmarc-report-converter

手元環境(Intel コア MacBook Pro, macOS 14.3.x)ではビルド済みのパッケージは上手く動作しなかった。

zsh: exec format error

ので、golang を使ってビルドするところからやった。

build
$ git clone https://github.com/tierpod/dmarc-report-converter.git
$ cd dmarc-report-converter
$ make release

input, output フォルダを作成して config ファイルに指定

config
$ cp config/config.dist.yaml config/config.yaml
vi config/config.yaml
config/config.yaml
--- config/config.dist.yaml     2024-02-15 19:01:50
+++ config/config.yaml  2024-02-15 19:06:33
@@ -1,6 +1,6 @@
 input:
   delete: no
-  dir: "/tmp/dmarc_files/"
+  dir: "../dmarc_files/input"
   #imap:
   #  server: ""
   #  username: ""
@@ -14,7 +14,7 @@
 output:
   # output file
   # should be: string, golang template string or "stdout"
-  file: "/tmp/html/{{ .ID }}.html"
+  file: "../dmarc_files/output/{{ .ID }}.html"
   # file: "/tmp/html/{{ .ReportMetadata.Email }}/{{ .PolicyPublished.Domain }}!{{.ReportMetadata.DateRange.Begin}}!{{ .ReportMetadata.ReportID }}.html"

   # output format

実行してみる。
ファイル名にドメインとかいろいろ見えちゃってるので適宜中略。

$ ./bin/dmarc-report-converter -config ./config/config.yaml
[INFO] files: found 32 input files in ../dmarc_files/input
[INFO] ReadParseZIP: read file ....xml from zip
[INFO] ReadParseZIP: read file ....xml from zip
[INFO] merge: 9 report(s), grouped by key '...'
[INFO] merge: 13 report(s), grouped by key '...'
[INFO] output: write to file ../dmarc_files/output/YYYY-MM-DD-domain/....html
[INFO] output: write to file ../dmarc_files/output/YYYY-MM-DD-domain/....html

output フォルダに HTML 化されたレポートが出力されているので読む。

tmd45tmd45

DMARC レポート(xml)の内容

RFC 7489 - Domain-based Message Authentication, Reporting, and Conformance (DMARC)
→ Appendix C. DMARC XML Schema

大事な「結果」は record > row の中の以下の項目に入っている。

  • policy_evaluated : DMARC ポリシーに則った結果[1] 受信サーバーで最終的にどう判断されたか
  • auth_results : SPF / DKIM の認証結果がどうだったのか
<?xml version="1.0" ?>
<feedback>
  <version>0.1</version>

  <report_metadata>
    <org_name>レポーターの名前</org_name>
    <email>レポーターのメールアドレス</email>
    <report_id>レポートID</report_id>
    <date_range>
      <begin>集計期間の開始日時(UNIXTIME)</begin>
      <end>集計期間の終了日時(UNIXTIME)</end>
    </date_range>
    <extra_contact_info />
    <error />
  </report_metadata>

  <policy_published>
    <!-- DNS で公開した DMARC レコードの仕様。ちゃんと認識されているかが分かる -->
    <domain>example.com</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>none</p>
    <sp>none</sp>
    <pct>100</pct>
  </policy_published>

  <record>
    <row>
      <source_ip>(レポーターに受信されたメールの)送信元IPアドレス</source_ip>
      <count>集計期間内に送信された回数</count>

      <policy_evaluated>
        <!-- DMARC のチェック結果(SPF アラインメントと DKIM アラインメントの合否結果)。必須 -->
        <disposition>DMARC レコードの p と sp で指定された DMARC ポリシーアクション(none / quarantine / reject)</disposition>
        <dkim>DKIM 認証& DKIM アラインメントの結果(pass / fail)</dkim>
        <spf>SPF 認証& SPF アラインメントの結果(pass / fail)</spf>
        <reason />
      </policy_evaluated>
    </row>

    <identifiers>
      <envelope_to />
      <envelope_from>エンベロープの From 値(ドメイン)。必須</envelope_from>
      <header_from>ヘールヘッダーの From 値(ドメイン)。必須</header_from>
    </identifiers>

    <auth_results>
      <!-- 認証結果(SPF認証とDKIM認証の合否結果)の詳細 -->
      <dkim>
        <!-- DKIM 認証の結果 -->
        <domain>DKIM 認証を行ったドメイン。必須</domain>
        <serector />
        <result>DKIM 認証の結果(none / pass / fail / policy / neutral / temperror / permerror)。必須</result>
        <human_result />
      </dkim>
      <spf>
        <!-- SPF 認証の結果 -->
        <domain>SPF 認証を行ったドメイン。必須</domain>
        <scope>SPF 認証を行ったドメインのスコープ(helo / mfrom)。必須</scope>
        <result>SPF 認証の結果(none / neutral / pass / fail / softfail / temperror "unknown" / permerror "error")。必須</result>
      </spf>
    </auth_results>
  </record>

  <!-- 以下同様に複数のレポート(レコード)が含まれる -->
  <record />
  <record />
</feedback>
脚注
  1. DMARC ポリシーに従うかどうかは受信サーバー次第なので、則ってるかどうかは不明 ↩︎

tmd45tmd45

レポートファイルの見方はわかった。

が、例えば auth_results で pass なのに policy_evaluated では fail になってたり、softfail って何なのよとか、実際の値がどういう意味でそうなっているのかが全然分からない🤔

tmd45tmd45

DMARC レポートの読み方を調べようとしても、上記のとおりの xml の定義止まりで、値の意味まで書かれていない。
あるいは DMARC の設定方法、解析サービスの情報ばかり出てきてしまう🤔

tmd45tmd45

アライメント(Alignment)とは、メールに表示される送信元メールアドレス(ヘッダfrom)が、SPFやDKIMで認証したドメインと一致するか照合することを指します。

SPFとDKIMのどちらかが認証とアライメントをPass(合格)できていれば、もう一方は未導入あるいはFail(失敗)となっていてもDMARC認証にPassすることができます。ただし注意しなくてはならないのは、SPFとDKIMの認証がどちらも合格していたとしても、アライメントが両方とも合格できなかった場合DMARCの認証としてはFailとなってしまうということです。

tmd45tmd45

「エンベロープFrom」と「ヘッダFrom」の違いとは? - ベアメールブログ

  • エンベロープFrom(Return-Path) : 封筒に書かれた送信元。SMTP(配達員)はこちらを見る
  • ヘッダFrom : 便箋に書かれた差出人。メールの仕様上は送信者が自由に記載できる

この2つが存在していることで

  • メリット : BCC が使える。転送や代理送信など、柔軟なメール配信が可能になる
  • デメリット : なりすましが行われる
tmd45tmd45

結局 RFC 読むのだ〜

認証結果の読み方

DKIM 認証の結果

Results 説明
none メッセージは署名されていない
pass メッセージは署名されており、ADMD[1] に承認され、署名検証に合格した
fail メッセージは署名されており、ADMD に承認されたが、署名検証に失敗した
policy メッセージは署名されているが、署名または署名の一部が ADMD に承認されなかった
neutral メッセージは署名されているが、その署名に構文エラーがあるかその他の理由で処理できなかった。この結果は他のエラーに該当しない「その他のエラー」としても使われる
temperror 公開鍵が一時的に取得できないなど、一過性と思われる何らかのエラーによりメッセージが検証できなかった。再試行すれば結果を得られるかもしれない
permerror 必須ヘッダーフィールドが存在しないなど、回復不可能なエラーのため、メッセー ジを検証できなかった。再試行しても結果を得られる可能性は低い

公開鍵が一時的に取得できないなど

公開鍵は DNS に置かれるため、以下の SPF の temperror と同じく DNS の一時的なエラーによるものが一般的なのだと思われる。

SPF 認証の結果

Results 説明
none 構文的に有効な DNS ドメインがない、または DNS に SPF レコードがない
neutral 明示的。ADMD は IPアドレスが許可されているかどうか断言しない
pass 明示的。クライアントは指定された ID でメール挿入する権限がある
fail 明示的。クライアントは指定された ID のドメインを使用する権限がない
softfail ADMD による弱い声明。このホストはおそらく許可されていない。"fail" になるような確定的なポリシーを公開していない
temperror SPF チェック中に一時的な(一般的には DNS の)エラーに遭遇した。再試行すれば DNS オペレータの介入なしに成功する可能性がある
permerror ドメインの公開レコードが正しく解釈できなかった。解決するためには DNS オペレータの介入が確実に必要
脚注
  1. Administrative Management Domain, 公的管理ドメイン。なにそれ ↩︎

tmd45tmd45

OpenAI に聞いた ADMD。分かるような分からないような…

ADMD(Administrative Management Domain)は、電子メールの分野で使用される用語です。ADMDは、電子メールシステム内での管理的な管理領域を指します。これは、電子メールメッセージの送信、受信、およびルーティングに関する管理上の機能を制御するためのドメインまたは領域を示しています。

ADMDは、メッセージがどのように処理され、送信されるかに関するポリシーや手順を定義します。異なるADMD間での相互運用性を確保するために、共通の標準やプロトコルが採用されることがあります。

一般的に、ADMDは電子メールのネットワーク内での管理的な制御に使用され、メッセージの信頼性、セキュリティ、および効率を確保するために重要な機能を果たします。

tmd45tmd45

dmarc-report-converter の出力結果は ヘッダFrom、エンベロップFrom の値が省略されてるのがちょっと不便かも。

各項目や値の意味がわかってきたら、XML で読んじゃったほうが早くね?って気持ちになるようなならないような。

このスクラップは2024/03/15にクローズされました