Linux 网络实验室 (三):进阶之路 ------ 策略路由 (PBR) 与 GRE 隧道
- 策略路由 (PBR): 如何根据源 IP(老板 vs 员工)决定走哪条宽带上网?
- GRE 隧道: 如何在公网之上挖一条隧道,把北京和上海的内网连起来?
实验五:双宽带分流 (Policy Based Routing)
在传统的路由表中,我们只能根据"目的地"来决定下一跳(Destination-based Routing)。但在现实中,我们经常需要根据"是谁发的包"来决定路线。
场景: 路由器接了两条宽带。
- ISP 1 (电信): 速度快,给老板 (PC1) 用。
- ISP 2 (联通): 备用线路,给员工 (PC2) 用。
1. 实验拓扑
text
Namespace: PC1 (Boss) Namespace: ISP 1
+-----------------------+ +--------------------+
| IP: 192.168.1.10 | | IP: 203.0.113.88 |
+----------+------------+ +----------+---------+
| ^
v (veth-r-wan) |
[ Switch (br0) ] <------------------+ |
^ IP: 203.0.113.1| |
| | |
+----------+------------+ +-----+------------------+-----+
| IP: 192.168.1.20 | | Namespace: ROUTER |
+-----------------------+ | |
Namespace: PC2 (Staff) | [Rules] |
| From PC1 -> Table 100 (ISP1) |
| From PC2 -> Table 200 (ISP2) |
| |
+-----+------------------+-----+
| IP: 198.51.100.1 |
| (veth-r-wan2) |
v |
+------+------------------+-----+
| IP: 198.51.100.88 |
+-------------------------------+
Namespace: ISP 2
2. 实战配置
(前置准备:建立 PC1, PC2, Router 和两个 ISP 的物理连接,具体命令略,重点看路由配置)
第一步:创建多张路由表
Linux 支持多张路由表。除了默认的 main 表,我们为两个 ISP 创建独立的表。
bash
# 配置 Table 100 (走 ISP 1)
sudo ip netns exec router ip route add default dev veth-r-wan table 100
# 配置 Table 200 (走 ISP 2)
sudo ip netns exec router ip route add default dev veth-r-wan2 table 200
第二步:配置策略规则 (IP Rule)
这是 PBR 的核心。我们要告诉内核:来自 PC1 的查表 100,来自 PC2 的查表 200。
bash
# 规则:来自 192.168.1.10 (老板) -> 查表 100
sudo ip netns exec router ip rule add from 192.168.1.10 lookup 100
# 规则:来自 192.168.1.20 (员工) -> 查表 200
sudo ip netns exec router ip rule add from 192.168.1.20 lookup 200
第三步:验证分流
我们在 Router 的两个 WAN 口分别抓包,然后让 PC1 和 PC2 分别 Ping 外网。你会发现它们的流量被精确地分流到了不同的物理接口上。
实验六:穿越公网的隧道 (GRE Tunnel)
如果你的公司在北京和上海各有一个分部,如何让两边的内网 IP 直接互通?最基础的方案就是 Overlay 网络 ,通过 GRE (Generic Routing Encapsulation) 协议在公网 IP 上封装一层私网 IP。
1. 实验拓扑 (Overlay vs Underlay)
- Underlay (物理层): Site-A (1.1.1.1) 和 Site-B (2.2.2.2) 通过公网互通。
- Overlay (逻辑层): 我们在两者之间建立一条
gre1隧道,配置私有 IP (10.10.10.x)。
text
Namespace: Site-A Namespace: Site-B
+---------------------------+ +---------------------------+
| Physical: 1.1.1.1 | < Internet > | Physical: 2.2.2.2 |
| | | |
| [Tunnel Interface: gre1] | ============ | [Tunnel Interface: gre1] |
| Inner IP: 10.10.10.1 | (Tunnel) | Inner IP: 10.10.10.2 |
+---------------------------+ +---------------------------+
2. 实战配置
第一步:打通底层网络 (Underlay)
首先必须保证 Site-A 能 Ping 通 Site-B 的公网 IP (2.2.2.2)。
第二步:建立 GRE 接口
bash
# 在 Site-A 上挖隧道
# remote: 对方公网IP, local: 我方公网IP
sudo ip netns exec site-a ip tunnel add gre1 mode gre remote 2.2.2.2 local 1.1.1.1 ttl 255
sudo ip netns exec site-a ip link set gre1 up
sudo ip netns exec site-a ip addr add 10.10.10.1/24 dev gre1
# 在 Site-B 上挖隧道
sudo ip netns exec site-b ip tunnel add gre1 mode gre remote 1.1.1.1 local 2.2.2.2 ttl 255
sudo ip netns exec site-b ip link set gre1 up
sudo ip netns exec site-b ip addr add 10.10.10.2/24 dev gre1
第三步:配置私网路由
如果你想让 Site-A 后端的 192.168.1.0/24 访问 Site-B 后端的 192.168.2.0/24,你需要在路由表中指定:"去往对方内网,请走 gre1 接口"。
bash
# Site-A 路由表
sudo ip netns exec site-a ip route add 192.168.2.0/24 dev gre1
第四步:验证
现在,Site-A 可以直接 Ping 通 Site-B 的内网地址。在中间的 Internet 抓包,你会看到神奇的 "IP in IP" 结构:外层是公网 IP,内层是私网 IP。
深度思考与排错分析
这两个实验看似简单,但在实际操作中,我们踩到了两个非常经典的"坑"。
1. 策略路由的"盲从陷阱":为什么 Router 自己 Ping 不通了?
问题描述:
配置好 PBR 后,我们发现 PC1 上网正常,但 Router 想要 Ping 直连的 ISP2 网关却不通了。
原因分析:
ip rule 的逻辑非常机械。我们配置了 from 192.168.1.10 lookup 100。
但是,当 Router 本身发出流量,或者访问直连网络 (比如去访问 ISP2 的 198.51.100.x)时,如果没有特殊的规则,它可能会错误地命中某些默认规则,或者因为 Table 100 里只有一条默认路由(指向 ISP1),导致 Router 明明要去 ISP2,却被强制扔给了 ISP1。
解决方案:
我们必须显式地告诉 Router:"本地直连的邻居,请直接查 Main 表,不要走策略路由。"
我们需要添加一条高优先级的规则:
bash
# 凡是去往 ISP2 网段的,强制查 Main 表 (pref 50 优先级极高)
sudo ip netns exec router ip rule add to 198.51.100.0/24 lookup main pref 50
这条规则就像是"特赦令",保证了底层网络的互通性。
2. GRE 的隐形杀手:MTU 与分片
问题描述:
GRE 隧道建立后,Ping 没问题,但传大文件时可能会卡死。
原因分析:
标准的以太网 MTU 是 1500 字节 。
GRE 协议需要在原始数据包上增加头部:20字节 (外层IP头) + 4字节 (GRE头) = 24字节 。
如果你强行塞入一个 1500 字节的包,加上头部就变成了 1524 字节 ,超过了物理网卡的限制。这会导致路由器不得不进行 IP 分片 (Fragmentation),极大地降低性能,甚至导致丢包。
最佳实践:
在配置 GRE 隧道时,应手动调小 Tunnel 接口的 MTU:
bash
# 1500 - 24 = 1476
sudo ip netns exec site-a ip link set gre1 mtu 1476
这样,Router 就会告诉内网的 PC:"路变窄了,发包请小一点",从而避免分片。