2026年6月

从 BGP 到街道:一个 IP 归属地地理库到底是怎么建出来的

从 BGP 到街道:一个 IP 归属地地理库到底是怎么建出来的

很多人对 IP 定位有个朴素的想象:既然每个 IP 都唯一,那查一下它在哪儿,应该像查身份证一样简单。等真要动手建一个 IP 归属地地理库,才会发现这件事远比想象的拧巴——而拧巴的根源,是把两件本质不同的东西混为了一谈。

这篇文章想把这件事讲透:一个能用的 IP 地理库,到底由哪些部分组成、每一层用什么方法、精度的天花板在哪里,以及哪些"街道级"其实是虚假精度。

第一性原理:路由身份 ≠ 物理位置

先立一个贯穿全文的认知:IP 的"路由身份"和"物理位置"是两个维度,必须解耦。

BGP 路由表告诉你的是"这个前缀由哪个 AS 宣告、经哪些 AS 可达"——这是逻辑的、三层的。一个 AS(自治系统)是一个统一路由策略下的管理实体,它跟地理没有必然关系:一个 AS 可以横跨几十个国家,一栋机房里也可以挤着好几个 AS。所以"这个 IP 属于哪个 AS"回答的是"谁在路由它",而不是"它在哪"。

更要命的是,一个被宣告的 CIDR 前缀不等于一个物理位置。运营商常把地理分散的小块聚合成一个大前缀宣告;一个 /16 可能服务一整个省、成千上万个互相隔离的局域网。哪怕是一个 /24(256 个地址),里面的地址也可能散在不同城市——这不是理论,而是经典算法 GeoCluster 真实遇到的情况:一个 /24 里 10 个 IP 在西雅图、1 个在波士顿。

所以物理位置是一份单独的事实,必须靠地理库或网络测量得到,而不能从"哪个 AS 宣告了它"反推。理解了这一点,整个地理库的架构就顺了:BGP 给骨架,别的方法给血肉。

地基:BGP/RIB 能做什么,不能做什么

虽然 BGP 给不了精确位置,但它是地理库不可或缺的地基。从公共采集点(RouteViews、RIPE RIS)的 RIB dump 里,你能拿到全球真实在路由的前缀全集 + 每个前缀的源 AS。这有几个关键作用:

  • 提供"行"的单元。地理库本质是一张"前缀 → 位置"的表;用 BGP 里实际宣告的前缀当行,而不是凭空切块,保证和真实网络一致、能按最长前缀匹配查询。
  • 源 AS → 机构和类型。把源 AS 映射到运营商名和类型(家宽 / IDC / 移动 / 云 / CDN),这决定了"该用什么策略去定位"——家宽和机房的定位逻辑完全不同。同时 AS 的注册国家给了一个国家级锚点。
  • anycast 检测。一个前缀若被多个源 AS、从分散位置宣告,就该标记为 anycast——这种前缀没有"一个位置",任何定位尝试都是错的。
  • 过滤与保鲜。BGP 告诉你哪些地址实际在用,变更 feed 还能在前缀拆分、源 AS 改变时提示你"该重新核对位置了"。

但 BGP 的天花板,大致就是国家级。想到城市、街道,得换方法。

方法分层:从国家到街道

真正决定精度的,是叠在前缀之上的地理信号。按精度从低到高,方法是这样的:

国家级:免费的兜底

RIR 委派数据whois 注册信息,免费,只能到国家级(whois 偶尔到省)。它们的价值是兜底——保证再差也有个国家。注意这是"注册/分配"国家,不一定等于实际使用地,所以连国家级都可能错,只能当下限。

城市级:务实的主战场

这一层有四类方法,组合起来能稳到城市:

1. 商业地理库(务实主力)。 MaxMind、IP2Location,以及国内城市级最准的 ipdb 等。它们已经替你做完了测量和挖掘,直接给"前缀 → 城市"。对绝大多数自建者,这应该是城市级基线——买,而不是重复造轮子

2. rDNS 主机名挖掘。 很多运营商基础设施的反向 DNS 名里藏着城市码或机场码,比如路由器名里的 sjc 指向圣何塞。批量解析这些 PTR 记录,对 IDC 和骨干设施很有效;但对家宽用户 IP 基本无用。

3. 接入边缘 / BRAS 锚定(家宽的正解)。 这是个聪明的反转。家宽用户 IP 又动又散,直接定位很难;但用户前面的接入设施(BRAS、城域网核心、OLT 局端)是物理固定在某个城市机房里的,而且用户挂在本地城域网下,所以接入边缘的城市 ≈ 用户的城市。做法是:先把"接入设施 IP → 城市"这层地标建准(traceroute 采中间跳 + rDNS + 测量 + 商业库交叉),之后给海量用户定位,只是查"它在哪个接入边缘后面"。这把"定位百万移动目标"降维成"定位少数稳定接入点再传导",能稳到城市级。

唯一要警惕的是 BRAS 集中化:运营商把接入设备集中云化后,接入边缘可能远离用户(整省几个点),这时要识别出来、降级到省级,别硬标城市。

4. 时延测量 + 基准点。 也就是 CBG / TBG 这类算法,适合做区域定位和交叉验证。这一类的原理值得单独说,因为它常被误解。

测量的真相:延迟给的是"上界",不是距离

有人会问:网络速度不固定,延迟会被排队、绕路、抖动污染,怎么可能从延迟测出距离?

问得对——确实测不出精确距离。但测量定位根本不求精确距离,它求的是距离的上界。延迟里所有的污染因素只会让延迟变大,永远不会让它小于光在光纤里走直线的时间。于是反过来:一个测到的 RTT,对应一个最大可能距离(光在光纤里约 200 km/ms,RTT 每毫秒对应约 100 km 的半径上界)。目标"不可能比这更远"。

有了上界,再用几招收紧:多个位置已知的基准点各给一个上界圆,目标在所有圆的交集里(基准点越多交集越小);就近基准点约束最紧;多次测量取最小值滤掉瞬时拥塞;概率模型(Spotter 等)直接从数据里学"延迟-距离"的真实分布,而不假设线性。最终得到的是一个带概率的区域,不是一个确定的距离值。精度由基准点的密度和邻近度决定——这也是为什么城区准、偏远差。

街道级:本质是地面真值工程

这是天花板,也是虚假精度的重灾区。要说一句实话:纯网络测量基本到不了家宽的街道级——末跳接入延迟的噪声比街道尺度的信号还大,基准点也不可能密到每条街。能到街道级的,几乎都靠地面真值数据:

  • 众包 GPS-IP 配对:在用户授权下,通过 App 采集「精确 GPS + 当前公网 IP」,汇聚成质心。这是端用户街道级唯一可规模化的途径,也是准确商业库的真正底牌。需要 App 触达和严格合规。
  • 应用层地址数据:自有业务里"收货地址 + 当时 IP"的配对,很强,但仅自有数据可用,且隐私敏感。
  • 机房设施识别:对服务器类 IP,通过 rDNS、已知 DC 地址段、PeeringDB 里登记的设施地址,把服务器映射到具体机房 → 楼/街道级。这是对 IDC 很实用的一条正经路径。

对家宽,如果拿不到真值,就老实停在城市级,不要堆一个看着像样、实则是猜测的"街道地址"

位置会"静默漂移"

还有一个容易被忽略的坑:即便前缀和源 AS 都不变,地址实际落在哪个机房也会变——地址重分配、VM 迁移、运营商换服务机房、地址租赁转让……这些里最危险的一种,是"运营商仍用同一个 AS 宣告同一前缀,只是把服务机房换了":RIB 行纹丝不动,地理数据却悄悄过期了,你从路由上完全察觉不到。

结论是:地理层必须独立、持续地刷新,不能假设"RIB 没变 = 位置没变"。靠 rDNS 变化、时延突变、whois 更新等信号触发重核。

数据模型:把"稳"和"流动"分开存

这些认知直接决定了表结构。核心是把路由身份(稳)物理位置(流动、可切分、带时间戳)分两层:

  • prefix:路由锚点(前缀 → 源 AS),来自 RIB,变化慢,当行索引。
  • asn:分类器(机构 + 类型 + 注册国),决定定位策略和国家兜底。
  • geo_segment:物理位置层。一个前缀下可挂多条——这就天然支持"一个前缀跨多机房",每条带 source / confidence / measured_at,可独立刷新、可被取代。
  • geo_resolved:把 geo_segment 按精度和置信度合并成不重叠区间,运行时只查它,单条命中最快。
  • change_log:记录 RIB 变更和探测异常,驱动地理层重核。

实现上,IP 统一按 16 字节存(IPv4 映射成 ::ffff: 形式),用区间做最长匹配。每条地理判定都带置信度和时间戳——位置是会变的事实,不是和前缀绑死的常量

务实的建库蓝图

把方法串成一条可执行的路径:

  1. 底座:RIB → prefix + asn(用 pyasn 等把"前缀 → AS"建起来)。
  2. 分类:判 AS 类型,不同类型走不同策略。
  3. 兜底:RIR 国家级全量铺满,保证有下限。
  4. 打底:商业库铺城市级基线(买,不重复造)。
  5. 精修家宽:rDNS + 接入边缘锚定,把家宽提到城市级。
  6. 验证:主动测量交叉核对商业库、精修城区,顺带抓"静默漂移"。
  7. 冲街道:在能拿到真值的地方(自有 App 众包、自有业务地址、服务器设施识别)做街道级。
  8. 合并 + 保鲜:压成 geo_resolved,全程带置信度和时间戳,持续刷新。

你会发现,BGP/AS 主要出现在 1、2 和切分、anycast、刷新这些结构性步骤;真正决定精度的地理信号层,BGP 完全帮不上,得靠商业库、挖掘、测量和真值。

诚实的天花板

最后留几句最该记住的:

  • 精度现实:国家级准确率约 99.9%,城市级约 70%,街道级靠地面真值,且市场充斥虚假精度。
  • 一个前缀 ≠ 一个位置:要按地理把前缀切开;anycast 不定位,只标记。
  • 反对假精度:没有真值支撑的"街道级"宁可降级到城市,也不要堆一个唬人的门牌号。
  • 分工铭记:BGP 给骨架(谁路由、国家级),四类方法给血肉(城市→街道),测量是"带不确定性的区域",真值才是街道级的来源。

一个好的 IP 地理库,不是某个神奇算法的产物,而是用 BGP 当稳定骨架、用多源信号当血肉、用置信度和时间戳兜住诚实的一套工程。把路由和位置分清楚,把"测得到的"和"猜出来的"分清楚——这是这件事最难、也最重要的地方。