跳转至

地理位置插件

内置的 geolocation 插件会将连接客户端的 IP 地址转换为粗略的城市。它随 OpenClaw 一起提供,首次使用时下载其数据库,并完全从该本地副本中应答,因此查询绝不会将地址发送到第三方。

它只负责一件事:将地址映射到地点。它不决定查询哪些地址,不存储结果,也不是授权输入。Control UI 使用它来标注某人 Activity 卡片上的设备。当 agent 请求 include: ["location"] 时,核心 presence 工具使用同一个查询所有者。

快速入门

插件默认内置并启用。要查看其效果,打开 Activity,选择一个人,并查看其设备行。远程客户端会显示其地址和解析出的城市:

openclaw-control-ui  MacIntel · 8.8.8.8 · Europe/Vienna  Mountain View, California ⓘ

全新安装后的首次视图在数据库下载期间不显示城市;数据库就绪后,该行会自动填充,无需重新加载。要直接检查插件:

curl -s "http://127.0.0.1:18789/plugins/geolocation/lookup?ip=8.8.8.8" -H "Authorization: Bearer <GATEWAY_TOKEN>"
{
  "found": true,
  "city": "Mountain View",
  "region": "California",
  "country": "United States",
  "countryCode": "US",
  "attribution": { "text": "IP Geolocation by DB-IP", "url": "https://db-ip.com" }
}

请使用一个实际可路由的地址。诸如 203.0.113.0/24 之类的保留范围不存在于数据库中,并返回 {"found": false}:

{
  "found": false,
  "attribution": { "text": "IP Geolocation by DB-IP", "url": "https://db-ip.com" }
}

首次调用也会下载数据库,因此可能需要最多一分钟,而后续调用会从本地副本应答。

Gateway 查询

具有 operator.read 的已认证调用者可以使用 geolocation.lookup 并传入 {"ips":["8.8.8.8"]}。一个请求最多接受 200 个 IPv4 或 IPv6 地址,并在 results 中为每个不同地址返回一个条目。每个条目包括 ip、status(found、not-found 或 unavailable)、可用的地点字段以及 attribution。

当请求位置时,presence 工具才会调用此方法。禁用插件或数据库故障时,在线状态和网络详情仍可用;位置会被报告为不可用。查询使用记录的连接 IP,从不请求 GPS,也不会将 IP 发送到外部服务。客户端时区仍然是单独报告的事实。

为什么某些客户端从不显示位置

位置只有在 Gateway 为该客户端记录了可用的公共地址时才会出现,而通常它并没有记录:

  • 连接处理会完全省略回环客户端的 ip,因此任何通过 SSH 隧道或本地端口转发到达 Gateway 的内容都没有可解析的地址。
  • Tailscale 客户端通过 100.64/10 运营商级 NAT 地址到达,LAN 客户端则通过私有地址到达。两者都会被记录并显示,但没有任何地理位置数据库包含它们,因此插件会针对这些范围返回 found: false,而完全不会加载数据库。因此,仅 tailnet 或仅 LAN 的 Gateway 永远不会下载数据库。
  • 移动运营商、VPN 和企业出口会解析到运营商的出口点,而不是个人。返回的结果往往是看似确定但错误,而不是缺失。

这就是为什么设备行还包含客户端报告的时区。无论浏览器如何到达 Gateway,它都知道自己的时区,因此 Europe/Vienna 恰好在地址不再具有信息量时继续有效。将城市视为提示,将时区视为更可靠的信号。参见 Presence 了解这两个字段如何生成。

配置

每个选项都是可选的。默认值是一套可用的配置。

选项 默认值 用途
databaseUrl 每月 DB-IP City Lite 构建 MMDB 来源。{yyyy} 和 {mm} 会展开为发布月份。
attributionText IP Geolocation by DB-IP 显示在每个结果旁边的署名。
attributionUrl https://db-ip.com 署名的链接目标。
refreshDays 30 缓存数据库在重新下载前允许过期多久。
{
  plugins: {
    entries: {
      geolocation: {
        config: {
          refreshDays: 7,
        },
      },
    },
  },
}

每月构建会在每月初几天后出现,因此插件会尝试当前月份,并回退到上一个月。无需月份替换的来源会按原样获取。

使用其他数据库

将 databaseUrl 与两个署名字段一起设置。署名归属于你所指向的数据集,因此更改来源而不更改署名会错误归属数据:

{
  plugins: {
    entries: {
      geolocation: {
        config: {
          databaseUrl: "https://example.internal/geoip/city.mmdb",
          attributionText: "IP data by Example",
          attributionUrl: "https://example.internal",
        },
      },
    },
  },
}

任何 MaxMind 格式的城市数据库都可以使用,包括自托管镜像或你已拥有许可的商业构建。缓存文件以来源 URL 命名,因此切换来源不会在新提供商的署名下提供旧提供商的数据。

数据许可

默认数据库是 DB-IP City Lite,采用 CC BY 4.0 许可。该许可要求署名,这就是为什么署名是每个响应的一部分,并渲染在值旁边,而不是隐藏在设置中。

OpenClaw 在运行时下载此数据库,并且从不重新分发它,因此许可附着在你的部署对数据的使用上,而不是 OpenClaw 本身。插件代码及其使用的 maxmind 读取器采用 MIT 许可。没有免费的市级 IP 数据库采用 MIT 许可;义务归属于数据本身。

预期城市级准确率在 55%-80% 之间,对于上述移动、VPN 和 CGNAT 情况会更差。

数据库如何管理

下载是惰性的且由需求驱动。它发生在对某个 公共 地址的首次授权查询时,例如打开某人的 Activity 视图,或要求 agent 提供带有位置详情的 presence。没有任何人检查的 Gateway —— 或者仅通过回环、隧道、局域网或 tailnet 访问的 Gateway —— 永远不会下载任何内容。

在首次符合条件的查询时,插件会将数据库获取到 <state-dir>/geolocation/,在发布前解析它,并一直保留到超过 refreshDays 的有效期。

有四种行为值得了解,因为它们决定了故障期间你会看到什么:

  • 响应会按压缩上限读取,并按磁盘上限解压,两者均在读取时强制执行。被替换的来源无法分配无界正文,压缩炸弹也无法解压超过限制。
  • 无法解析为 MMDB 的正文会被丢弃,而不会替换正在工作的数据库。限流页面或截断的下载不会破坏一分钟前还在正常工作的 Gateway。
  • 下载失败或数据库无效时,会提供缓存副本并记录警告。如果有效下载无法保存到磁盘,查询会从内存中使用它,并记录缓存写入失败。
  • 同一 Gateway 中并发的首次查询共享一次下载。不同 Gateway 独立暂存其下载,并在替换缓存前关闭完整文件,因此另一个 Gateway 永远不会读取部分写入的下载。

故障排查

任何设备行都没有位置。 要么 Gateway 未记录任何地址 —— 仅显示平台和时区的行没有 ip,对于回环和隧道客户端这是预期行为 —— 要么所有存在的地址都是私有地址或运营商级 NAT,插件会在不查询数据库的情况下回答。两种情况下都没有故障。

每次查询都返回 503。 数据库不可用 —— 仍在下载,或所有候选 URL 都失败。检查 Gateway 日志中的 geolocation: downloaded 或 geolocation database download failed 行,其中会列出它尝试过的每个 URL。没有出站网络访问的 Gateway 无法获取数据库;请将 databaseUrl 指向内部镜像。

found: false 回答。 数据库中没有该地址的条目。这是数据限制,不是故障。请注意,503 和 found: false 是刻意不同的:前者表示插件无法回答,后者表示数据库中没有该地址的位置。

城市错误。 确认该地址是此人的地址,而不是 VPN 或运营商出口。如果确实错误,DB-IP 接受更正,或者将 databaseUrl 指向覆盖范围更好的商业数据库。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw