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

浸透しなさいRFC 5322&7208

浸透しなさいRFC 5322&7208

2025年8月22,23日に開催されたDNS温泉11でのスライドです。
非公開部分を編集してあります。

DNS温泉11
https://dnsonsen.connpass.com/event/359943/

Avatar for Nonogaki Hiroshi

Nonogaki Hiroshi

August 25, 2025
Tweet

More Decks by Nonogaki Hiroshi

Other Decks in Technology

Transcript

  1. 自己紹介 • 野々垣 裕司 (ののがき ひろし) • COBOLer (間接的にゲームソフトウェア開発に関わる) •

    1996年からインターネットに携わる。IPv6は2001年から。 • 元々ISPを立ち上げたが、技術提供する方向に転換。 • SNS • Twitter xplntr • Facebook nonogaki • Tumblr https://memorandum.y0.net/ • 得意技? ルーティング(鉄道)、両声類 2025/08/22 DNS温泉11 KEYTEC 2
  2. RFC 5322 とは RFC 5322 は、「インターネットメッセージ形式 (Internet Message Format)」に関する仕様を定 義したインターネット標準文書です。この

    RFC は、電子メールのメッセージの構造とフォーマットを規定 しています。具体的には、以下のような要素を含んでいます: • ヘッダー(Headers): 送信者、受信者、件名、日付などの情報。 • 本文(Body): メッセージの内容。 RFC 5322 は、RFC 2822 を更新するもので、メールメッセージのフォーマットに関する最新のガイド ラインを提供しています。主な内容は以下の通りです: • メッセージの構造: ヘッダーフィールドと本文の区別。 • ヘッダーフィールドの形式: フィールド名、フィールド値、フィールドの折り返し方法など。 • 文字エンコーディング: 特に非ASCII文字を扱うための規則。 • 特定のヘッダーフィールドの詳細な定義(例えば、From, To, Subject など)。 この仕様は、電子メールを送受信する際に、メールクライアントやサーバーが互換性を持って動作するこ とを保証するために重要です。 (Grok-2より) 2025/08/22 DNS温泉11 KEYTEC 3
  3. 3.6. Field Definitions +----------------+--------+------------+----------------------------+ | Field | Min | Max

    number | Notes | | | number | | | +----------------+--------+------------+----------------------------+ | orig-date | 1 | 1 | | | from | 1 | 1 | See sender and 3.6.2 | | sender | 0* | 1 | MUST occur with | | | | | multi-address from - see | | | | | 3.6.2 | | reply-to | 0 | 1 | | | to | 0 | 1 | | | cc | 0 | 1 | | | bcc | 0 | 1 | | | message-id | 0* | 1 | SHOULD be present - see | | | | | 3.6.4 | | in-reply-to | 0* | 1 | SHOULD occur in some | | | | | replies - see 3.6.4 | | references | 0* | 1 | SHOULD occur in some | | | | | replies - see 3.6.4 | | subject | 0 | 1 | | +----------------+--------+------------+----------------------------+ 2025/08/22 DNS温泉11 KEYTEC 4
  4. 3.3 Date and Time Specification date-time = [ day-of-week ","

    ] date time [CFWS] date = day month year day = ([FWS] 1*2DIGIT FWS) / obs-day month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec" year = (FWS 4*DIGIT FWS) / obs-year time = time-of-day zone time-of-day = hour ":" minute [ ":" second ] hour = 2DIGIT / obs-hour minute = 2DIGIT / obs-minute second = 2DIGIT / obs-second zone = (FWS ( "+" / "-" ) 4DIGIT) / obs-zone Date: Fri, 14 Dec 2024 12:34:56 +0900 Date: 1 Dec 2024 12:34 +0900 Date: 1 Dec 2024 12:34 +000 2025/08/22 DNS温泉11 KEYTEC 5
  5. 3.3 Date and Time Specification Date: Fri, 14 Dec 2024

    12:34:56 +0900 Date: 1 Dec 2024 12:34 +0900 Date: 1 Dec 2024 12:34 +000 Date: 1 Dec 2099 12:34 +0000 /^Date: .+ 20[01]/ 2000-2019 /^Date: .+ 202[0-36-9]/ 2020-2023,2026-2029 /^Date: .+ 20[3-9] / 2030-2099 /^Date: .+ [+-][0-9]{1,3}$/ +000 +00 /^Date: .+ [+-][0-9]{5,}/ +00000 /^Date: $/ 2025/08/22 DNS温泉11 KEYTEC 6
  6. 3.6.4. Identification Fields message-id = "Message-ID:" msg-id CRLF msg-id =

    [CFWS] "<" id-left "@" id-right ">" [CFWS] id-left = dot-atom-text / obs-id-left id-right = dot-atom-text / no-fold-literal / obs-id-righ dot-atom-text = 1*atext *("." 1*atext) atext = ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" /“^”/ "_" / "`" / "{" / "|" / "}" / "~" no-fold-literal = "[" *dtext "]" dtext = %d33-90 / %d94-126 / obs-dtext Message-ID: <A-.Zaz09!#$%&'*+/=?^_`{|}~@["(),:;<>]> Message-ID: A-.Zaz09!#$%&'*+/=?^_`{|}~@["(),:;<>] Message-ID: <A-.Zaz09!#$%&'*+/=?^_`{|}~@host[IPv6:2001::abc]> Message-ID: <example> 2025/08/22 DNS温泉11 KEYTEC 7
  7. 3.6.4. Identification Fields Message-ID: <A-.Zaz09!#$%&'*+/=?^_`{|}~@["(),:;<>]> Message-ID: <A-.Zaz09!#$%&'*+/=?^_`{|}~@host[IPv6:2001::abc]> /^Message-ID: .*@localhost¥.localdomain>/ Linuxデフォルト

    /^Message-ID: <[^@]+>$/ @ 文字無し /^Message-ID: <.+[.@]example>/ 使用できないドメイン名 /^Message-ID: <.+[.@]localhost>/ ホスト名設定しろ /^Message-ID: <.+[.@]example¥.[a-z]+>/ 使用できないドメイン名 /^Message-ID: [^<].+[^>]$/ タグ抜くな /^Message-ID: <.*[()<>,:;“].*@/ @文字前に使用不可の文字列使うな /^Message-ID: <.+[^>]$/ タグの後ろに文字列書くな 2025/08/22 DNS温泉11 KEYTEC 8
  8. Other fields to = "To:" address-list CRLF cc = "Cc:"

    address-list CRLF address-list = (address *("," address)) / obs-addr-list Cc: [email protected] Cc: subject = “Subject:" unstructured CRLF comments = "Comments:" unstructured CRLF unstructured = (*([FWS] VCHAR) *WSP) / obs-unstruct VCHAR = %x21-7E WSP = SP / HTAB ; white space Subject: nom nom nom Subject: 2025/08/22 DNS温泉11 KEYTEC 9
  9. Other fields Cc: [email protected] Cc: Subject: nom nom nom Subject:

    /^From: $/ REJECT /^To: $/ REJECT /^Cc: $/ REJECT 実はこれが非常に多い /^Date: $/ REJECT /^Reply-To: $/ REJECT 2025/08/22 DNS温泉11 KEYTEC 10
  10. RFC 7208 とは RFC 7208は、Sender Policy Framework (SPF) に関するインターネット標準仕様で、電子メー ルの送信元ドメインの認証メカニズムを定義しています。SPFは、ドメイン所有者が自ドメインから送信さ

    れるメールの許可されたサーバーを指定するためのDNSレコード(TXTレコード)を使用し、メールのな りすまし(スパムやフィッシング)を防ぐことを目的としています。 • 目的: ドメインのメール送信サーバーを指定し、不正なメール送信を防止。 • 仕組み: 受信側のメールサーバーが、送信元のIPアドレスが送信ドメインのSPFレコードに記載された 許可されたサーバーと一致するかを確認。 • SPFレコードの例: v=spf1 ip4:192.0.2.0/24 include:example.com –all • v=spf1: SPFバージョンを指定。 • ip4: 許可するIPv4アドレス範囲。 • include: 他のドメインのSPFレコードを参照。 • -all: 指定外のサーバーからのメールを拒否。 特徴 • 前身: RFC 4408を更新し、明確化や改善を加えたもの。 • 用途: DMARCやDKIMと組み合わせて、メールセキュリティを強化。 (Grok-5より) 2025/08/22 DNS温泉11 KEYTEC 11
  11. SPF RR • 送信元のIPアドレスで判断する • MAIL FROMのホスト名、HELOのホスト名 • -all Fail

    一致していないとREJECT • ~all Softfail 信頼できないが受信する • ptr つかわないで(RFCに書かれています) • DNS参照は11回になるとエラー • DNS参照ができなかった時は2回になるとエラー • 同じSPF RRは複数書くとエラー 2025/08/22 DNS温泉11 KEYTEC 12 keytec.jp. 86400 IN TXT “v=spf1 include:spf.keytec.jp -all” spf.keytec.jp. 86400 IN TXT "v=spf1 ip6:2001:f58:2003:1::/126 ip6:2001:f58:2003:1::a ip4:202.124.214.192/30 ip4:202.124.214.202 ~all"
  12. 大企業でも間違えるSPF @ IN A TXT “v=spf1 ip4:192.0.2.10/24 ~all” @ IN

    A TXT “v=spf1 ip6:2001:db8::/32 ~all” SPF Permanent Errorとなっていた 全て私が世界中で一番最初に発見したらしい(Xにて) 2021年6月 amazon.com 2021年9月 docomo.ne.jp 2022年6月 icloud.com 2024年8月 ezweb.ne.jp (au.com) 2025/08/22 DNS温泉11 KEYTEC 13
  13. SPF DNS参照の制限 DNS参照ができなかった時は2回でエラー “spf=v1 a:mx.example.jp include:ml1.example.com include:ml2.example.com include:_spf.google.com – all”

    example.comのサービスを利用していたが、このサービ スが終了していた。このドメイン名がなくなったので参 照できずエラーとなった。 2025/08/22 DNS温泉11 KEYTEC 15
  14. SPF DNS参照の制限 DNS参照ができなかった時は2回でエラー city.example.lg.jp. include:_spf.salesforce.com include:spf.bmv.jp _spf.salesforce.com. IN TXT "v=spf1

    exists:%{i}._spf.mta.salesforce.com -all“ spf.bmv.jp. IN TXT "v=spf1 exists:%{i}.spf.bserver.jp exists:%{i}.spf.besender.jp include:spf.sendmsg.jp ~all" 1つめのexistsにてPass 問題無し 2つめのexistsにてPass 問題無し Passでなかったら以降せずPermError 2025/08/22 DNS温泉11 KEYTEC 17
  15. SPF DNS参照の制限 DNS参照ができなかった時は2回でエラー IPv6,IPv4混ぜるな @ IN MX 300 mx.example.jp. IN

    A TXT “v=spf1 a:m41.example.jp a:m42.example.jp a:m43.example.jp ” “a:m61.example.jp a:m62.example.jp a:m63.example.jp a:mx.example.jp –all” m41 IN A 192.0.2.1 m42 IN A 192.0.2.2 m43 IN A 192.0.2.3 m61 IN AAAA 2001:db8::1 m62 IN AAAA 2001:db8::2 m63 IN AAAA 2001:db8::3 mx IN A 192.0.2.10 IN AAAA 2001:db8::10 2025/08/22 DNS温泉11 KEYTEC 18
  16. Mailer deamonのメール example.jp. IN TXT “v=spf1 192.0.20/24 –all” mta1.example.jp. IN

    TXT “v=spf1 192.0.20/24 –all” from=<[email protected]> helo=<mta1.example.jp> SPF example.jp にて評価される from=<> helo=<mta1.example.jp> SPF mta1.example.jp にて評価される heloホストにもSPF RRを書きましょう! 日本は比較的書かれている ⇒ Passで通すことが可能 海外では書かれない事が多い ⇒ Noneとなってしまう 2025/08/22 DNS温泉11 KEYTEC 19
  17. py.spf を使いましょう To check an incoming mail request: % python

    spf.py [-v] {ip} {sender} {helo} % python spf.py 127.0.0.1 [email protected] mta.example.jp % spf.py 127.0.0.1 keytec.jp helo % spf.py ::1 keytec.jp helo # pkg install mail/py311-pyspf 2025/08/22 DNS温泉11 KEYTEC 21