Old-School Networking / 2026 ・ No.05
古法网络入门
第5讲 路由器 ── 路由表与 TTL、traceroute,以及“家用路由器”的真面目
发布
第 4 讲讲到:目的地如果是“外面的网络”,就交给路由器。这一讲看看接手的路由器在做什么。
我们搭一个有 4 台路由器的练习网络,读路由表,用 traceroute 查路径,再故意把路连成环,让包迷路。
后半讲家里那个叫“路由器”的盒子的真面目(NAT),以及全世界的网络互相告知路径的机制(BGP)。
指路的这一层
新井路由器,就是家里那个长着天线的白盒子吧?灯一闪一闪的那个。
古井那也是路由器,不过那个盒子里塞了大约 7 种工作。真正属于路由器的只有其中 1 种。
新井诶,那剩下 6 种在干什么?
古井留到后半讲。先看本职工作:指路。我摆了 4 台路由器。
全 12 讲路线图(当前:第 5 讲)
- 路由器的工作 ── 收下、查表、减 TTL、交给下一站
- 路由表与 traceroute ── 匹配最长的那一行,寿命 TTL 与查路径的方法(实测)
- ICMP ── “超时”“没有到该目的地的路”这类通知
- 家用路由器 ── 用 NAT 改写地址。去掉它、从外面进来会怎样(实测)
- 互联网 ── AS 与 BGP,约 107 万条路由
这一讲的练习网络是一条直路:从家(新井的电脑和家用路由器 r1)出发,经过运营商的 r2、中转的 r3、数据中心的 r4,到达接收申请的服务器。地址从第 4 讲的 10.0.x.x 换成了更像家里的 192.168.1.10。
练习用的路:4 台路由器,5 个网络
路由器的工作
路由器是同时站在两个以上网络上的机器。以图中的 r2 为例,它在左边的网络(198.51.100.0/30)里是 198.51.100.1,在右边的网络(198.51.100.4/30)里是 198.51.100.5,有两个地址。路由器收到包后,每次做的事都一样。
- 收下发给自己 MAC 的帧,拆开第 2 层的信封(第 3 讲)。
- 只看里面 IP 头部的目的地址。不看源地址。
- 查路由表,决定下一站交给谁、从哪条腿出去。
- 把头部的 TTL 减 1。变成 0 就丢弃,并通知发送方。
- 用 ARP 查下一站的 MAC,装进新的信封发出去。
每一段,信封(MAC)都会换掉,里面的目的地(IP)一直不变。第 3 讲说“MAC 管到隔壁,IP 管到终点”,正是因为路由器在做这件事。
路由器不在乎包是从哪里来的。看目的地,交给下一站,仅此而已。这一点在后面讲家用路由器时会派上用场。
路由表
新井路由表,是像电话簿那样,登记着全世界所有地址的东西吗?
古井家用路由器的只有 3 行。看看吧。
# 家用路由器 r1:不认识的目的地全部交给运营商(198.51.100.1)
r1$ ip route
default via 198.51.100.1 dev wan0
192.168.1.0/24 dev lan0
198.51.100.0/30 dev wan0
# 运营商的 r2:没有默认路由,只认识 3 条
r2$ ip route
198.51.100.0/30 dev e0
198.51.100.4/30 dev e1
203.0.113.0/24 via 198.51.100.6 dev e1
# 数据中心的 r4:自己 LAN 以外的全部交给 r3
r4$ ip route
default via 198.51.100.9 dev e0
198.51.100.8/30 dev e0
203.0.113.0/24 dev e1
一行就是一条指路。读法只有 3 种。
| 写法 | 含义 | 例子 |
|---|---|---|
| … dev 接口 | 自己直接连着的网络。用 ARP 找到对方直接交付 | 192.168.1.0/24 dev lan0 |
| … via 地址 | 去这个网络,交给这个地址的路由器 | 203.0.113.0/24 via 198.51.100.6 |
| default via 地址 | 哪行都不符合时,交给这里(0.0.0.0/0) | default via 198.51.100.1 |
家用路由器 r1 只认识家里(192.168.1.0/24)和它与运营商之间的小网络。其余全是 default,也就是“不知道就交给运营商”。这和第 4 讲电脑的“默认网关”是同一个思路,大多数机器有这些就够了。
运营商的 r2 没有 default。运营商核心的路由器对全世界每个网络都各有一条路,没有“不知道就交给谁”的对象(第八章)。练习用的 r2 只认识 3 行。
使用匹配最长的那一行
目的地同时符合两行以上时,用哪一行?在 r2 上加一条粗略的 203.0.0.0/8 来试试。
203.0.113.20 用哪一行发送
# 在 r2 上加一条粗略的路由 203.0.0.0/8
r2$ ip route add 203.0.0.0/8 via 198.51.100.6
# 203.0.113.20 同时符合 /8 和 /24 → 选择更长的 /24(下一跳相同,结果一样)
r2$ ip route get 203.0.113.20
203.0.113.20 via 198.51.100.6 dev e1 src 198.51.100.5 uid 0
r2$ ip route get 203.0.9.9
203.0.9.9 via 198.51.100.6 dev e1 src 198.51.100.5 uid 0
# 8.8.8.8 哪条都不符合,也没有默认路由 → 发不出去
r2$ ip route get 8.8.8.8
RTNETLINK answers: Network is unreachable
203.0.113.20 不管按前 8 位还是前 24 位看都符合。这时路由器选择匹配最长的那一行(最长前缀匹配,longest prefix match)。匹配得越长,指路就越具体。default 是长度为 0 的行,即“什么都符合,但优先级最低的行”。哪行都不符合的 8.8.8.8,因为 Network is unreachable(没有到该目的地的路)而发不出去。
在这个练习里,路由表是笔者手写的(静态路由)。公司和运营商的路由器会和相邻的路由器互相告知路径,自动生成路由表(路由协议。对外用第八章的 BGP,内部用 OSPF 等)。
traceroute 与 TTL
IP 头部里有一个 8 位的数,叫 TTL(Time To Live,寿命)。发送时从 64 之类的值开始,每经过一台路由器减 1,变成 0 就被丢弃。在服务器上接收 ping,到达时的 TTL 是 60。从 64 开始,经过 4 台路由器减了 4。
反过来利用这个寿命查路径的,就是 traceroute。
把 TTL 每次加 1 发出去
# 从新井的电脑到数据中心服务器的路径
$ traceroute -n -q 1 203.0.113.20
traceroute to 203.0.113.20 (203.0.113.20), 30 hops max, 60 byte packets
1 192.168.1.1 0.070 ms
2 198.51.100.1 0.046 ms
3 198.51.100.6 0.042 ms
4 198.51.100.10 0.038 ms
5 203.0.113.20 0.040 ms
# 越过 4 台路由器,第 5 跳到达服务器
TTL 为 1 的包在第一台路由器寿命耗尽,那台路由器会发回“超时(Time exceeded)”。发送者就是第 1 台路由器的地址。TTL 2 就是第 2 台……这样增加下去,最后到达对方。Linux 的 traceroute 发往看起来没人用的 UDP 端口(从 33434 开始),所以对方会回“该端口未使用”,由此得知“到了”。
封面的照片就是这时的记录。“超时”通知里原样装着寿命耗尽的原包的头部,发送方可以对照出这是哪个包的通知。
显示的是路由器朝向我们这一侧的接口的地址。r2 显示的是 198.51.100.1,而不是 198.51.100.5。另外,设置为不回通知的路由器会显示为 * * *,并不一定是路在那里断了。Windows 的 tracert 不用 UDP,而是用 ping(ICMP)。
路连成环时
新井寿命到底有什么用?只要指路正确,好像用不着。
古井指路有时会出错。让它错一次看看。
r2 把 203.0.113.0/24 交给 r3。我们故意把 r3 的这一行指回 r2。于是包就在 r2 和 r3 之间来回跑。
# 故意把 r3 的 203.0.113.0/24 指向 r2(r2 仍指向 r3),形成环
r3$ ip route replace 203.0.113.0/24 via 198.51.100.5
pc$ ping -c 1 203.0.113.20
From 198.51.100.1 icmp_seq=1 Time to live exceeded
# 数一数 r2 和 r3 之间的线,一次 ping 去 31 次、回 31 次
r2 e1 tx 31 rx 31 (tcpdump 62)
电脑发出的 ping,在 r1 和 r2 各减 1,以 62 进入 r2 与 r3 之间。之后每往返一次减 2,第 62 个时 TTL 变成 1,被丢弃,r2 发回了“超时”。整个过程只有 0.085 毫秒。如果没有 TTL,这个包会在线上永远转下去,进入环的包越多,线路就越堵。
这和第 3 讲交换机的环路(广播风暴)很像。不过第 2 层的帧没有寿命,所以要用 STP 把环本身切断。第 3 层有 TTL,即使出现了环,包最终也会消失。
ICMP 的通知
“超时”“该端口未使用”都是 ICMP(Internet Control Message Protocol)的通知,专为 IP 服务。ping 也是其中之一,由“请回复(Echo request)”和“好的(Echo reply)”组成。我们在练习网络里收集了出错时的通知。
# 发往无路可走的目的地:运营商的 r2 回复“没有到该目的地的路”
pc$ ping -c 1 8.8.8.8
From 198.51.100.1 icmp_seq=1 Destination Net Unreachable
# 从外面(服务器)到家里的 192.168.1.10:在途中的 r3 停下
srv$ ping -c 1 192.168.1.10
From 198.51.100.9 icmp_seq=1 Destination Net Unreachable
# 从外面到家用路由器的地址 198.51.100.2:没有在监听的东西
srv$ curl http://198.51.100.2:3000/
Failed to connect to 198.51.100.2 port 3000 after 0 ms: Couldn't connect to server
| 类型 | 含义 | 什么时候 |
|---|---|---|
| Echo request / reply | 请回复/好的 | ping |
| Time exceeded | 寿命耗尽 | traceroute、路由环路 |
| Net unreachable | 没有到该目的地的路 | 路由表里没有对应的行 |
| Port unreachable | 该端口未使用 | UDP 的目的端口没人(第 7 讲) |
| Fragmentation needed | 太大,过不去 | 途中的 MTU 较小(第 2 讲) |
ICMP 经常被公司或云的防火墙拦住。ping 不通,网页却能打开,这并不少见。不要只凭 ping 不通就断定“连不上”(第 12 讲)。
家用路由器的真面目
叫作“家用路由器”的盒子里装着什么
家里那个盒子,是在本来的路由器上塞进了交换机(第 3 讲)、Wi-Fi 主机(第 2 讲)、DHCP(第 4 讲)、DNS 中继(第 9 讲)等等。其中,让家里的机器能出去的,是 NAT(Network Address Translation,地址转换)。
出去时改写源地址
家里电脑的地址 192.168.1.10 是私有地址(第 4 讲)。全世界的家庭都在用同样的 192.168.1.10,所以外面的路由器不知道去这个地址的路。于是家用路由器把出去的包的源地址改写为自己外侧的地址 198.51.100.2,并把对应关系记在表里。回复会到达 198.51.100.2,再查表换回 192.168.1.10。申请顺利送达,返回了 201。
# 家用路由器记住的“转换表”(conntrack)
r1$ conntrack -L -p tcp
tcp 6 119 TIME_WAIT src=192.168.1.10 dst=203.0.113.20 sport=40418 dport=3000
src=203.0.113.20 dst=198.51.100.2 sport=3000 dport=40418 [ASSURED]
# 去程:192.168.1.10 → 203.0.113.20 / 回程:203.0.113.20 → 198.51.100.2(再换回 192.168.1.10)
表里不仅有地址,还有 40418、3000 这样的编号(端口)。家里好几台机器同时与外面往来,也能靠编号区分,正确地送回对应的机器(这次端口没变,冲突时路由器也会改端口)。这个编号的真身,是下一讲的 TCP。
去掉 NAT 会怎样
# 去掉家用路由器的 NAT,再 ping 一次
pc$ ping -c 3 203.0.113.20
3 packets transmitted, 0 received, 100% packet loss
# 服务器一侧的记录:请求到了,也回复了,但回复在 r3(198.51.100.9)被告知“没有到该目的地的路”
192.168.1.10 -> 203.0.113.20 Echo (ping) request seq=1/256, ttl=60
203.0.113.20 -> 192.168.1.10 Echo (ping) reply seq=1/256, ttl=64
198.51.100.9 -> 203.0.113.20 Destination unreachable (Network unreachable)
去掉 NAT 后,ping 全军覆没。看服务器一侧的记录,出乎意料的是,请求(ping)到了,服务器也回复了。路由器只看目的地,所以即使源地址是 192.168,去程也照样被送达。可是回复的目的地是 192.168.1.10,r3 不知道去这个地址的路,便以“没有到该目的地的路”丢弃了。去程到了、回程迷路,这就是没有 NAT 的家。
外面进不来
上一章 ICMP 记录里的第 2 和第 3 条,就是从外面(服务器)试图进入家里。发往 192.168.1.10 的,在途中的 r3 无路可走;发往家用路由器地址 198.51.100.2 的,只到达路由器自身,没有表告诉它该交给里面哪台机器。NAT 的家,外面没法主动搭话。这对防御来说很方便,大多数家用路由器还会再用防火墙挡住来自外面的连接。
想让外面看到家里正在开发的服务器,可以设置把固定端口指向内部机器的端口转发(端口映射),或者使用从内部保持向外连接、借用外部入口的隧道服务(第 11 讲)。如果运营商那边又做了一层 NAT(CGNAT,第 4 讲的 100.64.0.0/10),连端口转发也做不了。
互联网是怎样连起来的
新井r2 只认识 3 行,是因为这是练习吧。真正的运营商大概认识多少行?
古井2026 年 7 月底,1,065,956 行。
新井……还真是电话簿。
互联网是运营商、云、大学、大公司等各自按自己的方针运营的网络的集合。每一个这样的网络叫作 AS(Autonomous System,自治系统),都有编号(AS 号)。AS 之间用 BGP(Border Gateway Protocol)互相告知“这一块地址在我这边”。
AS 之间互相告知路径(编号是为说明而保留的)
数据中心通告“203.0.113.0/24 在我这里”后,中转把自己的 AS 号加在前面,再告诉运营商。运营商从收到的多条路径中,根据方针(费用、合同)和经过的 AS 数选出一条,放进路由表。如果编号序列里有自己就不接收,所以 AS 之间不容易形成环。
| 数字(2026 年 7 月 31 日统计) | 值 |
|---|---|
| 全球 BGP 路由表的行数(IPv4) | 1,065,956 |
| 路由表中出现的 AS 数 | 78,975 |
| 练习用 r2 的行数 | 3 |
AS 之间有的直接拉线相连,有的在 IX(互联网交换中心)这种很多 AS 聚在一起互相连线的地方相连。BGP 是相信对方申报的机制,所以有人通告了错误的路径,影响会传得很远。2021 年 10 月 Facebook 数小时无法访问,就是因为维护操作的命令切断了自家的骨干网,DNS 服务器察觉后用 BGP 撤回了通往自己的路,全世界都查不到 Facebook 的域名了。
在自己的电脑上确认
| 想查的内容 | Mac | Windows | Linux |
|---|---|---|---|
| 路径 | traceroute 目的地 | tracert 目的地 | traceroute 目的地 |
| 自己的路由表 | netstat -rn | route print | ip route |
| 这个目的地用哪一行 | route get 目的地 | Find-NetRoute -RemoteIPAddress 目的地 | ip route get 目的地 |
| 能否到达 | ping 目的地 | ping 目的地 | ping 目的地 |
在家里做 traceroute,第 1 跳应该是家用路由器(以 192.168 开头的地址),从第 2 跳左右开始出现运营商的路由器。途中出现 * * * 也没关系,只要最后能到就没问题。电脑的路由表里,除了 default 和家里网络的行,如果装了 VPN 或 Docker,还会有它们的行(第 11 讲)。
结 — 一页总结与下一讲
- 路由器只看目的地址,用路由表决定下一站,装进新信封(MAC)交出去。
- 路由表只有“直接相连”“交给这个地址”“default”三种。多行符合时用匹配最长的那一行。
- TTL 每过一台路由器减 1。traceroute 把它逐次加 1,收集“超时”通知的发送者。
- 把路由连成环,一次 ping 在 r2 和 r3 之间走了 62 次,TTL 才耗尽。
- ICMP 是 IP 的通知。常被防火墙拦住,ping 不通时网页也可能是通的。
- 家用路由器的本体是 NAT。改写源地址,查表换回。去掉它,去程能到、回程迷路。外面进不来。
- 互联网是约 8 万个 AS 的集合,用 BGP 互相告知约 107 万条路由。
新井NAT 表里的 40418、3000,到底是什么编号?
古井如果地址是大楼,编号就是房间。而且包在途中会丢,顺序也会乱。怎么把它们整理好?下一讲,TCP。
参考
- RFC 1812 — Requirements for IP Version 4 Routers
- RFC 792 — Internet Control Message Protocol
- traceroute(8) — Linux manual page
- RFC 3022 — Traditional IP Network Address Translator (Traditional NAT)
- RFC 4271 — A Border Gateway Protocol 4 (BGP-4)
- RFC 5737 — IPv4 Address Blocks Reserved for Documentation
- RFC 5398 — Autonomous System (AS) Number Reservation for Documentation Use
- Weekly Global IPv4 Routing Table Report (AFNOG, 2026-07-31)
- Geoff Huston — BGP in 2025 (ISP Column, January 2026)
- Engineering at Meta — More details about the October 4 outage (2021)
- Microsoft Learn — Find-NetRoute
记录来自笔者在云端 Linux(Ubuntu 24.04)上用网络命名空间搭建的练习网络,于 2026 年 10 月 25 日抓取。路由器使用 Linux 的转发功能,路由是手写的静态路由,NAT 是 iptables 的 MASQUERADE,转换表用 conntrack 1.4.8 查看,traceroute 为 2.1.5。表中的数字都是从这些记录和当时命令的输出读出的实际数值。地址和 AS 号都是为说明而保留的。全球路由表的数字来自 AFNOG 邮件列表每周发布的 Weekly Global IPv4 Routing Table Report(2026 年 7 月 31 日)。登场人物均为虚构。
古法网络入门 第5讲 — 路由器 / 2026.10