关于 Sendermap
Sendermap 是面向域名管理员和邮件安全审计人员的 Python 命令行工具,用于识别与域名邮件收发相关的服务。它依据公开 DNS 等证据绘制服务图,覆盖子域名,并标注可信程度与信息缺口;不推断邮件量或实际发送活动。
主要功能
- 01依据公开证据映射邮件服务
- 02检查 SPF、MX、DKIM 等记录
- 03发现发送子域名和服务痕迹
- 04按可信程度和证据标注结果
- 05标记配置问题和未知发送方
- 06导出 JSON 或 Markdown
适用场景
- 01核查域名配置了哪些邮件服务
- 02调查无法识别的邮件发送方
- 03检查 DKIM、SPF 和子域名配置
- 04通过脚本或 Agent 分享域名结果
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 地址范围会按通告这些范围的网络分组,这样来自同一提供商的十几个范围就会显示为一行。
每个 DKIM 密钥都会显示会改变其行为的标签:t=y(测试模式,因此验证方会将使用该密钥签名的邮件视为未签名)、t=s(严格模式)、h=(哈希算法)、s=(服务类型)和 k=(密钥类型)。如果某个标签会削弱密钥,例如测试模式或仅使用 SHA-1,就会将其列为发现项。每个密钥还会获得一个指纹,即 fp 和 16 个十六进制字符,因此,同一个密钥发布在两个选择器下时很容易识别;地图也会指出这种情况。
已检查但不存在
地图还会列出它查找过但未找到的内容,并附上能够证明这一点的 DNS 响应。目前,这适用于 DKIM 密钥。能否相信“并不存在”,取决于该域名的 DNS 对不存在名称的响应方式,因此 Sendermap 会先在每个名称下查询一个无人发布的选择器,并将响应归为以下四类之一:
- 经典:区域表示“名称不存在”。响应可信。如果
_domainkey本身不存在,那么其下就没有选择器。地图只检查域名 SPF 和 MX 指向的少数名称,而非完整列表,并会对此作出说明。如果_domainkey存在,但所查询的所有名称都不存在,地图会说明选择器存在,但尝试过的名称一个也不是。 - 按 rcode 归为无:区域对每个不存在的名称都返回空响应(紧凑拒绝),因此该响应无法说明哪些内容存在。地图会查询完整列表,但不会声称任何内容不存在。
- 通配符:每个名称都会得到响应。地图会忽略通配符重复返回的内容,并查询完整列表。
- 未知:测试查询失败,因此不会从中读取任何信息,地图会将其列为未检查。
工作原理
所有信息都来自公开来源:DNS、证书透明度日志、域名自身的网站,以及网络所有者的公开记录。每项发现都会附上支持它的记录,方便你自行核查。
- SPF 会按树状结构遍历,只将实际授权发件人的链接计入结果。
- DKIM 密钥通过扫描服务使用的名称来查找,并根据这些名称指向的位置计入结果。许多主机都会使用的普通名称(例如
s1),只有在该域名的 SPF、MX 或 NS 委派记录已显示相应服务时,才会计入该服务(Klaviyo)。 - SPF 中的原始 IP 范围会通过与各服务公布的范围进行匹配来命名,然后再根据网络所有者确定归属。
- 发送子域名来自服务要求使用的名称和证书日志。通过 NS 委派给服务名称服务器的子域名(例如 Klaviyo 和 Salesforce Marketing Cloud 的设置),会计入该服务。
- 网站会显示其加载的脚本和样式表、提及的服务,以及其分处理商页面列出的服务。每次获取页面都会经过同一道防护:仅使用 HTTPS,并先检查主机地址,以免域名将获取请求指向私人或内部地址。被拒绝的获取请求会列为未检查。
- 证书透明度:每次生成映射时,都会读取 Cert Spotter 的日志来搜索子域名。使用
--ct(默认关闭)时,也会读取 crt.sh,因为它还包含已过期的证书;日志中记录的每个名称都会解析当前记录,并像任何 DNS 记录一样进行匹配,因此指向电子邮件平台的品牌追踪链接(例如link.example.com)也会显示出来。已不再解析、但仍指向某项服务的日志名称会列为可能的过往供应商,而不是当前发件方。crt.sh 通常响应较慢;系统会尝试三次,每个日志的响应会缓存一天。如果某个日志始终没有响应,则会列为未检查,映射仍会在不使用该日志的情况下完成。
通过命令行运行。它从 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
对于脚本和 Agent:成功生成映射时退出码为 0,输入无效时为 2,无法读取域名自身的记录时为 3(不会生成映射)。进度信息会输出到 stderr,且仅在终端中显示,因此 stdout 中只有映射内容。sendermap --help 会说明所有标志。
网站不会保留查询过的域名记录。
MCP
安装 mcp 扩展后,sendermap mcp 会通过 MCP 在标准输入输出上提供两个工具:sendermap_map,其结构化内容是 sendermap/1 JSON 格式的映射(摘要或完整内容);以及 sendermap_vendor,用于查看某个供应商的模式、证据和文档说明的设置方法。架构和供应商列表作为资源提供。
{
"mcpServers": {
"sendermap": { "command": "uvx", "args": ["--from", "sendermap[mcp]", "sendermap", "mcp"] }
}
}
网站也会在 /mcp 上通过可流式 HTTP 提供相同的工具。对于没有 MCP 的 Agent,skills/sendermap/SKILL.md 是一项 Agent 技能,可运行命令行并读取 JSON。
诚实说明局限
- 无法得知发送量。 公开记录能显示哪些服务已配置为可发送邮件,但无法显示每项服务发送了多少邮件,也无法确认本月是否发送过邮件。
- 无法证明密钥正在使用。 DNS 中的 DKIM 密钥只能证明它曾被发布,不能证明有任何内容使用它进行签名。只有实际邮件才能证明这一点,而 Sendermap 不会读取邮件。
- 无法看到使用供应商自有域名发送的邮件。 如果某项服务使用自己的域名向你的客户发送邮件(例如支付平台发送的收据),你的 DNS 中不会留下任何记录。
- 无法发现所有选择器。 DNS 无法列出 DKIM 选择器。Sendermap 会查询已知服务使用的名称和一些常见名称,并说明查询了多少个。使用任何其他名称的密钥都不会被发现。
- 根据区域的应答来判断记录缺失,并明确说明这一点。 只有在区域的否定应答类型能让结果可信时,才会断言“记录不存在”,而且每条此类说明都会附上作为依据的应答。
JSON 契约
sendermap DOMAIN --json 和网站的 API 会以 JSON 格式提供一张映射,架构为 sendermap/1,
详见 sendermap/data/schema/sendermap-1.json
(JSON Schema 2020-12;Python 中的 sendermap.schema(),网站上的 /schema/sendermap-1.json)。
sendermap/1 只会通过新增内容扩展:可能出现新字段和新值(例如新类型的证据、新类型的缺口),不会删除、重命名任何内容,也不会改变其含义。忽略你不认识的字段,并容忍你不认识的值。破坏性变更将使用 sendermap/2。
供应商数据
所有供应商信息都存放在一个文件 sendermap/data/vendors.json 中,每个服务占一个区块,因此添加或更正供应商只需提交一个小型拉取请求。首个版本从 dns-audit 的供应商表格导入(MIT)。
参与贡献
每个供应商在 sendermap/data/vendors.json 中都有一个区块,所有已知信息都放在其中。区块中的每种模式(SPF include、MX 主机、CNAME 目标、报告地址、验证令牌、网络、网站主机、选择器名称、子处理商名称)都必须有各自的证明:发布该模式的有效域名、发现该模式的记录名称或页面,以及检查日期(对于 s1、s2 这类编号选择器系列,只需提供一份系列证明)。没有证明的模式不会被合并,Sendermap 也会拒绝加载。区块还可以列出 aliases,即客户称呼该服务的其他名称(例如 Microsoft 365 的“Office 365”)。别名无需证明,因为它只匹配用户输入的内容,永远不会匹配记录。
尚未得到证明的模式会存放在 sendermap/data/vendors_pending.json 中,每个区块都附有已检查内容的说明;Sendermap 从不读取此文件,因此与这些模式匹配的记录会显示为无法识别。供应商按照每种模式一份证明的规则,从 pending 移至 vendors.json,这与新增区块的规则相同。tools/hunt_proofs.py 会在 data/hunt_domains.txt 中的客户域名上查找这些证明,检查方式与每周复查相同。
每周都会针对实时 DNS 和网站重新检查所有证明;任何涉及 vendors.json 的拉取请求也会触发重新检查。若证明不再成立,系统会创建 issue,以便发现并修正过时的模式。
添加 v* 标签会构建发布文件;如果仓库变量 PYPI_READY 为 true(Settings、Secrets and variables、Actions、Variables),则会通过可信发布将其发布到 PyPI,并使用 CHANGELOG.md 中该标签对应的说明创建 GitHub release。
相关链接
- dns-audit.com:对域名进行完整的电子邮件安全审计。
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。