8.5 内存传输与传输安全


文档摘要

8.5 内存传输与传输安全 本节摘要:第 8 章收尾节,讲两种特殊场景——内存传输(测试与嵌入用)与传输安全(公网部署的安全底线)。内存传输是 的底层机制,用直接分发代替读写流,跳过 JSON-RPC 序列化,极快零配置,是开发期验证的首选。传输安全则解决一个公网部署必须面对的威胁——DNS 重绑定攻击(DNS Rebinding),SDK 默认用防护机制只允许 localhost 连接,要公网暴露必须正确配置。读完本节,你掌握测试传输与公网安全两件事。 一、内存传输:测试与嵌入 内存传输是第 1.3 节 的底层机制。

8.5 内存传输与传输安全

本节摘要:第 8 章收尾节,讲两种特殊场景——内存传输(测试与嵌入用)与传输安全(公网部署的安全底线)。内存传输是 Client(mcp) 的底层机制,用直接分发代替读写流,跳过 JSON-RPC 序列化,极快零配置,是开发期验证的首选。传输安全则解决一个公网部署必须面对的威胁——DNS 重绑定攻击(DNS Rebinding),SDK 默认用防护机制只允许 localhost 连接,要公网暴露必须正确配置。读完本节,你掌握测试传输与公网安全两件事。

一、内存传输:测试与嵌入

内存传输是第 1.3 节 Client(mcp) 的底层机制。当客户端拿到一个服务端对象(而非 URL 或传输)时,它用内存传输连接——直接函数调用,无 JSON-RPC 序列化:

普通传输(stdio/HTTP): 客户端 ──序列化 JSON-RPC──► 服务端 客户端 ◄──反序列化────────── 服务端 内存传输: 客户端 ──直接函数调用──► 服务端 客户端 ◄──直接返回──────── 服务端 (无序列化、无帧)

内存传输用一种叫直接分发(Direct Dispatcher) 的机制——客户端的「发」函数直接调用服务端的「收」函数,中间没有序列化、没有 JSON-RPC 帧、没有网络。

二、内存传输的价值

内存传输的主要价值是测试与嵌入:

价值 说明
测试极速 无序列化开销,毫秒级,适合写大量测试
零配置 不用起子进程、不开端口,直接 Client(mcp)
进程内嵌入 把 MCP 服务端嵌入应用,客户端直连
确定性 无网络,不受网络抖动影响
# 测试场景(第 1.3 节的骨架) async with Client(mcp) as client: result = await client.call_tool("add", {"a": 1, "b": 2}) assert result.structured_content["result"] == 3

这就是全书所有示例的测试基础——内存连接让验证服务端行为极快、极简单。

三、内存传输的局限

内存传输不适合生产,因为它有几个固有局限:

局限 说明
必须同进程 客户端与服务端在同一 Python 进程
不跨机器 不能远程访问
无并发隔离 共享进程资源,无进程/网络隔离
非生产 设计目标就是测试/嵌入,不是生产

⚠️ 注意:内存传输只用于测试与进程内嵌入,不能用于生产。生产环境客户端与服务端通常分属不同进程(甚至不同机器),那时必须用 stdio 或流式 HTTP。但你的服务端业务代码不变——这是传输解耦的体现。

四、传输安全:DNS 重绑定威胁

讲完内存传输,转向传输安全。当流式 HTTP 服务端暴露到网络,一个必须面对的威胁是 DNS 重绑定(DNS Rebinding)攻击:

DNS 重绑定攻击(概念): 1. 攻击者控制一个域名,如 evil.com 2. 让受害者浏览器访问 evil.com 3. evil.com 的 DNS 第一次解析到攻击者服务器(正常页面) 4. DNS 第二次解析到 127.0.0.1(受害者本地!) 5. 浏览器的脚本 now 可访问受害者本地的服务(绕过同源策略)

这种攻击让恶意网页能访问受害者本地的服务(如你的 MCP 服务端)。如果你本地跑的 MCP 服务端没防护,恶意网页可能通过浏览器调用你的工具——读文件、执行操作。

五、SDK 的默认防护

SDK 用传输安全(transport_security)机制防护 DNS 重绑定——默认只允许 localhost 连接:

默认行为: 服务端监听 localhost 只接受来自 localhost 的连接 → 外部网络(含恶意网页)连不上 要公网暴露: 必须显式配置允许的主机(allowed hosts) → 明确放开,知道自己暴露了

这个默认是「安全优先」——宁可本地能用、公网连不上,也不要默认暴露。开发者要公网暴露时,必须显式配置,这一步强制你意识到「我在公开服务」。

六、配置公网暴露

如果你的 MCP 服务端要公网访问,必须正确配置传输安全:

mcp.run( "streamable-http", host="0.0.0.0", # 监听所有网卡 port=8000, transport_security={ "allowed_hosts": ["mcp.example.com"], # 允许的主机名 # 其他安全配置 } )

配置时的要点:

要点 说明
allowed_hosts 要精确 只列你实际使用的主机名,别用通配符
配合认证 公网暴露必须加认证(第 11 章 OAuth)
HTTPS 生产用 HTTPS,传输安全 + TLS 双保险
反代场景 如果在 nginx 后面,配置要考虑反代的 Host 头

⚠️ 注意:别为了「能连上」就关闭传输安全或用通配符 allowed_hosts。这等于把你的 MCP 服务端无保护暴露到公网——任何人都能调用你的工具。公网暴露的正确做法是:精确的 allowed_hosts + OAuth 认证 + HTTPS,三者缺一不可。

七、三种传输的安全特性对比

最后用一张表对比三种传输的安全特性,帮你选型:

传输 默认安全 暴露范围 需要认证吗
stdio 高(本地子进程) 仅本机宿主 通常不需要(宿主可信)
流式 HTTP 中(默认 localhost) 配置后可公网 公网必须(第 11 章)
内存 高(同进程) 仅本进程 不需要(无网络)

stdio 与内存因「不暴露到网络」,天然安全;流式 HTTP 一旦暴露到网络,就必须配传输安全 + 认证。

本节要点回顾

  1. 内存传输用直接分发,无 JSON-RPC 序列化,极快零配置。
  2. 价值:测试极速、零配置、进程内嵌入、确定性。
  3. 局限:必须同进程、不跨机器、无并发隔离,只用于测试/嵌入,不能生产
  4. DNS 重绑定威胁:恶意网页通过浏览器访问本地服务,绕过同源策略。
  5. SDK 默认防护:传输安全默认只允许 localhost,公网暴露要显式配置。
  6. 公网暴露配置:精确的 allowed_hosts + OAuth 认证 + HTTPS,三者缺一不可。
  7. 三种传输安全对比:stdio/内存高(不暴露),流式 HTTP 中(需配置)。

第 8 章结束。你已经掌握 MCP 的全部传输机制:抽象、stdio、流式 HTTP、SSE、内存、安全。第 9 章转向客户端主线——Client 如何连上这些传输。


发布者: 作者: 灏天文库 转发
评论区 (0)
U