1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

初めに

2024年2月以降のGoogleの迷惑メール対策強化でDMARCの導入も進んでいます。
送信側の対応についての記事は良く見ますが、受信側についての情報が少ないのでまとめてみました。

前提

メールサーバーとして postfix を使っており openDMARC(Ver1.4.1) を当初導入しました。
その後、Rspamd(version 3.8.4)に変更してます。
その経緯についても説明します。
そもそも「DMARCとは何か」ということや、これらのインストールや設定は他の解説しているサイトを参照して下さい。

概要

送信ドメイン認証(SPF/DKIM/DMARC)の送信側は一生懸命対応しているようですが、それを見る受信側の対応については関心が薄いようです。
実際に受信したメールの解析を通じてDMARCの特性を理解していきたいと思います。
GmailやYahoo!MailのようなWEBメールでは参照が可能ですが、IMAPやPOPを使うメールソフト側の対応が出来ていません。
メールを読むユーザーがどのようにメリットを享受できるかが今後の課題です。

解析してみよう

ここではopenDKIM/openDMARCをpostfixに連携したもので見ています。
メールプロバイダの多くはDMARCに対応しているはずなので環境の無い方はそれらでも同様な情報が見られるはずです。
Gmailから受信した結果をメールのエンベロープで確認した例です。

dmarcサンプル.png

postfixで受信したメールはopenDKIM/openDMARCに連携され、検証された結果がヘッダーに追加されます。
spf=pass」「dkim=pass」「dmarc=pass」という情報が確認でき、それぞれに対応していることが解ります。
SPF/DKIM/DMARCで送信側から送られてきているのはDKIMの署名(Signature)だけです。
それ以外は対象ドメインのDNSの設定だけで行われている点に注目して下さい。

openDMARCは必要か?

上記の解析結果から言えるのは、送信側の対応だけならopenDMARCは不要ということです。
テスト方法は簡単でpostfixのopenDMARCへの連携(milter)を一時的に解除してあげれば良いだけです。
これで、Gmailに送信してみます。

ほら、ちゃんとDMARCはpassしてます。
DMARCの送信側は自身のDNSに登録し受信側の対応を指示するものなんですね。
DMARCの真価は受信側がどう情報を利用するかにあるようです。

さらなる解析

手身近なQiitaの例です

Authentication-Results: openDMARC; dmarc=fail (p=none dis=none) header.from=qiita.com
    Authentication-Results: openDMARC; spf=pass smtp.mailfrom=us-west-2.amazonses.com
DKIM-Filter: OpenDKIM Filter v2.11.0 ****.com CBF37180009
Authentication-Results: ****.com;
	dkim=pass (1024-bit key) header.d=qiita.com header.i=@qiita.com header.b="SnWcl7EQ";
	dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="TC/FQ5rd"

あれ!?dmarc=fail になっています。
spf=pass、dkim=pass です。
header.from ≠ smtp.mailfrom( qiita.com ≠ us-west-2.amazonses.com )
となっているからですかねえ?
いやいや、そうではないでしょう。
RFC7489によれば、

「複数のDKIM署名の1つでもイン・アライメントであると検証された場合には、DMARCの結果は「成功」とみなす。」

とあります。
「アラインメント」(調整)とは何か?
SPFとDKIMのそれぞれにあり、DKIMだけについて言えば header.d= のドメインと header.from= のドメインを比較し正当性を検証します。

アラインメントには厳密緩和の2通りあり緩和ではサブドメインも正しいと判断します

上記の例では1つの署名は「qiita.com」で一致してます。
また、DMARCではSPF/DKIMどちらかがpassしてアラインメントも合格していればpassと判断します。
つまり、openDMARCの判定が間違いです。

アラインメントを理解する

一番特徴的なのが、DMARCをpassするには、SPF/DKIMのどちらか一方だけでも良いという点です。
試しに、SPFだけにしてGmailに送信してみましょう。(openDKIMのmilterを外す)

ほら、SPFだけでもちゃんとDMARCはpassしたでしょう。
もちろんこの場合、DMARCのDNS設定やFromと送信元のドメイン名が一致している場合です。
同様にDKIMだけでも良いです。
DKIMの場合は、送信ドメイン名が違っていても許される点が大きいです。
(qiitaの例がまさにそうです)

openDMARC の問題点

さて、良くありがちなのが header.from に素直に親ドメイン(つまり会社のドメイン)を設定していれば良いですが、往々にしてサブドメインにしている会社を見かけます。
例えば、mail.yahoo.co.jp のように。
もちろん使っても問題は無いのですが、openDMARC では

Authentication-Results: openDMARC; dmarc=none (p=none dis=none) header.from=emails.****.jp
Authentication-Results: openDMARC; spf=pass smtp.mailfrom=em7420.emails.****.jp

のように dmarc=none を返す場合があります。
none という値は定義されておらず passfail でなければなりません。
これはどう解釈すべきなのでしょう?
DMARCのポリシーは特別にサブドメインの指定が無ければ親ドメインの設定が継承されます。
どうも、openDMARC の GitHub の過去の issue を見る限り、サブドメインへの継承が出来ておらず、結構な修正が必要なようで先送りされているようです。
実際に開発も3年前からほとんど進んでいないようでこの先も期待が持てそうもない状況です。
送信側についてはopenDMARCを使わなくても問題無い事は書きましたが、このように受信側で正しい判定をしてくれないのでは使う意味がありません。

Rspamdに変える

今も開発が継続しているという観点からRspamdを代替に検討してみました。
Rspamdは高機能なスパムフィルタとして有名で、解説するサイトもその観点で書かれている場合がほとんどです。
RsmapdはSPF/DKIM/DMARC/ARCの機能も持っておりここではDMARCに必要な機能だけ利用することにしました。
スパムフィルタやWEBのUIによる設定や分析機能がありますが設定が大変です。
今回利用する予定が無いので最小限の設定を行いました。

Rspamd のDMARCだけを利用する為の設定

openDKIM/openDMARCの代替だけに必要な設定に絞って説明します。
インストール方法等の詳しい手順は他のサイトを参照して下さい。
要点は、

  • Redisのインストールは不要
  • スパムフィルタの設定は不要
  • WebUIの設定は不要
  • Milterの設定が必要

Redisはデータベースシステムです。

DMARCのレポートを送るならRedisも必要になります。

また管理や分析の為のWEBインターフェースも必要ありません。
初期設定の際、最初にRedisの使用を聞いてくるので"n"で答えます。

# rspamadm configwizard
   :
Do you wish to set Redis servers?[Y/n]:n

SPFはデフォルトで有効なので設定不要です。
DKIMはキーを dkim_keygen で作成する事が出来ますが、openDKIMで作ったキーをそのまま使えます。

Rspamdの設定ポリシーは少し変わっていて、設定ファイル(*.conf)を直接書き換えず差分を追加(または上書き)します。
多くは、/etc/rspamd/local.d/ に追加設定ファイルを置きます。

openDKIMで作ったキー(秘密鍵)を利用する場合は、ファイルをコピーし
/etc/rspamd/local.d/dkim_signing.conf を開き修正します。

allow_hdrfrom_mismatch_sign_networks = true;
allow_username_mismatch = true;
domain {
    ドメイン名 {
        selector = "セレクタ名";
        path = "/var/lib/rspamd/dkim/秘密鍵のファイル名";
    }
}
sign_authenticated = true;
use_esld = false;
use_domain = "header";
allow_hdrfrom_mismatch = true;

こうすることで、DNSに設定したレコード(公開鍵)をそのまま使えます。

次に、postfixと連携する為に main.cf に milter を設定します。
考え方は openDKIM/openDMARCと同じです。
私の場合は簡単にコメントで切り替えできるようにしています。

# smtpd_milters = inet:127.0.0.1:8891, inet:127.0.0.1:8893
smtpd_milters = inet:127.0.0.1:11332

以上で、送信側はうまくSPF/DKIM/DMARCに対応しますが、このままでは受信側のメールヘッダーには何も載りません。
/etc/rspamd/local.d/milter_headers.conf
を作成して、必要とするヘッダー情報を追加します。
詳細はRspamdの公式ドキュメントを参照して下さい。
デフォルトで良ければ1行だけ書きます。

use = ["authentication-results"];

これで追加されるようになります。
再び Qiita からのメールを受信して見てみましょう。

Authentication-Results: ****.com;
	dkim=pass header.d=qiita.com header.s=ykosyy7esjatwnwqjaghjxf3c5e6b7ej header.b=OigRdk5H;
	dkim=pass header.d=amazonses.com header.s=7v7vs6w47njt4pimodk5mmttbegzsi6n header.b=CCJyHnda;
	spf=pass (****.com: domain of 01010190af7b90a9-87514781-d595-483b-a7a5-bf65a1af779b-000000@us-west-2.amazonses.com designates 54.240.27.23 as permitted sender) smtp.mailfrom=01010190af7b90a9-87514781-d595-483b-a7a5-bf65a1af779b-000000@us-west-2.amazonses.com;
	dmarc=pass (policy=none) header.from=qiita.com

ちゃんとdmarc=passになっている事が判ります。

Thunderbird でのDMARC利用例

いちいちメールの詳細(エンベロープ)を確認するのは面倒です。
メールソフトで簡単にDMARCの結果を見る例として、Thunderbird にフィルタを作ってみました。

直接迷惑フォルダに移動しても良いですが、今のところはタグを付ける位が良いのではと思います。
SPF/DKIMの判定を加えても良いですが成りすまし検知という意味では、あくまでDMARCの判定が頼りです。

最後に

DMARC をいくら送信側が対応してもメールを受ける側が対応し、利用者に正しく理解してもらわないと結局宝の持ち腐れです。
その為にはメールソフト(メーラー)もデフォルトで対応して欲しいところです。
それまでは自分でフィルタを作る等して活用しましょう。
DMARCの次にBIMI(企業ロゴの表示)があるように言う人がいますが、利用者側の視点に立つと私はちょっと方向性が違うんじゃないの?と思ってしまいます。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?