mcpField
S
Sendermap

Sendermap

ローカル
github.com/marmot7775セキュリティ11 日前に更新

Sendermap について

Sendermap は、ドメインのメール設定を監査し、関連サービスを特定する Python 製コマンドラインツールです。公開 DNS などの証拠からサブドメインも含めてサービスを対応付け、確度と未確認事項を示します。メール量や実際の送信状況は判定しません。

主な機能

  1. 01公開情報を基にメールサービスをマッピング
  2. 02SPF、MX、DKIM などのレコードを調査
  3. 03送信サブドメインとサービスの痕跡を検出
  4. 04確度と証拠に基づく結果の表示
  5. 05設定上の問題と未特定の送信元を指摘
  6. 06JSON または Markdown で出力

活用シーン

  1. 01ドメインに設定されたメールサービスの確認
  2. 02未特定のメール送信元の調査
  3. 03DKIM、SPF、サブドメイン設定の確認
  4. 04スクリプトやエージェントとの調査結果共有

MCP 対応

`mcp` エクストラを使うと、Sendermap は標準入出力で `sendermap_map` と `sendermap_vendor` を提供します。スキーマとベンダー一覧もリソースとして公開し、ウェブサイトではストリーミング HTTP で同じツールを利用できます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"marmot7775-sendermap": {
"command": "uvx",
"args": [
"sendermap"
]
}
}
}
起動コマンドuvx sendermap

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
pypisendermap0.1.11

ツール

2

掲載時のツール一覧 · 今日に更新

パラメーター型必須説明
detailenumいいえsummary:各サービスの決め手となる主張。full:すべての情報。summary | full
domainstringはいマッピングするドメイン。例:example.com。
claimedarrayいいえドメイン所有者が使用すると申告したサービス名。
websitebooleanいいえホームページとサブプロセッサーのページを読み取ります。
subdomainsbooleanいいえemail や mg などの送信用サブドメインを検索します。
certificate_logbooleanいいえcrt.sh も読み取り、記録されたすべての名前を解決します。時間がかかります。

詳細

Sendermap

テスト 証明を検証

ドメインを入力すると、そのドメインとしてメールを送信するすべてのサービスと、それぞれの公開証拠を確認できます。

ステータス:早期リリース(0.1.1)。 コマンドラインツールは動作しますが、ウェブサイトはまだホストされていません。 Python 3.12 以降が必要です。

表示される内容

任意のドメインについて、Sendermap は、そのドメインのメールを送信または受信するサービスのマップを作成します。メールボックスプロバイダー、マーケティングおよびトランザクションプラットフォーム、サポート窓口、セキュリティゲートウェイ、レポートを受信するサービスが対象です。それぞれについて、次の情報を確認できます。

  • 証拠:レコードごとに表示します。手掛かりとなった SPF include、MX ホスト、DKIM キー、バウンスまたはトラッキング用 CNAME、確認トークン、レポートアドレスなどです。
  • 確度:パーセンテージではなく、言葉で示します。
    • 使用中:そのドメイン宛てのメールがそこに配信されます。
    • 設定済み:そのドメインとして送信するよう設定されています。
    • 可能性が高い:名前からそのサービスを示唆する署名キーがあります。
    • アカウントのみ:アカウントの痕跡はありますが、送信設定はありません。

メインドメインだけでなく、その先も調べます。ブランドは email.、mg.、bounce. などのサブドメインから送信することがよくあり、メインドメインだけを調べても見つかりません。また、注意が必要な点も示します。存在しなくなった名前を指す DKIM レコード、10 件のルックアップ上限を超える SPF レコード、取り消されたキー、名前を特定できない送信元などです。名前を特定できない未加工の IP 範囲は、その範囲をアナウンスするネットワークごとにまとめられるため、同じプロバイダーの範囲が十数件あっても、1 行で確認できます。

各 DKIM キーには、その動作を変えるタグが表示されます。t=y(テストモード。検証側はこのキーで署名されたメールを未署名として扱います)、t=s(厳格)、h=(ハッシュアルゴリズム)、s=(サービスの種類)、k=(キーの種類)です。テストモードや SHA-1 のみの使用など、キーの安全性を弱めるタグは検出事項として取り上げられます。また、各キーにはフィンガープリント(fp と 16 桁の 16 進数)が付与されるため、異なる 2 つのセレクターで公開されている同じキーを簡単に見つけられます。該当する場合は、マップにもそのことが示されます。

確認した項目と見つからなかった項目

マップには、調査したものの見つからなかった項目と、それを示す DNS 応答も表示されます。現在は DKIM キーが対象です。「見つからなかった」という結果を信頼できるかどうかは、存在しない名前に対するドメインの DNS 応答によって異なります。そのため、各名前について、Sendermap はまず誰も公開していないセレクターを問い合わせ、応答を次の 4 種類に分類します。

  • 従来型:ゾーンが「その名前は存在しない」と応答します。この応答は信頼できます。_domainkey 自体が存在しない場合、その下にセレクターはありません。マップはドメインの SPF と MX が参照する少数の名前だけを確認し、確認範囲が限られていることを明記します。_domainkey は存在するものの、問い合わせた名前がすべて見つからない場合は、セレクターは存在するが、試した名前はいずれも該当しないと示します。
  • rcode による否定なし:ゾーンは、存在しない名前すべてに空の応答(簡潔な否定応答)を返すため、その応答から既存の名前については何もわかりません。マップは全リストを調べますが、存在しないとは断定しません。
  • ワイルドカード:すべての名前に応答があります。マップはワイルドカードが繰り返す内容を無視し、全リストを調べます。
  • 不明:テスト用のルックアップに失敗したため、その応答からは何も判断せず、マップでは未確認として一覧表示します。

仕組み

すべて公開情報を利用しています。DNS、証明書の透明性ログ、ドメイン自身のウェブサイト、各ネットワークの所有者に関する公開記録です。各調査結果には根拠となるレコードが示されるため、ご自身で確認できます。

  • SPF はツリーとしてたどり、送信者を実際に認可するリンクのみを対象にします。
  • DKIM キーは、サービスが使用する名前をスキャンして見つけ、その参照先に基づいて対象を特定します。s1 のように多くのホストが使う一般的な名前は、ドメインの SPF、MX、または NS 委任でそのサービスがすでに確認できる場合に限り、そのサービス(Klaviyo)として扱います。
  • SPF の生 IP 範囲は、各サービスが公開している範囲と照合し、さらにネットワークの所有者を確認して特定します。
  • 送信用サブドメインは、サービスが要求する名前と証明書ログから取得します。Klaviyo や Salesforce Marketing Cloud の設定のように、サービスのネームサーバーへ NS 委任されたサブドメインは、そのサービスのものとして扱います。
  • ウェブサイトからは、読み込まれるスクリプトやスタイルシート、言及されるサービス、サブプロセッサーのページに記載されたサービスを確認します。すべてのページ取得には共通のガードを適用します。https のみを許可し、取得前にホストのアドレスを確認することで、ドメインが取得先をプライベートアドレスや内部アドレスに向けられないようにします。拒否された取得は「未確認」として表示されます。
  • 証明書の透明性:サブドメイン検索では、すべての調査で Cert Spotter のログを読み取ります。--ct(デフォルトでは無効)を指定すると、期限切れの証明書も含まれる crt.sh も読み取ります。また、ログに記録されたすべての名前を現在名前解決し、DNS レコードと同様に照合するため、メールプラットフォームを指す link.example.com のようなブランド付きトラッキングリンクも検出されます。ログに記録された名前が現在は名前解決できないものの、引き続きサービスを指している場合は、現在の送信者ではなく、過去に利用されていた可能性のあるベンダーとして表示されます。crt.sh は応答が遅いことがよくあります。3 回試行し、各ログの結果を 1 日間キャッシュします。応答がないログは「未確認」として表示し、そのログを除いてマップの作成を完了します。

コマンドラインから実行します。PyPI からインストールできます(Python 3.12 以降)。

pip install sendermap
uvx sendermap example.com             # run without installing

リリース前の最新コードは、GitHub から pip install git+https://github.com/marmot7775/sendermap でインストールできます。

sendermap example.com
sendermap example.com --evidence     # every piece of evidence
sendermap example.com --markdown     # a summary to paste
sendermap example.com --json         # everything, for scripts
sendermap example.com --ct           # resolve every name in certificate logs, crt.sh too
sendermap example.com --claimed "Office 365, Mailchimp"   # hold the services you were told of against the map
sendermap example.com --json --output map.json            # write the map to a file

スクリプトやエージェント向け:マップの作成に成功すると終了コードは 0、不正な入力の場合は 2、ドメイン自身のレコードを読み取れなかった場合(マップなし)は 3 です。進行状況は stderr に出力され、ターミナルで実行している場合に限り表示されるため、stdout にはマップのみが出力されます。すべてのフラグについては sendermap --help をご覧ください。

ウェブサイトでは、検索されたドメインの記録を保持しません。

MCP

mcp エクストラを追加すると、sendermap mcp は MCP 経由で stdio 上に 2 つのツールを提供します。sendermap_map の構造化コンテンツは sendermap/1 JSON(概要または全体)としてマップを返し、sendermap_vendor は 1 つのベンダーのパターン、根拠、文書化された設定方法を返します。スキーマとベンダーの一覧はリソースとして提供されます。

{
  "mcpServers": {
    "sendermap": { "command": "uvx", "args": ["--from", "sendermap[mcp]", "sendermap", "mcp"] }
  }
}

ウェブサイトでは、ストリーム可能 HTTP を使って /mcp で同じツールを提供しています。MCP を利用しないエージェント向けには、skills/sendermap/SKILL.md に、コマンドラインを実行して JSON を読み取る Agent Skill があります。

正直な制約

  • 送信量はわかりません。 公開レコードからわかるのは、どのサービスが送信できるよう設定されているかであり、各サービスがどれだけメールを送信するかや、今月に送信したかどうかではありません。
  • キーが使用中である証拠はありません。 DNS に DKIM キーがあることからわかるのは、キーが公開されたことだけであり、何かの署名に使われているかどうかはわかりません。それがわかるのは実際のメールだけですが、Sendermap はメールを読み取りません。
  • ベンダー独自のドメインから送信する場合は確認できません。 決済プラットフォームの領収書のように、サービス自身のドメインから顧客へメールを送る場合、DNS には何も残りません。
  • セレクターの検出を完全に行うことはできません。 DNS から DKIM セレクターの一覧を取得することはできません。Sendermap はサービスで使われるとわかっている名前と、いくつかの一般的な名前を問い合わせ、問い合わせた数を示します。それ以外の名前のキーは検出されません。
  • 存在しないという判定はゾーンの応答に基づいて行い、その旨を示します。 「存在しない」と主張するのは、ゾーンの否定応答の種類から信頼できると判断できる場合に限られ、そのような行にはすべて、根拠となる応答が記載されます。

JSON の契約

sendermap DOMAIN --json とサイトの API は、スキーマ sendermap/1 に準拠したマップを JSON 形式で 1 つ返します。スキーマの説明は sendermap/data/schema/sendermap-1.json にあります(JSON Schema 2020-12。Python では sendermap.schema()、サイトでは /schema/sendermap-1.json)。
sendermap/1 は追加のみで拡張されます。新しいフィールドや新しい値(新しい種類の証拠や、新しい種類の欠落など)が加わることはありますが、削除、名前の変更、意味の変更はありません。不明なフィールドは無視し、不明な値も許容してください。互換性を破る変更は sendermap/2 になります。

ベンダーデータ

ベンダーに関する情報はすべて、サービスごとに 1 ブロックを記載した sendermap/data/vendors.json の 1 つのファイルにあります。そのため、ベンダーの追加や修正は小さなプルリクエストで済みます。初版は dns-audit(MIT)のベンダー表から取り込まれました。

コントリビュート

各ベンダーのブロックは sendermap/data/vendors.json に 1 つずつ記載し、そのベンダーについて判明している情報はすべてそこに入れます。ブロック内の各パターン(SPF の include、MX ホスト、CNAME ターゲット、レポート用アドレス、検証トークン、ネットワーク、ウェブサイトのホスト、セレクター名、サブプロセッサー名)には、それぞれ独自の証拠が必要です。証拠には、そのパターンを公開している稼働中のドメイン、見つかったレコード名またはページ、確認日を記載します(s1、s2 のような番号付きのセレクター群には、系列全体で 1 つの証拠が必要です)。証拠のないパターンはマージされず、Sendermap は読み込みを拒否します。ブロックには aliases を記載することもできます。これは、顧客がサービスを別の名前で呼ぶ場合の別名です(Microsoft 365 の「Office 365」など)。別名はユーザーが入力した内容との照合にのみ使われ、レコードとは照合されないため、証拠は不要です。

まだ証明されていないパターンは sendermap/data/vendors_pending.json で保留されます。各ブロックには、何を確認したかのメモを記載します。Sendermap はこのファイルを読み込まないため、該当するレコードは認識されていないものとして表示されます。ベンダーを保留中の状態から vendors.json に移すには、新しいブロックと同じルールに従い、各パターンに 1 つずつ証拠を添えます。tools/hunt_proofs.py は data/hunt_domains.txt にある顧客ドメインで、週次再確認と同じチェックを行い、証拠を探します。

各証拠は毎週、また vendors.json に関わるプルリクエストごとに、稼働中の DNS とウェブサイトを使って再確認されます。証拠が確認できなくなるとイシューが作成されるため、古くなったパターンを検出して修正できます。

v* タグを付けるとリリースファイルがビルドされ、リポジトリ変数 PYPI_READY が true の場合(Settings、Secrets and variables、Actions、Variables)、信頼された公開によって PyPI に公開され、タグに対応する CHANGELOG.md のノートを使って GitHub リリースが作成されます。

関連項目

  • dns-audit.com:ドメインのメールセキュリティを全面的に監査します。

ライセンス

MIT

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。