💨

DKIM2についての所感

2024/12/14に公開

このブログは GMOペパボ エンジニア Advent Calendar 2024 🎄 の14日目の記事です。

13日目はKazuhito Nakayamaさんの「minneはなぜGraphQLを推進しているか」です。私はあまりプログラムを書けない身なのですが、GraphQLに関する社での取り組みを俯瞰するのにとても学びがありました。

15日目はshimojuさんが書かれるようです。楽しみですね。

前書き

GMOペパボでは、いわゆるレンタルサーバのサービスを提供しており、サービスでは、毎日、大量のメールが行き来しています。

興味がある方は、「MREチームの取り組み - Pepabo Tech Conference #21 夏のSREまつり」や、テックブログなどを見ていただけると早いです。

私自身はMREチームに所属していませんが、メールについては関心が高いです。そのため、今回は、メールの仕組みが大幅に変わりえるDKIM2の議論について興味を持ちました。そこで、IETFのdraftである「DKIM2 Why DKIM needs replacing, and what a replacement would look like」を読んだので、特に重要と思われた概念や、draftで解消したい関心ごとについて共有します。

おことわり

本文書中では、現行のDKIMをDKIM1とし、draftにて提案されている内容をDKIM2とします。

tl;dr

DKIM2で注目すべきは以下のような部分でしょう。

  • ホップ毎に、メールにTrace Information以外にも処理を行う
  • ホップの逆順に、変更内容を辿ったりエラー通知を行うことができる
  • メールのタイムスタンプを元に配送可能な期限を設定する
  • DKIM1やSMTPで標準化されていないエラーに関する取扱いを標準化する

メールデータの例

これが

Return-Path: <user1@rcpt-to.sender>
Received: from hop2
        by receiver (Postfix) with ESMTPS id EDB104092E3
        for <user1@receiver>; Sat, 14 Dec 2024 18:31:56 +0900 (JST)
Received: from hop1
        by hop2 (Postfix) with ESMTPS id B2A3F4092D0
        for <user1@receiver>; Sat, 14 Dec 2024 18:31:56 +0900 (JST)
Authentication-Results: hop2;
        dkim=pass header.d=sender header.s=s20241214 header.b=WynAFD3V
Received: from sender (client.a.test [10.255.1.10])
        by hop1 (Postfix) with SMTP id 93E5B4092BC
        for <user1@receiver>; Sat, 14 Dec 2024 18:31:55 +0900 (JST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sender;
        s=s20241214; t=1734168716;
        h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
         to:to:cc; bh=0pdj9wqws+KIJQqIWGPQakvN114IPDt1CK4ekSU+NIs=;
        b=WynAFD3VO2E1v9Va72tkztVrqgWh2/UhLjRkEQbvqd76trkf6D/Mvt1oegieNNIxRYscPQ
        vBbb3rJoZURLtjCipw5M6x3Zv5imuEse6CIVgNvfVuRP7R3IIYQJRtumOuRQWPXWfoGyId
        g3e6NJAlEopEb0GYSlQZBKeeTgpytdpKcWYPC923gIIjBlytKEPXn6bffYqfq0uCwLTi31
        ZGnVz3eKQ3upTlWz+bCz+tQKXDFqpyAW0en6LrIpNmbPyDp90rVwzjFF/vpSj20j8sEXAQ
        BTIwTO3kjspsNKWAJ5wrBcXQ1NGnGxglamBgg+wJd4/qSalyk8xiIj3XdDXOAw==
Message-ID: <20241214183155.20147@sender>
Date: Sat, 14 Dec 2024 18:31:55 +0900
From: user1@sender
To:   user1@receiver
Subject: some subject

Hello world

このような形になる気がします。

Return-Path: <user1@rcpt-to.sender>
Authentication-Results: receiver;
        dkim=pass header.ds=hop2,hop2-20241214 header.b=(省略)
Received: from hop2
        by receiver (Postfix) with ESMTPS id EDB104092E3
        for <user1@receiver>; Sat, 14 Dec 2024 18:31:56 +0900 (JST)
DKIM-Signature: 
        i=3; t=1734168718; ds=hop2,hop2-20241214; a=rsa-sha256; h=;
        m=nomodify; mf=user1@sender; rt=user1@rcpt-to.sender; fb=y; n=2345678901;
        bh=(省略)=;
        b=(省略)==
Authentication-Results: hop2;
        dkim=pass header.ds=hop1,hop1-20241214 header.b=(省略)
Received: from hop1
        by hop2 (Postfix) with ESMTPS id B2A3F4092D0
        for <user1@receiver>; Sat, 14 Dec 2024 18:31:56 +0900 (JST)
DKIM-Signature: 
        i=2; t=1734168717; ds=hop1,hop1-20241214; a=rsa-sha256; h=;
        m=nomodify; mf=user1@sender; rt=user1@rcpt-to.sender; fb=y; n=2345678901;
        bh=(省略)=;
        b=(省略)==
Authentication-Results: hop1;
        dkim=pass header.ds=sender,s20241214 header.b=WynAFD3V
Received: from sender (client.a.test [10.255.1.10])
        by hop1 (Postfix) with SMTP id 93E5B4092BC
        for <user1@receiver>; Sat, 14 Dec 2024 18:31:55 +0900 (JST)
DKIM-Signature: 
        i=1; t=1734168716; ds=sender,s20241214; a=rsa-sha256; h=some-header;
        m=nomodify; mf=user1@sender; rt=user1@rcpt-to.sender; fb=y; n=1234567890;
        bh=0pdj9wqws+KIJQqIWGPQakvN114IPDt1CK4ekSU+NIs=;
        b=WynAFD3VO2E1v9Va72tkztVrqgWh2/UhLjRkEQbvqd76trkf6D/Mvt1oegieNNIxRYscPQ
        (省略)
        BTIwTO3kjspsNKWAJ5wrBcXQ1NGnGxglamBgg+wJd4/qSalyk8xiIj3XdDXOAw==
Message-ID: <20241214183155.20147@sender>
Date: Sat, 14 Dec 2024 18:31:55 +0900
From: user1@sender
To:   user1@receiver
Subject: some subject

Hello world

最大の関心ごと: DKIM1の問題点と解消方法

DKIM2に関して、一番の関心ごとは「何が嬉しいか」ということでしょう。DKIM2のdraftでは、長年のメール運用の知見によって得られたDKIM1問題点の洗い出しが行われています。(これは、DKIMに限らず、SMTP自体の問題も絡んでいるものもあります。)

元の文書の第4章に具体的な問題が書かれているので、ざっくり説明します。尚、記述は和訳ではなく、筆者の解釈なので注意してください。

  1. ヘッダの取り扱いが複雑。h=の順序や、c=の選択方法、省略可能なタグもあり、実装は柔軟に対応しなければならない。そのため、全て必須項目にする。
  2. 前ホップに確実にバウンスを行う場合は、SMTPトランザクション内に行う必要がある。DKIM2に従うと、ホップ毎に、しいバウンス先を知ることができるようになるため、SMTPトランザクションに関係なく、かつ、仕様上定められた期間内(5.3によると1week)までならバウンスを行うことができるようになる。
  3. メール転送サービスにおいて、SPFなどの問題によりSender Rewriting Schemeを実行する場合、書き換えた事実をあとで追うことができないため、適切にバウンスができない場合がある。DKIM2の場合、書き換えたこと自体も記録するので、バウンスが行えるようになる。
  4. SMTPのエラーは、現状Return-Pathベースで行われてしまうため、エラーメールの取り扱いに関して、VERP(a+b=example.com@example.jpのような)やSRSのように標準化されていない方法が取られる。これをDKIM2 DSNでは標準化する。
  5. 古典的なメーリングリストによっては、メールデータ中のヘッダを解釈せず、reply-toを追加したり、titleを変更するような動作が取られる。そういった処理をした場合に、DKIMはfailしてしまう。DKIM2では、変更前に戻せるような仕組みを取り入れる。
  6. 5に関する内容で、例えば、受信したメールのURLにアクセスした場合にセキュリティ担当者が監査可能なように、社内セキュリティゲートウェイによってURLを書き換えるなどの挙動は、変更を戻せない場合がある。そういった場合は、書き換えたエンティティ自身が最初のホップ(メール送信者)になることが期待されるとのこと。
  7. DKIM1では、(セレクタが変更されない限りは、)過去に送信されたメールを再送してもDKIMがパスしてしまう。そしてメールは簡単に複製可能である特徴を合わせると、DKIMがパスするメールを不特定多数に大量に送信することで、IPやドメインのレピュテーションを損なうような攻撃が可能である。DKIM2では、タイムスタンプベースでメールの期限についての仕様を導入し、古いメールは拒否されるため、このような攻撃ができなくなる。

(時間の都合上、8.と9.は省略しました。)

以上となります。

参考文献

あとがき

あまりに書きたいことが多かったのですが、情報共有という点では余計な部分についてはいかにまとめました。

補足: tl;dr中のDKIM2の具体化について

DKIM2のような新しい技術に関する議論を見ると、実際にどのようなものなのか、実例があると手っ取り早いなあと思うのが人間の心理だと思います。一方で、DKIM2は、それ自体はまだまだ議論が始まったばかりで、 tl;dr に書いたような具体例は提示されていません。ましてや、誤った例を提示するのは、害悪となりえる可能性も認識しています。

しかし、DKIM2に関することだけでなく、インターネット上におけるメールに関する議論は、実例が伴わないことが多いため、何となく読んで何となくわかった気になる場合が多いです。私自身、今回のdraftを見て、適当な翻訳を読み、慣れない英文を読んで、わかった気になりかけてしまっていたので、「現状の私の理解ではこうなるはず」という具体例を示すこととしました。誤っているという指摘は大いに歓迎です。

付録: 1~3章の試訳

以下、ざっくりDKIM2が何がしたいかわかるように、 https://datatracker.ietf.org/doc/draft-gondwana-dkim2-motivation/ の1~3章までの試訳を置いておきます。

1. 背景とモチベーション

2007年、見方によっては(in a way)、受信者がソースドメインのDNSに公開されている公開鍵とマッチする秘密鍵を保持するエンティティからメールが来ることを保証することが可能となる方法で、メールに署名するドメインへのメカニズムを記すRFC4871(DKIM)が発行された。この文書では明確化のため、これをDKIM1と呼ぶ。

DKIM1の文書は何度も廃止され、アップデートされ、大量の運用経験が得られました。しかし、(DKIM1には)ある種のメールフローの既知の弱点を持っている。

中間者がメールを変更すると、元のDKIM1署名は検証不可能になる。2019年、RFC8617(Authenticated Received Chain / ARC)はこの問題を解決するのに取り組もうとした。しかし、ARC署名を認識するのか、もしくは署名を追加したシステムの正しさを信頼するのかを決定するメカニズムを提供しなかった。

さらに、悪意のあるアクターは、DKIM署名された悪性のメールを”リプレイ”し、署名者のレピュテーションを損なわせる可能性がある。

メールにDKIM署名を配置するアドホックシステムは、 フィードバックループと呼ばれる、リレーしているメッセージのクオリティについて知らされる可能性がある。

しかし、正式な仕様がないスキームやフィードバックには、実際には、必要のないフィードバックが送信されることがある。

さらに、メッセージの送信元が偽造されており、かつ、チェインの最後のサーバ(中間者)が配送不能と気づいた場合、デリバリーステータス通知(DSN)は知らないサードパーティに送られる。この現象をbackscatterと呼ぶ。

この文書は、転送チェインの全てのホップに後述の責任を求めるという全体的な方法で、前述や関連した問題を解決する:

  1. 変更を元に戻すことが可能か、直前のホップを無条件に信頼することを主張し、それをチェーンの次のホップで宣言することで、メッセージが到着するに至ったパスを検証する
  2. (送信者自身の署名の保護下で)次がどこに送信されるかを明確にする
  3. 合理的時間内に、前ホップへ(配送通知やabuseレポート、バウンスを含め)コントロールメッセージを戻すことを宣言する

2. 設計目標

  1. 前世紀から構築されたレガシーメールシステムと新しい仕様は相互運用できることを目的とする。しかしながら、より発展したシステムでは、相互運用の期間後、メールの認証を可能とすることの継続性のためにアップグレードする必要がある。
  2. 曖昧な機能性よりも、単純さを好む。
  3. ほぼすべての一般的なメール利用の利用形態について、暗号技術に関するオペレーションの数を同じかそれ以下に保つ。
  4. 経験上、オプション機能の提供は相互運用性に影響を与えるため、全ての仕様を実装必須であることを目指す。

3. 基本理念

ほぼDKIM1のスタンダードと同じように、DKIM2は originator (※RFC5322 Originator Field) によって署名される。実際、大部分のメールは relaxed/relaxed で署名される。DKIM2 では、 relaxed/relaxed のみ許可する。

メールをハンドルする“ホップ”ごとに、順番に番号が振られたDKIM2ヘッダーフィールドを追加する。シンプルなリレーでは、1行のヘッダーを追加する。メールサービスプロバイダーは、よく2つ追加する。1つは originator 自身、もう一つはメールサービスプロバイダー自身。ドメインを書き換えるメールリレーは、書き換えを記録するために2つのヘッダーを追加する。

メールがサーバに受け入れられたが、後に配送ができないか、もしくはメールの内容を解析したし配送するべきでないと決定された場合、一つ前のホップはデリバリーステータス通知(DSN)という手段を用いて(訳注: 配送できないことを)知られる。

DKIM2ヘッダーはメールの送信元と宛先を含む。メールの品質について(as to)、後のエンティティから ”フィードバック” をリクエストするかもしれない。このフィードバックは、フィードバックを尊重する全ての要求者のうち、送信者が適切とみなした際に送信される。

(のちのホップが署名をチェックしたりアンドゥしたりできるように)メールのレコードを変更する中間者は、アクションを記録する。変更が説明したり戻すのに複雑すぎる変更を持つ中間者は、(メッセージの経路の最初に近い場合、) メッセージの originator として扱われるようにするか、 (メッセージ経路の最後に近い場合、)その後の中間者から暗黙的に信頼される必要がある。

メールを複製する中間者は、のちのシステムが複数のコピーのメールを ”リプレイ”としてメールを破棄したり拒否しないためにアクションを記録する。

Discussion