Sendermap について
Sendermap は、ドメインのメール設定を監査し、関連サービスを特定する Python 製コマンドラインツールです。公開 DNS などの証拠からサブドメインも含めてサービスを対応付け、確度と未確認事項を示します。メール量や実際の送信状況は判定しません。
主な機能
- 01公開情報を基にメールサービスをマッピング
- 02SPF、MX、DKIM などのレコードを調査
- 03送信サブドメインとサービスの痕跡を検出
- 04確度と証拠に基づく結果の表示
- 05設定上の問題と未特定の送信元を指摘
- 06JSON または Markdown で出力
活用シーン
- 01ドメインに設定されたメールサービスの確認
- 02未特定のメール送信元の調査
- 03DKIM、SPF、サブドメイン設定の確認
- 04スクリプトやエージェントとの調査結果共有
MCP 対応
`mcp` エクストラを使うと、Sendermap は標準入出力で `sendermap_map` と `sendermap_vendor` を提供します。スキーマとベンダー一覧もリソースとして公開し、ウェブサイトではストリーミング HTTP で同じツールを利用できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
2掲載時のツール一覧 · 今日に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| detail | enum | いいえ | summary:各サービスの決め手となる主張。full:すべての情報。summary | full |
| domain | string | はい | マッピングするドメイン。例:example.com。 |
| claimed | array | いいえ | ドメイン所有者が使用すると申告したサービス名。 |
| website | boolean | いいえ | ホームページとサブプロセッサーのページを読み取ります。 |
| subdomains | boolean | いいえ | email や mg などの送信用サブドメインを検索します。 |
| certificate_log | boolean | いいえ | 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
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。