Upgrade to Pro — share decks privately, control downloads, hide ads and more …

次世代のメールプロトコルの斜め読み

 次世代のメールプロトコルの斜め読み

JPAAWG 8th General Meetingでの発表資料です。
そろそろ固まりそうなDMARC2からDKIM2や宇宙でのメール通信など、RFCになりそうなものからならなさそうなものまで、メールに関するドラフトを斜め読みして紹介しようと思います。

Avatar for HIRANO Yoshitaka

HIRANO Yoshitaka

November 04, 2025
Tweet

More Decks by HIRANO Yoshitaka

Other Decks in Technology

Transcript

  1. 自己紹介 名前 平野 善隆 所属 Hornetsecurity株式会社 (旧Vade Japan) Principal Messaging

    Engineer 好きな メール、DNS、Python、Go 技術 AWS、Serverless 趣味 長距離の自転車大会(1,200kmとか、2,000kmとか) バンド演奏 主な活動 M3AAWG JPAAWG 迷惑メール対策推進協議会 Audax Randonneurs Nihonbashi
  2. 3 www.vadesecure.com メールとの関わり 1990 パソコン通信などでメールに触れる 199x ドメインを取得して近所のISPに個人のサーバーを置かせても らって運用開始 2000 外人さんの多い会社に転職したのでメールの漢字にふりがなを

    付けたりして遊ぶ (のちのhiragana.jp) 個人のサーバーをちゃんとしたデータセンターに移動。 imail.ne.jpというドメインを取って一攫千金を夢見るが挫折 2004 メールの会社に入社 以降 スパムフィルタ、誤送信防止製品の開発やサービスの立ち上げ。 PPAPの礎を築く。 2023 Vade Japan(現Hornetsecurity)に入社
  3. お題 5 • DMARCbis • DKIM2 • Secure SMTP/TLS SRV

    Announcement • RFC5321bis • RFC5322bis • SMTP Service Extension for Client Identity • The LIMITS SMTP Service Extension • Deploying and Using Email in Deep Space • BIMI on an Independent MUA
  4. 新しいタグ (np) 9 • 存在しないサブドメインに対するポリシー • 存在しないとは? • sub.example.jpが存在するかどうか •

    _dmarc.sub.example.jpがあるかどうかは関係ない example.jp v=dmarc1; p=none, sp=quarantine, np=reject sub.example.jpが存在しない → reject sub.example.jpは存在する _dmarc.sub.example.jpが存在しない → quarantine _dmarc.sub.example.jpがp=none → none
  5. p, sp, npの関係 10 親ドメイン Subdomain 参照ポリシー p sp np

    存在する? _dmarc あり なし なし 存在しない - 親ドメインのp あり なし なし 存在する なし 親ドメインのp あり なし なし 存在する あり subドメインのp あり あり なし 存在しない - 親ドメインのsp あり あり なし 存在する なし 親ドメインのsp あり あり なし 存在する あり subドメインのp あり なし あり 存在しない - 親ドメインのnp あり なし あり 存在する なし 親ドメインのp あり なし あり 存在する あり subドメインのp あり あり あり 存在しない - 親ドメインのnp あり あり あり 存在する なし 親ドメインのsp あり あり あり 存在する あり subドメインのp
  6. 現行のDMARCの仕組み 12 • a.b.c.hornetsecurity.com • 1. _dmarc.a.b.c.hornetsecurity.com を調べる • →

    あれば使う • 2. なければ _dmarc.b.c.hornetsecurity.com を調べる? _dmarc.hornetsecurity.com を調べる? • 3. _dmarc.hornetsecurity.comにもなければ _dmarc.com を調べる? 組織ドメインを調べる 調べない 組織ドメインより上は調べない
  7. Public Suffix Domainとは 13 • jp, co.jp, com, net などの組織ドメインの1つ上の階層のこと

    • もともとは、webのクッキーの境界のため company1.net company2.net sub1.example.net sub2.example.net website1.cloudfront.net website2.cloudfront.net • Public Suffix Listというものが(いくつか?)ある が、管理が曖昧 お互いクッキーが見えても問題ない こちらも、まずい cloudfront.netもPublic Suffix Domain お互いクッキーが見えるとまずい
  8. 新しいタグ (psd) 14 • 既存の曖昧なPublic Suffix Listを使わずに、 自分で境界を宣言するためのタグ • y:

    自分はPublic Suffix Domainです。ここより上は探索しないでね。 例: jp, co.jp, cloudfront.net • n: 自分は組織ドメインまたはそのサブドメインです。 ここより上は探索しなくていいよ。 • u: 不明 (デフォルト) 組織ドメインかPSDになるまで上位のドメインを探索する。 → レコードがない場合もこれ a.9.8.7.6.5.4.3.2.com 辿るのは上位8階層だけ
  9. こんな感じ? 15 • _dmarc.jp p=reject; psd=y • _dmarc.example1.jp p=quarantine; psd=n

    • _dmarc.a.example1.jp p=none; psd=n • _dmarc.b.example1.jp レコードなし • _dmarc.example2.jp レコードなし • example1.jp → quarantine • a.example1.jp → none • b.example1.jp → quarantine • example2.jp → reject 現在のDMARCではPSDまで辿らないので DMARCは「なし」になる jp: reject example1: quarantine a: none b: レコードなし example2: レコードなし
  10. 新しいタグ (t) 16 • テストモード • 1段階低いポリシーが適用される • rejectの場合はquarantine •

    quarantineの場合はnone • noneの場合は変化なし • 値はyとn • デフォルトはn • 詳しくは付録A6で議論
  11. t=y と pct=0 17 • pctは0~100の任意の値を設定できたが、受信側は事実上0と 100しか実装していなかった。 • 「p=none」と「p=quarantine; pct=0」に違いがある?!

    • メーリングリストなどでヘッダFromを書き換える機能がある。 → p=quarantine, rejectの場合には書き換わる → p=noneでは書き換わらない • 0, 100しかないのにpctはおかしい • tタグを新たに導入、pctは廃止
  12. 廃止されたタグ 18 • pct: tに置き換え • ri: レポートの送信間隔。 誰も実装せず無視して日次で送信。→ 廃止

    • rf: 失敗レポートのフォーマット afrf(ARF形式)とiodefが指定できたが、ARFに固定。
  13. ドメイン所有者の アクション 21 • SPFをヘッダFromのドメインで公開 • DKIMをヘッダFromのドメインで署名するように設定 • DMARCレポートを受けられるように準備 •

    p=noneとruaタグを書いたDMARCレコードを公開 • レポートを集めて分析 • 認証に失敗している原因を修正 • ポリシーを厳しくするかどうかを決める 必ずしもp=rejectにするのがいいとは限らない
  14. 慎重になるべきポイント2 23 • 一般ユーザーが日常的にメールを送るようなドメインで、イン ターネット上のメーリングリストに送るような場合 • p=rejectにするべきではない (SHOULD NOT) •

    p=rejectにしたい場合は • 1ヶ月間p=noneでレポートを分析 • さらに1ヶ月間p=quarantineでレポートを分析、noneの時と比較する • p=rejectにする場合は、ユーザーに • メーリングリストに投稿させないようにするか • メーリングリストの参加が妨げられる可能性があることを周知すべき (SHOULD)
  15. メール受信者のアクション 24 • ヘッダFromからドメインを抽出 • DMARCが宣言されているか確認 • SPF、DKIMのチェック • アラインメントを確認

    • DMARCのPASS, FAILを決定 • ポリシーを適用する • 結果を保存する • Aggregateレポートを送る • 失敗レポートを送ってもいい
  16. ポリシー強制の懸念 25 • DMARC PASSはヘッダFromドメインが正当なものであること を示すにすぎず、メッセージの価値判断をするものではない • DMARC PASSでも隔離したり、Rejectしてもよい •

    p=rejectでDMARCが失敗しても、メールを受け入れてもよい • p=rejectだけを理由にRejectすべきではない (SHOULD NOT) • p=noneの場合は既存の処理プロセスを変更してはならない (MUST NOT)
  17. ARCよりはヘッダFromの書き換え 27 • ここ10年でメーリングリストソフトはすでに [email protected][email protected] のように書き換えるような修正をおこなった • 理想とはほど遠いがメーリングリスト業者は受け入れている

    • ARCも解決策のひとつで研究は現在も進行中であるが、 この文書の発行時点では、広く普及するには至っていない • 将来、広く採用されるようになった場合には、 本文書は更新される
  18. DKIM2のRFCドラフト 29 • DKIM2 - signing the source and destination

    of every email (draft-ietf-dkim-dkim2-motivation-01) • DomainKeys Identified Mail Signatures v2 (DKIM2) (draft-clayton-dkim2-spec-03) • DKIM2 Header Definitions (draft-gondwana-dkim2-header-05) • Domain Name Specification for DKIM2 (draft-chuang-dkim2-dns-03) • A method for describing changes made to an email (draft-gondwana-dkim2-modification-alegbra-04) • DKIM2 Procedures for bounce processing (draft-robinson-dkim2-bounce-processing-01) • DKIM2 Message Examples (draft-robinson-dkim2-message-examples-00) 昨日 変わった!
  19. DKIM2 - signing the source and destination of every email

    draft-ietf-dkim-dkim2-motivation-02 (2025-11-03)
  20. DKIM2 - signing the source and destination of every email

    31 • 2007に公開されたDKIMの問題点を解決する目的 • DKIM-Replay攻撃 • 署名者へのフィードバック • 署名対象ヘッダのリストの簡素化 • 特定のヘッダは必ず署名 • 差分は保存 • → Header Stuffing Attackから守る From: [email protected]  悪い人が追加 From: [email protected]
  21. 配送途中ですること 32 • 正当な受信者を記録する • DKIM Replay Attackの防止 • 中継されるたびに署名を追加し、連鎖させる

    • バウンスは署名され、元のパスを辿って返送される • Back Scatterの防止 • 変更する場合、変更内容を記録する • URL書き換えなど契約に基づいて変更している場合など戻す必要がな いものについては不要
  22. DomainKeys Identified Mail Signatures v2 (DKIM2) 35 • DKIM2のメインプロトコルを説明する資料 •

    以下がDKIMとは異なる • 新しいDKIM2-Signatureヘッダ • 署名、検証手順の変更 • 暗号アルゴリズムと鍵管理の変更 • その他セキュリティ考慮
  23. DKIM2-Signatureヘッダ 36 • i: 署名の連番 • d: 署名者のドメイン名 • s1:

    セレクタ • mv: メッセージのバージョン • t: タイムスタンプ • mf: MAIL FROM (Envelope From) • rt: RCPT TO (Envelope To) • a1: 署名のアルゴリズム • b1: 署名データ • bh1: 本文のハッシュ • h: 署名するヘッダ名 (option) • f: フラグ (option) • pp: 代理署名時の元のドメイン (option)  昨日なくなった • n: base64の文字列。署名者が自由に使ってよく、受信時には利用されない (option)
  24. i=タグ 37 • 中継毎にカウンターを増加 • 最大50 MAIL FROM: <[email protected]> RCPT

    TO: <[email protected]> DATA DKIM2-Signature: i=2; d=alias.example; s1=key4321; [email protected]; [email protected]; b1=PASS DKIM2-Signature: i=1; d=origin.example; s1=key1; [email protected]; [email protected]; b1=PASS From: <[email protected]> A Message! MAIL FROM: <[email protected]> RCPT TO: <[email protected]> DATA DKIM2-Signature: i=1; d=origin.example; s1=key1; [email protected]; [email protected]; b1=PASS From: <[email protected]> A Message!
  25. f=タグ 40 • すでにやったこと・受信サーバにやってほしいこと • exploded • 他の人に送った • modifiedbody

    • 本文を変更した • modifiedheader • ヘッダを変更した • donotmodify • 変更しないで • donotexplode • 他の人に送らないで • feedback • Feedbackレポートを送って
  26. s1, a1, b1, bh1 / s2, a2, b2, bh2 41

    • 複数の署名を付けられるようになっている • どちらか失敗したら、全体が失敗とみなす • たぶんこんな感じ DKIM2-Signature: i=1; d=example.jp; s1=sel1; a1=rsa-sha256; bh1=abc; b1=abcdefg; s2=sel2; a2=ed25519-sha256; bh2=abc; b2=hijklmn; From: <[email protected]> A Message!
  27. pp=タグ 43 • 転送時等に代理で署名した時の本来のドメイン • origin.exampleの代わりにforwarder.exampleが署名 → d=forwarder.example; pp=origin.example •

    origin.exampleのDNSの_ppレコードには、 forwarder.exampleを認可する旨を記述 2025/11/3のドラフトで消えた
  28. A method for describing changes made to an email 46

    • ヘッダや本文の変更を記録する方法 • MailVersion というヘッダを追加
  29. MailVersionヘッダ 47 • v= リビジョン番号 • bh= このリビジョンのハッシュ • bin.n.m=

    Part毎のハッシュ • b= 本文のレシピ • h.header名= ヘッダのレシピ
  30. 本文のレシピ 48 • c: start-end の範囲の行をコピーする • b: base64で書かれた行をdecodeして挿入 •

    t: textで書かれた行を挿入 • z: 差分は保存しない。元に戻せない MailVersion: v=2; bh=...; b=c:1-500, b:PGEgaHJlZj0iaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20iPkV4YW1wbGU8L2E+Cg==, c:501-702 <a href="https://www.example.com">Example</a> 本文501行目にあったURLの行を削除したときのヘッダ
  31. ヘッダのレシピ 49 • d: int 番目のヘッダを削除、または*で全て削除 • b: base64で書かれたヘッダをdecodeして挿入 •

    t: textで書かれたヘッダを挿入 • z: 差分は保存しない。元に戻せない MailVersion: v=3; bh=...; h.Subject=d:*,t:A replacement for DKIM; h.Reply-To=d:* A replacement for DKIMというSubjectを変更した Reply-Toヘッダを追加した
  32. DNSへの鍵の公開方法 51 • 基本的にはDKIM1と同じ • k=にed25519が利用可能 • DKIM1にはRFC8463で追加されたもの • DKIM2には標準装備

    • Defaultはrsa • DKIM2完成時にはed25519-sha256の実装が必須(MUST)に変 更される • sha1はdeprecated
  33. 例: 転送 54 • a.comからb.comにメールを送信 MAIL FROM: <[email protected]> RCPT TO:

    <[email protected]> DATA DKIM2: i=1; d=a.com; [email protected]; [email protected] From: Sender <[email protected]> To: <[email protected]> I hope this email reaches its destination MAIL FROM: <[email protected]> RCPT TO: <[email protected]> DATA DKIM2: i=2; d=b.com; [email protected]; [email protected] DKIM2: i=1; d=a.com; [email protected]; [email protected] From: Sender <[email protected]> To: <[email protected]> I hope this email reaches its destination • b.comがc.comに転送
  34. 例: 転送先からBouce (c → b) MAIL FROM: <> RCPT TO:

    <[email protected]> DATA DKIM2: i=1; d=c.com; [email protected] From: <[email protected]> To: <[email protected]> Subject: DSN for ... Content-Type: multipart/report; boundary="divider43541325151" --divider43541325151 Content-Type: text/plain This message is being returned. --divider43541325151 Content-Type: message/delivery-status --divider43541325151 Content-Type: message/rfc822 DKIM2: i=2; d=b.com; [email protected]; [email protected] DKIM2: i=1; d=a.com; [email protected]; [email protected] From: Sender <[email protected]> To: <[email protected]> I hope this email reaches its destination --divider43541325151--
  35. 例: 元の送り先からBouce (b → a) MAIL FROM: <> RCPT TO:

    <[email protected]> DATA DKIM2: i=1; d=b.com; [email protected] From: <[email protected]> To: <[email protected]> Subject: DSN for ... Content-Type: multipart/report; boundary="divider89869878" --divider89869878 Content-Type: text/plain This message is being returned. --divider89869878 Content-Type: message/delivery-status --divider89869878 Content-Type: message/rfc822 DKIM2: i=1; d=a.com; [email protected]; [email protected] From: Sender <[email protected]> To: <[email protected]> I hope this email reaches its destination --divider89869878-- . i=2のヘッダは消えている
  36. SRVレコード 59 • RFC2782 (2000/2月) • ホスト名: _サービス名._プロトコル.名前 • 内容:

    優先度 重み ポート 対象サーバー _abc._tcp.example.jp SRV 10 30 8080 api.example.jp. SRV 10 70 8081 api.example.jp. SRV 20 0 8080 api_back.example.jp.
  37. Secure SMTP/TLSの仕組み 60 • SRVレコードのサービス名は「_smtp-tls」 • portが25の場合はSTART TLS • portが25以外の場合はImplicit

    TLS(暗黙のTLS) • portは842であるべき • SRVレコードがあるときはMXは調べない _smtp-tls._tcp.example.jp SRV 0 0 25 mail.example.jp Implicit TLSの場合 _smtp-tls._tcp.example.jp SRV 0 0 842 mail.example.jp START TLSの場合
  38. RFC5321からの変更点 62 • 基本的な動作は変わっていない • 構文定義(ABNF)の修正・更新・明確化 • Source Routeに関する説明を削除 •

    @example1.jp,@example2.jp:[email protected] • 索引などの追加 • EHLOが複数来た場合や引数の明確化 • MTAとMSAの区別 • EHLO, HELOの引数の後ろに余分なテキストを付けることを禁 止 (SHOULD NOT → MUST NOT) • EHLO localhost abcdefg
  39. Appendix A.5 空白やコメントの例 64 From: Pete(A nice \) chap) <pete(his

    account)@silly.test(his host)> To:A Group(Some people) :Chris Jones <c@(Chris's host.)public.example>, [email protected], John <[email protected]> (my dear friend); (the end of the group) Cc:(Empty list)(start)Hidden recipients :(nobody(that I know)) ; Date: Thu, 13 Feb 1969 23:32 -0330 (Newfoundland Time) Message-ID: <[email protected]> Testing. From: Pete(A nice \) chap) <[email protected](his host is silly)> To:A Group(Some people) :Ed Jones <[email protected](.host of Ed)>, [email protected], John <[email protected]> (my dear friend); (the end of the group) Cc:(Empty list)(start)Hidden recipients :(nobody(that I know)) ; Date: Thu, 13 Feb 1969 23:32 -0330 (Newfoundland Time) Message-ID: <[email protected]> Testing. RFC5321 RFC5321bis
  40. Received:で空のトークンに空白を許可 65 • RFC5322 • received = "Received:" *received-token ";"

    date-time CRLF • RFC5322bis • received = "Received:“ [1*received-token / CFWS] ";" date-time CRLF Received:; Mon, 02 Jan 2006 15:04:05 -0700 Received:; Mon, 02 Jan 2006 15:04:05 -0700 Received: ; Mon, 02 Jan 2006 15:04:05 -0700 Received: ; Mon, 02 Jan 2006 15:04:05 -0700
  41. Message-Idの<>の中に名前が付いた 66 • RFC5322 msg-id = [CFWS] "<" id-left "@"

    id-right ">" [CFWS] • RFC5322bis • msg-id = [CFWS] "<" msg-id-internal ">" [CFWS] msg-id-internal = id-left "@" id-right
  42. 仕組み 70 • EHLOの応答: CLIENTID • TLS/START TLSが確立している場合のみ送信 • SMTPコマンド

    • CLIENTID <client-id-type> <client-id-token> • client-id-type: UUID、ライセンス、デバイスID、MACアドレスなど • CLIENTIDコマンドはAUTHの前でのみ使用可能 • CLIENTIDは1度しか送信できない • RSETでCLIENTIDは破棄される
  43. ユースケース 71 • 特定のデバイスからのみAUTHの使用を許可 • 同一のクライアントからたくさんのAUTHが成功していれば怪 しいので制限する • 過去に使われていたAUTHと違う場合制限する •

    ライセンスキーなどをトークンにし、利用を許可する • CLIENTIDのあり/なしで違うポリシーを適用する • 複数のデバイスがIPを共有していても、CLIENTIDでレート制 限すれば、他に影響を与えない • CLIENTIDを第3の要素として認証に渡して利用する
  44. 例 72 C: [connection established] S: 220 server.example.com ESMTP ready

    C: EHLO client.example.net S: 250-server.example.com S: 250-STARTTLS S: 250 AUTH LOGIN C: STARTTLS S: 220 Go ahead C: <starts TLS negotiation> C & S: <negotiate a TLS session> C & S: <check result of negotiation> C: EHLO client.example.net S: 250-server.example.com S: 250-AUTH LOGIN S: 250 CLIENTID C: CLIENTID UUID 23bf83be-aad7-46aa-9e0f-39191ccf402f S: 250 OK C: AUTH LOGIN dGVzdAB0ZXN0ADEyMzQ= S: 235 Authentication successful C: MAIL FROM:<[email protected]> ・・・ CLIENTIDを広告 一意なIDを送信
  45. EHLOでLimitを返す拡張 74 • EHLOの応答: LIMITS • 制限の種類 • MAILMAX: •

    1トランザクションで処理できるメール数 (MAIL FROMの回数) • RCPTMAX: • RCPT TOコマンドの回数 • RCPTDOMAINMAX: • RCPT TOコマンドで渡せるユニークなドメイン数 C: EHLO example.org S: 250-mail.example.com S: 250-LIMITS RCPTMAX=20 MAILMAX=5 S: 250-SIZE 100000000 S: 250-8BITMIME S: 250-PIPELINING S: 250-CHUNKING S: 250 STARTTLS
  46. 宇宙空間の一連のドラフト 76 • IP in Deep Space: Key Characteristics, Use

    Cases and Requirements • (draft-ietf-tiptop-usecase-00) • Deployment and Use of the Domain Name System(DNS) in Deep Space • (draft-many-tiptop-dns-01) • An Architecture for IP in Deep Space • (draft-many-tiptop-ip-architecture-02) • Deploying and Using Email in Deep Space • (draft-many-tiptop-email-00)
  47. 地球から深宇宙へメールを送る 78 1. Earth Mail GatewayがSMTPでメールを受け取る 2. GatewayはメールをBatch SMTP(BSMTP) MIMEオブジェク

    トに変換する (RFC2442) 3. GatewayはこのBSMTPオブジェクトをHTTP/3 QUICを使っ て対応する天体側のGatewayに送信する 4. 天体側Gatewayは受信したBSMTPオブジェクトをデコードし、 天体側の最終メールサーバーにSMTPで送信する
  48. 概要 82 • BIMIはDMARC, SPF, DKIMの検証が必要で、特にSPFはMTA しかできない → BIMIの検証はMTAでやる •

    表示はMUA • MTAとサードパーティーのMUAとの間の相互運用性について考 える
  49. 改ざん防止の仕組み 84 • DKIMと同じ方法で、BIMI-Receiver-Signatureヘッダを付け る • 必須の署名対象は、BIMI-Location, BIMI-Selector, BIMI- Receiver-Information

    • この場合の公開鍵は marketing.example.org.sel_sign._local._bimi.isp.net に保管 BIMI-Receiver-Signature: v=BIMI1; d=isp.net; s=marketing.example.org.sel_sign; c=canonicalization; h=BIMI-Location:BIMI-Selector:BIMI-Receiver-Information; b=<SIGNATURE_BLOB>; t=timestamp BIMI-Receiver-Information: date: Tue, 25 Feb 2023 01:05:55 +0000 ; rcpt: 6d9010b2b7a1483b256ae7477738dba7c530bd9ba53db1d6691441e74b83608a@isp.net