arp - icmp - nat
04. ARP、ICMP 与 NAT
0. 本章先解决什么问题
学到 IP 和路由以后,很容易产生一个错觉:只要知道目标 IP,数据包就能自动到达目标机器。
真实网络里还差三类关键能力:
- 相邻设备之间怎么真正交付:IP 地址只说明“目标是谁”,但以太网/Wi-Fi 这一跳真正需要的是 MAC 地址。
- 网络层怎么报告和诊断问题:包到不了、TTL 用完、目标不可达、路径 MTU 不合适,都需要控制信息反馈。
- 私有地址怎么访问公网:大量机器使用内网地址,它们和公网通信时需要地址转换。
这三件事分别对应:
| 机制 | 解决的问题 | 常见现象 |
|---|---|---|
| ARP | 已知下一跳 IP,怎样找到下一跳 MAC | 同网段不通、网关 MAC 缓存异常 |
| ICMP | 网络层如何反馈错误和做诊断 | ping、traceroute、不可达、TTL 超时 |
| NAT | 私有地址如何通过公网地址通信 | 内网访问外网、端口映射、连接超时 |
本章要把这三者放进一次真实发包路径里理解,而不是孤立背名词。
先把三件事放到同一条路径里:ARP 解决本地下一跳,ICMP 提供诊断信号,NAT 改写地址并维护映射。
这张图怎么读
把图分成三个观察点:发包前,主机需要 ARP 找到本地下一跳的 MAC;转发中,ICMP 可能返回不可达、超时等诊断信号;穿过 NAT 时,源地址或端口会被改写,并在 NAT 设备上留下映射表。排障时要分别问:本地能不能找到下一跳、路径中有没有错误反馈、地址改写后的回包能不能匹配回来。
1. 先区分三种地址
网络里经常同时出现域名、IP、MAC、端口。它们在不同层次解决不同问题:
| 标识 | 所属层次 | 主要作用 | 例子 |
|---|---|---|---|
| 域名 | 应用层/命名系统 | 给人和服务使用的名字 | www.example.com |
| IP 地址 | 网络层 | 标识主机或接口所在的网络位置 | 203.0.113.10 |
| MAC 地址 | 链路层 | 标识同一链路里的网卡 | 00:11:22:33:44:55 |
| 端口 | 传输层 | 标识主机上的进程通信入口 | 443 |
一个程序访问远程服务时,通常经历:
域名 -> IP
IP -> 下一跳 IP
下一跳 IP -> 下一跳 MAC
端口 -> 目标进程
ARP 只负责其中一小段:同一链路中,已知 IP,找到 MAC。
2. ARP:IP 到 MAC 的本地映射
以太网帧投递时需要目标 MAC。假设主机 A 要把包交给同网段主机 B:
A 的 IP: 192.168.1.10
B 的 IP: 192.168.1.20
A 知道 B 的 IP,但不知道 B 的 MAC,于是发 ARP 请求:
广播: 谁是 192.168.1.20?请告诉 192.168.1.10
同一局域网里的设备都会收到这条广播,只有 B 回答:
单播: 192.168.1.20 是我,我的 MAC 是 bb:bb:bb:bb:bb:bb
之后 A 把映射放进 ARP 缓存:
192.168.1.20 -> bb:bb:bb:bb:bb:bb
2.1 ARP 只在本地链路内工作
如果目标 IP 不在本机子网里,本机不会 ARP 查询目标主机的 MAC,而是查询默认网关的 MAC。
例如:
代码块收起展开
本机: 192.168.1.10/24
网关: 192.168.1.1
目标: 203.0.113.10本机判断 203.0.113.10 不在 192.168.1.0/24 内,于是:
- IP 包目标地址:203.0.113.10
- 以太网帧目标 MAC:网关 192.168.1.1 的 MAC
这点非常关键:
跨网段通信时,IP 目标通常是最终目标;
MAC 目标永远是当前这一跳的下一跳。
2.2 ARP 缓存为什么存在
如果每次发包都广播查询 MAC,局域网会被大量 ARP 请求拖慢。主机会缓存查询结果:
| 缓存行为 | 作用 |
|---|---|
| 记录 IP -> MAC | 避免重复广播 |
| 设置过期时间 | 防止设备更换网卡、迁移地址后旧映射长期存在 |
| 收到新回应后更新 | 适应局域网变化 |
缓存提升效率,也带来排障点。错误或陈旧的 ARP 映射会让同网段通信异常。
2.3 ARP 常见问题
| 现象 | 可能方向 |
|---|---|
| 同网段主机互相 ping 不通 | ARP 没解析到、交换机/VLAN 隔离、防火墙过滤 |
| 能访问公网,不能访问局域网某台机器 | 那台机器离线、IP 冲突、ARP 缓存错误 |
| 偶发访问到错误机器 | IP 冲突或 ARP 欺骗 |
| 网关可达性异常 | 默认网关配置错、网关 MAC 映射异常 |
ARP 没有强身份认证,所以局域网里存在 ARP 欺骗风险。安全网络会用交换机安全策略、静态绑定、检测系统等方式降低风险。
3. ICMP:网络层的控制与诊断消息
ICMP 经常被简化成 ping,但它的本质是:网络层用来发送控制信息和错误信息的协议。
IP 本身尽力转发。如果中间节点遇到问题,需要一种方式告诉发送方:
这个目标不可达。
这个包太大不能转发。
TTL 用完了。
请检查连通性。
ICMP 就承担这类反馈。
4. ping 不是“端口通不通”
ping 使用 ICMP Echo Request / Echo Reply:
Host A — ICMP Echo Request —> Host B
Host A <— ICMP Echo Reply --- Host B
它能说明:
| ping 结果 | 能说明什么 | 不能说明什么 |
|---|---|---|
| 能 ping 通 | 某种网络层路径可达,目标愿意回 ICMP | 目标端口一定开放 |
| ping 不通 | ICMP 不通或被禁,路径可能有问题 | 应用服务一定不可用 |
很多环境会限制 ICMP。一个服务的 TCP 端口可以正常访问,但 ping 被防火墙丢弃;也可能 ping 正常,但目标端口没有进程监听。
排障时要分清:
- ping:网络层诊断
- connect:传输层连接
- HTTP 请求:应用层交互
5. traceroute 的基本原理
IP 包里有 TTL。每经过一个路由器,TTL 减 1;减到 0 时,路由器丢弃包,并返回 ICMP TTL Exceeded。
traceroute / tracert 利用这个机制探测路径:
TTL=1 -> 第 1 跳路由器返回 TTL 超时
TTL=2 -> 第 2 跳路由器返回 TTL 超时
TTL=3 -> 第 3 跳路由器返回 TTL 超时
…
于是可以得到大致路径:
本机 -> 网关 -> 运营商路由 -> 骨干网络 -> 目标网络 -> 目标主机
注意它不是完美地图:
| 限制 | 解释 |
|---|---|
| 路由可能不对称 | 去程和回程路径可能不同 |
| 中间设备可能不回 ICMP | 某些跳显示 * 不代表后面一定不通 |
| 路径会动态变化 | 路由策略和拥塞状态可能改变 |
| 只显示网络层路径 | 不代表应用层服务健康 |
6. NAT:私有地址到公网地址的转换
IPv4 地址数量有限,局域网通常使用私有地址:
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
这些地址不能直接在公网路由。内网机器访问公网时,边界设备会做 NAT。
最常见的是源地址转换:
内网主机: 192.168.1.10:51500
公网地址: 203.0.113.5
目标服务: 198.51.100.20:443
出站时,NAT 设备把包改成:
原始:
192.168.1.10:51500 -> 198.51.100.20:443
转换后:
203.0.113.5:40001 -> 198.51.100.20:443
同时记录映射表:
203.0.113.5:40001 <-> 192.168.1.10:51500
响应回来时,NAT 设备根据映射表改回内网地址:
198.51.100.20:443 -> 203.0.113.5:40001
改回:
198.51.100.20:443 -> 192.168.1.10:51500
6.1 NAT 不只是改 IP
如果多个内网主机共用一个公网 IP,只改 IP 不够,还要区分连接。常见做法是同时改端口,也叫 PAT 或端口复用 NAT。
192.168.1.10:51500 -> 203.0.113.5:40001
192.168.1.11:51500 -> 203.0.113.5:40002
192.168.1.12:51500 -> 203.0.113.5:40003
端口成为 NAT 映射表的重要索引。
6.2 NAT 带来的影响
| 影响 | 解释 |
|---|---|
| 内网主动访问外网容易 | 出站时自动建立映射 |
| 外网主动访问内网困难 | 没有映射时,NAT 不知道该转给谁 |
| 需要端口映射 | 把公网端口固定转到某台内网机器 |
| 映射有超时 | 长时间无流量,NAT 表项会被清理 |
| 破坏端到端直连 | 中间设备修改地址和端口 |
| 点对点通信更复杂 | 双方都在 NAT 后面时需要穿透或中继 |
NAT 让 IPv4 网络继续运转,但代价是连接不再只是两端的事,中间设备也保存了状态。
机制深挖:NAT 映射是一张会过期的状态表
NAT 的关键不是“改一下地址”这么简单,而是维护一张映射表。
一条出站连接可能变成:
- 内网 192.168.1.10:51500 -> 外网目标 198.51.100.20:443
- NAT 203.0.113.5:40001 -> 外网目标 198.51.100.20:443
NAT 表里需要记录:
| 字段 | 用途 |
|---|---|
| 内网源地址和端口 | 回包要还原给谁 |
| NAT 后的公网地址和端口 | 外部看到的源 |
| 目标地址和端口 | 区分不同会话或流 |
| 协议 | TCP/UDP/ICMP 处理方式不同 |
| 最近活动时间 | 决定映射是否过期 |
这张表带来三个重要边界:
| 边界 | 现象 |
|---|---|
| 表项未建立 | 外部主动访问内网时,NAT 不知道转给谁 |
| 表项过期 | 空闲一段时间后,回包或后续包突然失败 |
| 端口资源耗尽 | 大量连接共享出口时,新连接建立失败或不稳定 |
所以 NAT 排障要问:
出站流量有没有建立映射?
回包是否命中同一条映射?
映射是否因为空闲或连接状态变化被清理?
出口端口资源是否足够?
这能解释很多“刚开始能连,过一会儿断”“内网主动访问正常,外部主动访问失败”“只有某个出口异常”的问题。
7. 把 ARP、ICMP、NAT 放进一次访问
假设内网主机访问公网服务:
主机 A: 192.168.1.10
网关: 192.168.1.1 / 公网 203.0.113.5
目标: 198.51.100.20:443
路径可以拆成:
- A 判断目标不在本地子网
- A 需要把帧交给默认网关
- A 用 ARP 找到网关 MAC
- A 发出 IP 包: 192.168.1.10 -> 198.51.100.20
- 网关做 NAT: 203.0.113.5:40001 -> 198.51.100.20:443
- 公网路由逐跳转发
- 目标返回响应
- NAT 设备根据映射表改回 192.168.1.10
- A 收到响应
如果中间某处出问题,ICMP 可能反馈错误;如果 ICMP 被过滤,应用看到的可能只是超时。
8. 常见故障映射
| 现象 | 优先检查 |
|---|---|
| 同网段不通 | IP/掩码、ARP 表、交换机/VLAN、本机防火墙 |
| 不能访问外网 | 默认网关、网关 ARP、NAT、上游路由 |
| ping 通但端口不通 | 目标进程监听、防火墙、传输层连接 |
| ping 不通但服务能访问 | ICMP 被过滤,应用层路径仍可用 |
| 内网服务外网访问不到 | 端口映射、防火墙、公网地址、运营商 NAT |
| 连接空闲后断开 | NAT 映射超时、中间设备 idle timeout |
| traceroute 中间有星号 | 中间设备不回 ICMP 或限速,不一定是断点 |
9. 联系实际:为什么会“我这里能访问,他那里不能”
这类问题很常见,因为不同位置看到的网络边界不同。
同一台服务
公司内网访问: 可能走内网地址、内网 DNS、内网路由
家里访问: 可能走公网 DNS、NAT、运营商网络
机房内访问: 可能走私有网络、专线、内部负载均衡
排查时不要只问“服务是不是开着”,而要画路径:
发起方在哪个网络?
解析到哪个 IP?
第一跳网关是谁?
是否经过 NAT?
目标端口有没有映射?
中间是否有防火墙或安全策略?
ICMP 和 TCP/UDP 的结果是否一致?
一旦路径画出来,很多“玄学网络问题”都会变成具体检查点。
手推:ARP 缓存错了,为什么 IP 层看起来没错但仍发不到
同网段发送时,IP 层决定:
目标 IP 在本地子网
=> 直接发给目标 IP 对应的 MAC
但真正上以太网时需要 MAC。如果 ARP 缓存里记录错了:
192.168.1.20 -> 错误 MAC
主机仍会构造一个目标 IP 正确的包:
IP dst = 192.168.1.20
但以太网帧会发给错误的二层地址:
Ethernet dst = 错误 MAC
结果是:
| 层 | 看起来 |
|---|---|
| IP 配置 | 目标地址、掩码都可能正确 |
| 路由选择 | 本地直达判断也正确 |
| 二层交付 | 帧交给了错误设备或没人接收 |
这解释了为什么同网段问题不能只看 IP 和路由表,还要看 ARP 表、VLAN、交换机学习表和地址冲突。
边界条件:ICMP 被过滤不等于路径不可达
很多网络设备会限制或丢弃 ICMP。于是:
ping 不通
只说明 ICMP Echo 这类消息没有得到响应,不必然说明 TCP/UDP 服务不可达。
反过来:
ping 通
也只说明某种网络层往返成立,不代表目标端口开放、TLS 成功、应用正常。
排障时要把证据分开:
| 证据 | 能证明 | 不能证明 |
|---|---|---|
| ARP 成功 | 本地二层下一跳可达 | 远端服务正常 |
| ping 成功 | ICMP 往返可用 | TCP/UDP 端口可用 |
| traceroute 有响应 | 部分中间跳会回 ICMP | 没星号处就是故障点 |
| TCP connect 成功 | 端口有响应 | 应用协议成功 |
ICMP 是诊断工具,不是业务协议本身。它能提供线索,但不能替代传输层和应用层证据。
排障卡:把本地可达、远端可达和地址转换分开
遇到“我这里能访问,他那里不能”,按三张表拆:
| 检查点 | 问题 | 典型结论 |
|---|---|---|
| ARP | 本机能不能找到下一跳的 MAC? | 找不到时,问题常在同网段、网关、VLAN、地址冲突 |
| ICMP | 网络层有没有返回控制信息? | 超时、不可达、TTL 递减能帮助判断路径位置 |
| NAT | 私有地址是否被正确转换和记录? | 只在某个出口失败时,要怀疑地址池、端口映射、回程 |
一个实用判断:如果同网段目标不通,先看 ARP;如果跨网段路径不清楚,看 ICMP / traceroute;如果内网访问外网表现不一致,再看 NAT。不要把 ping 不通直接等价成“服务挂了”,也不要把 ping 通等价成“端口一定通”。
10. 学完本章你能解决什么问题
学完本章,你应该能处理这些实际问题:
- 判断同网段通信失败是不是 ARP、掩码、网关或二层隔离导致的。
- 解释为什么跨网段通信时帧的目标 MAC 是下一跳,而不是最终目标。
- 正确使用 ping 和 traceroute,把它们当作网络层证据,而不是最终结论。
- 区分“网络层可达”“端口可连接”“应用响应正常”这三件事。
- 理解 NAT 映射表如何让内网机器访问公网。
- 解释为什么外网访问内网服务需要端口映射或其他穿透方案。
- 排查“内网能访问、公网不能访问”“ping 不通但服务正常”“连接空闲后断开”等常见问题。