IP 与路由
→ 返回 计算机网络
IP 协议工作在网络层,负责跨网段寻址与数据包转发;路由协议负责维护路由表,决定数据包的转发路径。
IPv4
32 位,点分十进制,约 43 亿个地址:
| 类型 | 范围 | 用途 |
|---|---|---|
| 私有地址 | 10.0.0.0/8、172.16.0.0/12、192.168.0.0/16 | 局域网内部 |
| 回环地址 | 127.0.0.0/8 | 本机通信(127.0.0.1) |
| 链路本地 | 169.254.0.0/16 | APIPA,DHCP 失败时自动分配 |
| 组播地址 | 224.0.0.0/4 | D 类,多播组 |
| 广播地址 | 255.255.255.255 | 有限广播 |
| 公网地址 | 其余 | 互联网通信 |
IPv4 头部关键字段
版本(4) │ IHL │ DSCP/ECN │ 总长度(16)
─────────────────────────────────────────
标识(16) │标志│ 片偏移(13)
─────────────────────────────────────────
TTL(8) │ 协议(8) │ 首部校验和(16)
─────────────────────────────────────────
源 IP 地址(32)
─────────────────────────────────────────
目标 IP 地址(32)
- TTL(Time To Live):每经路由器减 1,归零则丢弃并回 ICMP Time Exceeded,防止包循环。
traceroute通过逐跳递增 TTL 探测路径。 - 协议字段:6=TCP,17=UDP,1=ICMP,89=OSPF
- 标志位:DF(Don’t Fragment)禁止分片,MF(More Fragments)后续还有分片
子网划分(CIDR)
CIDR(无类域间路由):用前缀长度 /N 替代固定类别,灵活分配地址空间。
192.168.1.0/24
└── 前 24 位网络部分,后 8 位主机部分
网络地址:192.168.1.0
广播地址:192.168.1.255
可用主机:192.168.1.1 ~ 192.168.1.254(共 254 台)
| 前缀 | 子网掩码 | 主机数 | 典型用途 |
|---|---|---|---|
| /8 | 255.0.0.0 | 16,777,214 | A 类大型网络 |
| /16 | 255.255.0.0 | 65,534 | 企业内网 |
| /24 | 255.255.255.0 | 254 | 常用局域网段 |
| /25 | 255.255.255.128 | 126 | 划分两个子网 |
| /26 | 255.255.255.192 | 62 | 小型部门 |
| /30 | 255.255.255.252 | 2 | 点对点链路 |
| /32 | 255.255.255.255 | 1(主机路由) | 特定主机路由 |
VLSM(可变长子网掩码)
按需分配不同大小的子网,节省地址:
10.0.0.0/24 划分给三个部门:
销售部(100 台)→ 10.0.0.0/25 (126 可用)
研发部(50 台) → 10.0.0.128/26 (62 可用)
IT部 (10 台) → 10.0.0.192/28 (14 可用)
WAN链路(2台) → 10.0.0.208/30 (2 可用)
超网(Supernetting / 路由聚合)
将多个连续子网合并为一条路由,减少路由表条目:
192.168.0.0/24
192.168.1.0/24 → 聚合为 192.168.0.0/23(包含两个 /24)
IPv6
128 位,冒号十六进制,约 3.4×10³⁸ 个地址,从根本上解决地址耗尽问题。
完整格式:2001:0db8:85a3:0000:0000:8a2e:0370:7334
简写规则:连续全 0 段用 :: 代替(仅用一次),前导 0 省略
简写后: 2001:db8:85a3::8a2e:370:7334
IPv6 地址类型
| 类型 | 前缀 | 说明 |
|---|---|---|
| 全局单播(GUA) | 2000::/3 | 可路由的公网地址 |
| 链路本地(LLA) | fe80::/10 | 同链路通信,不可跨路由器 |
| 唯一本地(ULA) | fc00::/7 | 私有地址,类似 RFC1918 |
| 多播 | ff00::/8 | 组播,无广播概念 |
| 回环 | ::1/128 | 等同于 127.0.0.1 |
NDP(邻居发现协议)
IPv6 用 NDP(ICMPv6)替代了 ARP:
功能对照:
ARP(IPv4) → NDP 邻居请求/通告(Neighbor Solicitation/Advertisement)
RARP → 无状态地址自动配置(SLAAC)
路由发现 → 路由器请求/通告(RS/RA)
NDP 地址解析过程:
节点 A 想联系 fe80::2:
→ 发送 ICMPv6 NS(目标:对应组播地址 ff02::1:ff00:2)
→ 节点 B 回复 NA:包含自己的 MAC 地址
双栈与过渡机制
| 机制 | 说明 |
|---|---|
| 双栈(Dual Stack) | 主机同时支持 IPv4 和 IPv6,优先使用 IPv6(RFC 6724) |
| 6to4 隧道 | 将 IPv6 包封装在 IPv4 包中穿越 IPv4 网络 |
| NAT64 / DNS64 | IPv6-only 客户端访问 IPv4 服务(运营商过渡方案) |
NAT(网络地址转换)
多台私有地址主机共用一个公网 IP:
局域网(192.168.1.x)→ NAT 路由器(公网 1.2.3.4)→ 互联网
出站 NAPT(端口转换):
内网 192.168.1.2:5000 → 公网 1.2.3.4:10001
内网 192.168.1.3:5000 → 公网 1.2.3.4:10002
(通过端口区分不同内网主机)
SNAT vs DNAT
| 类型 | 修改方向 | 典型用途 |
|---|---|---|
| SNAT(源 NAT) | 修改源 IP/Port | 内网主机访问外网(共享公网 IP) |
| DNAT(目标 NAT) | 修改目标 IP/Port | 外网访问内网服务(端口映射/反向代理) |
# iptables SNAT(内网出口)
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE
# iptables DNAT(端口映射,外网 80 → 内网 8080)
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 \
-j DNAT --to-destination 192.168.1.10:8080NAT 穿透(P2P 场景)
NAT 阻碍了外部主动连接内网主机,常用穿透方法:
- STUN:客户端探测自己的公网 IP:Port
- TURN:通过中继服务器转发(完全绕过 NAT)
- ICE:综合 STUN/TURN 的候选地址协商(WebRTC 使用)
IP 分片与 MTU
MTU(最大传输单元)
数据链路层单帧能携带的最大 IP 数据报大小:
| 链路类型 | 典型 MTU |
|---|---|
| 以太网 | 1500 字节 |
| Wi-Fi | 2304 字节(但实际走以太网时 1500) |
| PPPoE | 1492 字节(额外 8 字节头) |
| GRE 隧道 | 1476 字节(减去隧道头开销) |
| Loopback | 65536 字节 |
IP 分片
当 IP 包超过链路 MTU,路由器将其分片(IPv4 路由器可分片;IPv6 只有源主机分片):
原始 IP 包(3000 字节,MTU=1500):
→ 分片 1:标识=101,MF=1,偏移=0,长度=1500
→ 分片 2:标识=101,MF=0,偏移=185(185×8=1480),长度=1520
接收端重组(标识相同 + 偏移排序)
PMTUD(路径 MTU 发现)
端到端协商最佳 MTU,避免分片:
- 发送方设置 DF 位(Don’t Fragment)
- 路径上某路由器 MTU 不足 → 丢包并回 ICMP “Fragmentation Needed” 含路由器 MTU
- 发送方降低包大小重传
- 持续探测直到找到路径最小 MTU
# 测试路径 MTU(Linux)
tracepath -n 8.8.8.8 # 自动探测路径 MTU
ping -M do -s 1472 8.8.8.8 # 手动指定包大小,-M do 设置 DF 位DHCP(动态主机配置)
主机启动时自动获取 IP、掩码、网关、DNS,通过 UDP 广播(67/68 端口):
客户端 DHCP 服务器
│ │
│── DHCP Discover(广播,我需要 IP)────────►│ D: 广播寻找服务器
│◄─ DHCP Offer(提供 IP 192.168.1.100)────│ O: 服务器报价
│── DHCP Request(广播,我要那个 IP)────────►│ R: 客户端选择
│◄─ DHCP Ack(确认,租期 24h)──────────────│ A: 服务器确认
│ IP 生效 │
DHCP 中继(Relay Agent):跨网段 DHCP,路由器将广播转为单播转发给 DHCP 服务器。
# Linux 查看 DHCP 租约
cat /var/lib/dhcp/dhclient.leases
dhclient -v eth0 # 手动重新获取路由表与最长前缀匹配
路由器收到 IP 包后,查路由表选最长匹配的路由(更具体的路由优先):
路由表示例:
目标网络 下一跳 接口 度量
10.0.0.0/8 192.168.1.1 eth0 10
10.1.0.0/16 192.168.1.2 eth0 5 ← 更具体
10.1.1.0/24 直接连接 eth1 0 ← 最具体,优先
0.0.0.0/0 203.0.113.1 eth2 1 ← 默认路由(兜底)
目标 IP 10.1.1.5 匹配 10.1.1.0/24(/24 > /16 > /8)
# Linux 查看路由表
ip route show
ip route get 8.8.8.8 # 查询特定目标会走哪条路由
# 添加静态路由
ip route add 192.168.2.0/24 via 10.0.0.1 dev eth0
# 默认网关
ip route add default via 192.168.1.1ECMP(等价多路径)
多条等价路由同时存在,实现负载均衡:
# 添加 ECMP 路由(Linux 内核支持)
ip route add 10.0.0.0/8 \
nexthop via 192.168.1.1 dev eth0 weight 1 \
nexthop via 192.168.1.2 dev eth1 weight 1路由协议
| 协议 | 类型 | 适用 | 核心算法 |
|---|---|---|---|
| 静态路由 | 手动配置 | 简单拓扑 | — |
| RIP | 距离向量 | 小型网络 | Bellman-Ford,跳数度量(max 15) |
| OSPF | 链路状态 | 企业内网 | Dijkstra 最短路径 |
| BGP | 路径向量 | 互联网骨干 | 路径属性选路 |
OSPF 区域划分
骨干区域(Area 0)
│
├── Area 1(普通区域)
│ └── ABR(区域边界路由器)连接 Area 0
├── Area 2(Stub 区域,不接受外部路由)
└── Area 3
OSPF 路由器通过 LSA(链路状态通告)泛洪建立完整拓扑图(LSDB),每台路由器独立运行 Dijkstra 计算最短路径树。
BGP 路径属性
BGP 通过多个属性控制路径选择(优先级从高到低):
- Weight(Cisco 私有,本地优先)
- Local Preference(AS 内优先级)
- AS Path 长度(经过的 AS 数,越短越好)
- Origin(IGP > EGP > incomplete)
- MED(Multi-Exit Discriminator,外部 AS 建议入口)
ICMP
网络层控制协议,用于错误报告和网络诊断:
| ICMP 类型 | 用途 |
|---|---|
| Echo Request/Reply(Type 8/0) | ping 连通性测试 |
| Destination Unreachable(Type 3) | 目标不可达,含端口不可达 |
| Time Exceeded(Type 11) | TTL 归零,traceroute 利用此实现 |
| Redirect(Type 5) | 路由器通知主机用更好的下一跳 |
| Fragmentation Needed(Type 3 Code 4) | PMTUD 依赖此消息 |
ping 8.8.8.8 # 测试连通性(ICMP Echo)
ping -c 4 -W 1 8.8.8.8 # 发 4 包,超时 1s
traceroute 8.8.8.8 # 追踪路由路径(TTL 递增)
traceroute -T -p 443 8.8.8.8 # 用 TCP 443 traceroute(穿越防火墙)
mtr 8.8.8.8 # 实时 traceroute + 丢包率统计ARP(地址解析协议)
将 IP 地址解析为 MAC 地址,用于同一局域网内通信:
主机 A(192.168.1.2)想发数据给 192.168.1.5:
① ARP 请求(广播):
src:MAC-A → dst:FF:FF:FF:FF:FF:FF
"谁是 192.168.1.5?请告诉我你的 MAC"
② ARP 应答(单播):
"我是 192.168.1.5,MAC 是 00:AA:BB:CC:DD:EE"
③ 主机 A 缓存 IP→MAC 映射(ARP 缓存),有效期约 20 分钟
arp -n # 查看 ARP 缓存(Linux)
arp -a # Windows
arp -d 192.168.1.5 # 删除指定缓存条目
# Gratuitous ARP(免费 ARP):主机主动通告自己的 IP/MAC 映射
# 用途:更新其他主机的 ARP 缓存(如 HA 故障切换、IP 变更)隧道协议
将一种网络包封装在另一种包内传输,用于 VPN、跨网段互联、Overlay 网络:
| 协议 | 封装方式 | 用途 |
|---|---|---|
| GRE | IP over IP(增加 24 字节头) | 点对点隧道,连接两个网络 |
| IPIP | IP over IP(最简单) | 轻量级隧道 |
| VXLAN | UDP 封装 L2 帧(8 字节头+UDP+IP) | 数据中心 Overlay,支持多租户 |
| WireGuard | UDP + 现代密码学 | 高性能 VPN 隧道 |
# 创建 GRE 隧道(Linux)
ip tunnel add tun0 mode gre remote 203.0.113.1 local 198.51.100.1
ip link set tun0 up
ip addr add 10.0.0.1/30 dev tun0
# VXLAN(容器网络,Docker/K8s 常用)
ip link add vxlan100 type vxlan id 100 dstport 4789 \
remote 192.168.1.2 local 192.168.1.1 dev eth0策略路由(PBR)
按源 IP、入接口、报文标记等策略选择路由,而非仅按目标 IP:
# 场景:来自 192.168.1.0/24 的流量走 ISP1,其他走 ISP2
# 1. 建立路由表 100
ip route add default via 203.0.113.1 table 100
# 2. 添加策略规则
ip rule add from 192.168.1.0/24 table 100
# 查看策略规则
ip rule show