DeepAI Paper Hermes Agent 教程,Hermes 安全、网络与代理 Hermes 代理后访问网页被 Blocked?198.18.0.0/15 Fake-IP 被当成私网的排查

Hermes 代理后访问网页被 Blocked?198.18.0.0/15 Fake-IP 被当成私网的排查

如果你在 Clash、Mihomo、Sing-box、Surge 这类代理工具里开启了 TUN / TProxy + Fake-IP,再用 Hermes Agent 的浏览器或网页抓取工具访问普通网站,可能会遇到:

Blocked: URL targets a private or internal address

奇怪的是,同一个网址用系统浏览器、curl 或普通客户端都能打开,只有 Hermes 的 browser_navigateweb_extract 等 URL 工具被拦。

这篇文章基于 NousResearch/hermes-agent issue #3777,解释为什么 RFC 2544 benchmark 网段 198.18.0.0/15 会被安全检查误判成 private address,以及 TUN Fake-IP 用户该如何在 SSRF 防护和可用性之间取平衡。


典型现象:普通网站被当成内网地址

复现环境通常长这样:

# Clash / Mihomo 类配置示意
tun:
  enable: true

dns:
  enhanced-mode: fake-ip

然后在 Hermes 里访问公开网站:

browser_navigate(url="https://www.baidu.com")
# 或 web_extract / web_search / browser_vision 等 URL 工具

结果不是网络超时,也不是 DNS 失败,而是直接被 URL safety 拦截:

Blocked: URL targets a private or internal address

这意味着请求还没真正走到代理隧道,就在 Hermes 的 SSRF 保护层被挡住了。


Fake-IP 是怎么工作的?

现代代理软件为了优化 DNS 和透明代理,常用 Fake-IP:

1. 应用查询 github.com; 2. 代理 DNS 返回一个虚拟 IP,例如 198.18.0.131; 3. 应用连接这个 Fake-IP; 4. TUN 接口捕获流量; 5. 代理根据映射表把流量转发到真实目标。

常见映射可能类似:

域名Fake-IP实际目标
www.baidu.com198.18.4.114公网网站,经代理转发
google.com198.18.2.84公网网站,经代理转发
github.com198.18.0.131公网网站,经代理转发

所以 198.18.x.x 不是用户真的想访问某台内网服务器,而是本机代理栈里的“临时路标”。


为什么 Hermes 会拦?

issue 指向 Hermes 的 URL 安全检查逻辑:

if ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved:
    return True

而 Python 的 ipaddress198.18.0.0/15 的判断会让人踩坑:

import ipaddress
ip = ipaddress.ip_address("198.18.4.114")
print(ip.is_private)   # True
print(ip.is_reserved)  # False
print(ip.is_global)    # False

RFC 2544 把 198.18.0.0/15 定义为 benchmarking test range,不是传统意义上的 RFC1918 私网:

10.0.0.0/8
172.16.0.0/12
192.168.0.0/16

但 URL safety 层只看到 ip.is_private=True,于是把它当成内网风险拦掉。


这为什么会影响很多中国用户?

Clash / Mihomo / Clash Verge Rev / Sing-box / Surge 用户中,TUN + Fake-IP 是很常见的模式,尤其在需要透明代理、系统级代理或复杂分流规则时。

这类用户的 DNS 结果经常是 198.18.0.0/15

因此受影响的不只是一个网站,而是所有依赖 URL 安全检查的工具:

  • browser_navigate
  • web_extract
  • web_search
  • 浏览器相关截图/视觉工具
  • 远程附件或媒体下载路径
  • 其他复用 url_safety 的平台 adapter

issue 评论里也明确补充:这不只是 browser navigation,web_extract 也会在 Fake-IP DNS 下触发同样误拦。


安全难点:不能简单把所有 private URL 放开

有人会说:既然拦错了,那直接允许 private URL 不就行了?

Hermes 后续提供了全局开关:

security:
  allow_private_urls: true

或者通过环境变量类似:

HERMES_ALLOW_PRIVATE_URLS=true

但这类开关必须谨慎。

SSRF 防护的意义,是阻止工具访问:

  • 127.0.0.1
  • localhost
  • 192.168.0.0/16
  • 10.0.0.0/8
  • 169.254.169.254 云 metadata
  • 内网管理面板
  • link-local / loopback / multicast 等敏感地址

如果全局放开 private URL,确实能让 Fake-IP 通过,但也扩大了攻击面。

所以它更适合作为“我知道当前运行环境风险,并且需要可用性”的显式运维开关,而不是默认行为。


更细的方案:只信任 TUN Fake-IP CIDR

评论中有人提出更窄的配置思路:

browser:
  allow_private_urls: false
  trusted_tun_cidrs:
    - 198.18.0.0/15

设计思路是:

  • 默认仍然阻止 private URL;
  • 只在特定工具路径(例如 browser)允许特定 CIDR;
  • 192.168.1.10127.0.0.1169.254.169.254 仍然阻止;
  • pre-navigation 和 post-redirect SSRF 检查都要传入该 allowlist;
  • 避免把 198.18.0.0/15 全局当成安全。

这比粗暴开 allow_private_urls: true 更符合最小权限原则。

不过维护者后来指出,合并的处理路径是 security.allow_private_urls 全局 toggle,并让多个 URL call sites 继承该开关,同时保留对云 metadata 地址的特殊保护。


另一个坑:不要随便改 Fake-IP 到 28.0.0.0/8

issue 里有人问:把 Fake-IP range 改成 28.0.0.0/8 安全吗?

这个问题很关键。28.0.0.0/8 并不是给你本地随便用的私有网段,它属于真实分配地址空间。随便把 Fake-IP 池改到真实公网段,可能制造更诡异的路由冲突。

因此优先级通常是:

1. 用代理软件默认推荐的 Fake-IP 池; 2. 在应用侧配置明确的安全例外; 3. 不要随意占用真实公网地址段做假 IP 池。


排查步骤:确认是不是 Fake-IP 误拦

1. 看 DNS 解析结果

在受影响环境里确认目标域名是否解析到:

198.18.x.x
198.19.x.x

只要落在:

198.18.0.0/15

就符合 RFC 2544 benchmark range。

2. 对比普通客户端

如果:

  • 系统浏览器能打开;
  • curl 能打开;
  • 但 Hermes URL 工具被 Blocked: URL targets a private or internal address 拦;

那就更像 SSRF 检查误拦,而不是网站不可达。

3. 检查代理模式

重点看:

  • TUN 是否开启;
  • TProxy 是否开启;
  • DNS 是否是 fake-ip/enhanced-mode;
  • Fake-IP 池是否使用 198.18.0.0/15

4. 选择 workaround

短期可以考虑:

  • 关闭 TUN,改用 HTTP/HTTPS proxy 环境变量;
  • 关闭 Fake-IP,改 real-ip 模式;
  • 显式启用 security.allow_private_urls,但理解 SSRF 风险;
  • 等待或使用更细粒度的 trusted CIDR 配置方案。

和 DeepAI API 中转站的关系

DeepAI API 中转站常见配置是:

Base URL: https://api.deepai.wang/v1
API Key: 你的 DeepAI Key
Model: 以 DeepAI 控制台为准

但本文问题不在模型 API,而在 Hermes 的 URL 工具访问外部网页时,被 SSRF 防护提前拦截。

如果你的任务是让 Hermes 调用 DeepAI 模型,通常不会触发这个 Fake-IP URL safety 问题;但如果你让 Hermes 同时使用浏览器、网页提取、搜索或远程媒体下载,就可能遇到。

分层判断:

  • 模型调用失败:看 DeepAI / OpenAI-compatible API 日志;
  • 网页访问被 Blocked:看 URL safety / SSRF / DNS Fake-IP;
  • 代理可用但工具不可用:看 Hermes 是否把 Fake-IP 当成 private。

FAQ

198.18.0.0/15 是私网吗?

它是 RFC 2544 benchmarking test range,不是 RFC1918 私网,但 Python ipaddress.is_private 会把它归为 True,导致安全检查容易误拦。

为什么浏览器能打开,Hermes 不行?

浏览器请求会走 TUN 代理映射;Hermes 在请求前做 SSRF 检查,DNS 解析到 Fake-IP 后就提前拦掉了。

直接开 security.allow_private_urls: true 安全吗?

能解决可用性,但会扩大 SSRF 风险。只应在你理解运行环境和信任调用者时启用。

更推荐的方案是什么?

理想上是 scoped allowlist,例如只允许 198.18.0.0/15 作为 TUN Fake-IP,并保留对 loopback、link-local、云 metadata 的拦截。

DeepAI API 中转站会受影响吗?

模型 API 本身通常不受这个问题影响;受影响的是 Hermes 的网页访问、浏览器、抓取等 URL 工具路径。


总结

Hermes 在 TUN + Fake-IP 代理环境下访问普通网站时报:

Blocked: URL targets a private or internal address

核心原因通常是:域名被代理 DNS 解析到 198.18.0.0/15,而 URL safety 把该 benchmark range 当成 private/internal address 拦截。

一句话:这不是网站真的在内网,而是 Fake-IP 与 SSRF 防护的边界冲突;修复时要兼顾代理可用性和内网访问安全。

Related Post

你明明发过,session_search 却说没见过:Hermes 记忆检索少了哪一块你明明发过,session_search 却说没见过:Hermes 记忆检索少了哪一块

Hermes session_search 能搜到 messages.content,却搜不到 tool_calls 和 tool_name。本文复盘 #16751:为什么工具参数、函数名和工具轨迹明明存进数据库,却在 FTS 检索里消失,以及该如何修复索引结构。

Hermes 多模态排错:image_url 发给非视觉模型为什么会 400?Hermes 多模态排错:image_url 发给非视觉模型为什么会 400?

Hermes 接入 OpenAI-compatible API 时,图片消息会变成 image_url content part。如果当前模型不是 vision model,就可能返回 HTTP 400。本文基于 Hermes PR #23750 讲清 non-vision model、多模态和 DeepAI 接入排错。

Kimi for Coding 报 invalid temperature?Hermes Agent 接入固定参数模型的排错指南Kimi for Coding 报 invalid temperature?Hermes Agent 接入固定参数模型的排错指南

Hermes Agent 接入 Kimi for Coding 报 HTTP 400 invalid temperature: only 0.6 is allowed?这通常不是 API Key 错,而是模型固定参数契约没有覆盖主聊天、summary、memory flush、auxiliary client 等所有调用路径。本文总结 Kimi temperature 0.6 的正确排查方式。