ICMPv6 一个人干了三份活:错误报告、地址解析(代替 ARP)、组播管理(代替 IGMP)。 所以「为了安全把 ICMPv6 全禁」在 IPv6 里会直接让网络瘫痪。
5.4.1 到 5.4.3 讲的是 ICMP,这一节讲它在 IPv6 里的扩张。 4.6.6 的 fe80 地址是 NDP 的基础,两节要连起来看。
一、它承担了三份活
IPv4 里三套东西,IPv6 合成了一套:
| IPv4 里是谁 | 干的什么活 | IPv6 里变成 |
|---|---|---|
| ICMP | 错误报告 | ICMPv6 类型 1~4 |
| ARP | IP 找 MAC | NDP(类型 135/136) |
| IGMP | 组播成员管理 | MLD(类型 130~132) |
合成一套的好处是「共用一套报文格式和一套安全机制」: IPv4 里 ARP 完全没有认证,而 ICMPv6 的 NDP 至少有 SEND 可选(虽然部署很少)。 但更实际的好处是「少了两个协议号、少了两种报文要处理」。 代价是「ICMPv6 变成了必需品」: 在 IPv4 里禁 ICMP 只是不能 ping,在 IPv6 里禁 ICMPv6 等于「不能找邻居、不能自动配置」。
二、NDP 的五种消息
NDP(邻居发现)是 ICMPv6 里最重要的一块:
| 类型 | 名称 | 作用 |
|---|---|---|
| 133 | 路由器请求 | 主机问「谁是网关」 |
| 134 | 路由器通告 | 网关说「我是,前缀是这个」 |
| 135 | 邻居请求 | 相当于 ARP 请求 |
| 136 | 邻居通告 | 相当于 ARP 应答 |
| 137 | 重定向 | 告诉你换个网关 |
第三、四行就是「ARP 的替代品」:只不过它们用多播( solicited-node 组)而不是广播, 所以「不关心的人收不到」。 第一、二行是「自动配置」的基础:主机开机发 133 问「网关在哪」,网关回 134 带上前缀, 主机拿前缀加自己的接口标识,地址就有了。 不需要 DHCP,这就是 SLAAC。
三、为什么不能全禁
因为「包太大」这条消息在 IPv6 里没有替代品:路由器不许分片,过不去只能回 ICMPv6, 源端收到才能调小。
| 禁掉什么 | 后果 | 严重程度 |
|---|---|---|
| 类型 2(包太大) | 大包直接不通 | 致命 |
| 类型 135/136 | 找不到邻居 | 致命 |
| 类型 133/134 | 自动配置失效 | 严重 |
第一行「致命」不是夸张: 因为「大包不通」意味着「TCP 握手可能成功、传数据就卡死」——这种「半通不通」的故障最难查。 所以 IPv6 的部署规范里有一条硬要求: 「ICMPv6 不能全拦,至少类型 1、2、3、4 和 135、136 要放行」。 把 IPv4 时代的「禁 ICMP」习惯搬过来,是 IPv6 部署最常见的坑之一。
四、动手 Demo:ICMPv6 不只是「v6 版的 ping」
把类型号排一遍,看哪些是「错误报告」、哪些是「邻居发现」。 注意第五行那五个类型,它们取代了整个 ARP。
rows = [(1, '目标不可达'), (2, '包太大'), (3, '超时'),
(128, '回显请求'), (129, '回显应答'),
(133, '路由器请求'), (134, '路由器通告'),
(135, '邻居请求'), (136, '邻居通告'), (137, '重定向')]
for t, n in rows:
print(t, n)
实跑输出:
--------------------------------------------------------------------
ICMPv6 不只是「v6 版的 ping」
--------------------------------------------------------------------
**ICMPv6 承担了 IPv4 里「ARP + ICMP + IGMP」三家的活**:**地址解析、错误报告、组播管理全在里面。**
类型 名称 作用
------------------------------------------------------------
**1** **目标不可达** **错误报告**
**2** **包太大** **PMTU 发现靠它**
**3** **超时** **traceroute 靠它**
**128/129** **回显请求/应答** **ping6**
**133~137** **NDP 五种消息** **取代 ARP**
**第五行那五种要记住**:
**路由器请求(133)、路由器通告(134)、邻居请求(135)、邻居通告(136)、重定向(137)。**
**其中 135 和 136 就是「IPv6 的 ARP」**——**只不过它用多播,不用广播。**
**第二行「包太大」是 IPv6 的必需机制**:**因为路由器不许分片,过不去只能回这个消息**,
**源端收到就调小重发。**
**所以「ICMPv6 被拦」在 IPv6 里的后果比 IPv4 更严重**——
**IPv4 只是 PMTU 发现失效(还能偷偷分片),IPv6 是「大包直接不通」。**
**所以 IPv6 的部署规范里有一条硬要求**:**ICMPv6 不能全拦**,至少 type 2 和 135/136 要放行。**
**「为了安全把 ICMP 全禁掉」这个习惯,在 IPv6 里会直接让网络瘫痪。**
类型号从 128 开始是一个有意的设计:小于 128 是「错误消息」,大于等于 128 是「信息消息」。 这个分界让「该不该转发」变得好判断——错误消息要送到源端,信息消息只在本地用。 「包太大(2)」在 IPv4 里是「类型 3 的代码 4」:IPv6 把它提成了独立的类型, 因为它是「正常流程的一部分」而不是「错误」——每个连接都要用它来发现路径 MTU。 NDP 用多播而不是广播,带来一个实际好处:无线网络里「不关心的设备不会被叫醒」, 所以 IPv6 的手机待机功耗比 IPv4 低。 这是「取消广播」的连带收益。
30 秒实验
- 想一下:为什么 IPv6 把「包太大」提成独立类型?
- 想一下:NDP 用多播代替广播,对无线设备有什么好处?
- 想一下:如果防火墙只放行 ping6,会发生什么?
常见误区
- 以为「ICMPv6 只是 v6 版的 ping」。 它还管地址解析和组播,是必需品。
- 以为「可以照 IPv4 的习惯全禁 ICMP」。 会让 IPv6 瘫痪,连邻居都找不到。
- 以为「NDP 就是 ARP 改个名字」。 机制不同,它用多播、跑在 ICMPv6 上、还能带前缀信息。
自测三问(点开对答案)
1. ICMPv6 承担了 IPv4 里哪三个协议的活? —— **ICMP、ARP、IGMP**:错误报告、地址解析、组播管理。 2. NDP 的五种消息是哪五种? —— **路由器请求、路由器通告、邻居请求、邻居通告、重定向**(133~137)。 3. 为什么不能全禁 ICMPv6? —— **因为「包太大」「邻居请求」没有替代品**,禁了会让大包不通、邻居找不到。下一节讲「自动拿地址」:DHCP。
- ☐ (本节完,下一节 5.5.1 DHCP实现即插即用)