Amazon Linux 2023:Bug 还是特性?
背景
在 AWS 的一个 VPC 内部的一台 EC2 上搭了一个 OpenVPN 服务器,对,就是 从 Client VPN endpoint 迁移到 EC2 上的 OpenVPN 提到的这件事。然后我有台 PC 通过 OpenVPN 客户端软件连了过来。以下是基本信息。
NOTE: IP 地址都不是实际真实情况
- EC2(A)
- 公网 IP:
1.1.1.1
(本地并没有,这个是防火墙或其他设备给做的一对一 map) - 私网 IP:
10.0.0.2/24
- 私网网关:
10.0.0.1
- 私网网卡:enX0
- tun 设备名:tun0
- tun 设备 IP:
172.16.0.1/24
- 公网 IP:
- PC(B)
- tun 设备名:tun0
- tun 设备 IP:
172.16.0.2/24
问题描述
问题的核心是:B 无法 ping 通 A 的私网 IP。换句话说,当我在 B 上执行 ping 10.0.0.2
命令时,无法得到响应。俗话就是 ping 不通 10.0.0.2。
问题排查
初步排查
我对 AWS EC2 的网络问题进行了深入的排查,包括各种路由表、安全组、网络 ACL,甚至本地的防火墙配置等等。然而,我并没有找到问题的所在。我可以访问 VPC 内部的私网里的 RDS 资源,也可以在 A 上明显看到有接收到数据包。
ICMP 包的追踪
我继续深入,发现在 A 上可以接收到 B 发送的 icmp 包,而且 A 也确实有回包,但是奇怪的是,回包并没有通过 tun0 设备,而是直接从 enX0 设备发送出去!
不是路由的问题(?)
马上怀疑本地路由有问题,直接在 A 上执行
1 | ip r get 172.16.0.2 |
发现没问题呀,是从设备 tun0 走的呀?这下就完全把我给整不会了。再此之后,我还做了好些努力,比如:
继续检测排查
- 在 A 上 ping B 的 VPN 地址(tun0 设备上):
ping 172.16.0.2
,当然是通的ping -I 10.0.0.2 172.16.0.2
,这种指定源 IP 的方式 ping,当然是不通的,同样问题,听包发现包没往 tun0 设备上走,而是往 enX0 上走了
- 跟各种 AI 掰扯,也被告知过 n 多需要检查的地方,比如 kernel 参数 rp_filter 啥的,都对,但都没啥意义,都查过 n 多遍了。
- 还在微信朋友圈里发了这个问题,看看朋友圈的卧龙凤雏有没有啥好一点的建议方法。回复基本上都有道理,但没有一个能给我灵感的。
问题原因
多番努力,虽然没有结果,但是慢慢还是明白了问题所在就是为什么从 10.0.0.2 出去按路由表应该往 tun0 上走的包却走到了 enX0 上?“这还是路由的问题“,我盖棺定论。
老想想不出为什么,于是就上网找了找 Linux 高级路由的资料看了看,突然想起来:Linux 系统里,路由选择上比路由表级别更高的还有一个:路由策略!柳暗花明呀。
我立马起来,登录上 EC2,
1 | ip rule s |
果然有一条记录:
10000: from 10.0.0.2 lookup 10000 proto static
果然有货,再接着看这条 id 是 10000 的路由表里有什么:
1 | ip r s table 10000 |
系统显示:
default via 10.0.0.1 dev enX0 proto dhcp metric 512
10.0.0.0/24 dev enX0 proto static scope link
这一下子逻辑就清晰了,源地址是 10.0.0.2、目标地址是 172.16.0.2 的数据包之所以会往 enX0 上走是因为路由策略 10000: from 10.0.0.2 lookup 10000 proto static
,这个策略规定了源地址是 10.0.0.2 的数据包怎么走要看路由表 10000,而在 10000 这张路由表又是这样的:
default via 10.0.0.1 dev enX0 proto dhcp metric 512
10.0.0.0/24 dev enX0 proto static scope link
按照这个路由表,去往 172.16.0.2 的数据包不妥妥的要往 enX0 上发吗?
问题验证
最后,我还要做最后一个测试,以验证我的结论:
1 | sudo ip r add 172.16.0.0/24 \ |
然后,那边在 B 上 ping 10.0.0.2
马上就通了。
最后的最后,我把刚加的这条路由删掉了,因为我还没想好要不要修以及怎么修这个问题。
1 | sudo ip r del 172.16.0.0/24 table 10000 |
结论
由于 Amazon Linux 2023 中在策略路由里将从 EC2 私网地址为源地址的数据包强制走了另外一张路由表,在那张表里源地址为 EC2 私网地址的数据包会走 enX0,而我的 OpenVPN 服务启动时只修改了缺省的路由表:main,故而导致从 OpenVPN 的客户端不能通 EC2 的私网地址。
所以,这到底是 Amazon Linux 2023 的 bug 呢,还是 OpenVPN 的 bug 呢?这个问题还需要进一步的探讨和研究。