手动配置IPsec NAT-T后捕获espinudp包但XFRM不工作的问题
手动配置IPsec NAT-T后的数据包处理问题
环境拓扑与配置说明
我手动配置了IPsec NAT-T,拓扑如下:
----------------------------------------------(公网) | +-|---------------------+ | |eth0 192.168.100.123/24| (iptables -A POSTROUTING -s | | R2 | 10.10.0.0/16 -j SNAT +-|-------------------+ |br0 10.10.0.254/16| --to-source 192.168.100.123) |eth0 192.168.100.2/24|--IPSec +-|---------------------+ | R1 | SA---| | (默认路由指向10.10.0.254) |br0 172.16.10.254/24| | +-|---------------------+ +-|-------------------+ |---|e1 10.10.0.1/16 (vm1)| (内网172.16.10.0/24)===IPSec隧道==+-----------------------+
- R1和R2拥有
192.168.100.0/24网段的公网IP - R1连接内网
172.16.10.0/24,R2连接内网10.10.0.0/16 - vm1是R2下的虚拟机,IP为
10.10.0.1/16 - vm1尝试通过IPsec NAT-T访问
172.16.10.0/24网段 - 使用脚本维持NAT存活
关键系统输出信息
R2上的连接跟踪信息
root@i-q6fcsdt9:~# conntrack -L | grep udp | grep 10.10.0.1 conntrack v1.4.6 (conntrack-tools): 3 flow entries have been shown. udp 17 26 src=10.10.0.1 dst=192.168.100.2 sport=4500 dport=4500 src=192.168.100.2 dst=192.168.100.123 sport=4500 dport=18984 mark=0 use=1
R1的XFRM状态与策略
[root@i-pi6sxtgz ~]# ip x s src 192.168.100.123 dst 192.168.100.2 proto esp spi 0x529561e0 reqid 40820 mode tunnel replay-window 0 flag af-unspec auth-trunc hmac(sha256) 0x9ae03071952c554f39767a1b958eeb53 96 enc cbc(aes) 0xc3c404f5719867fc70d4034dbdec24bf encap type espinudp sport 18984 dport 4500 addr 0.0.0.0 anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000 src 192.168.100.2 dst 192.168.100.123 proto esp spi 0x8f0e56d9 reqid 39005 mode tunnel replay-window 0 flag af-unspec auth-trunc hmac(sha256) 0x9da46b46ed7c637863662adf2aa5bafc 96 enc cbc(aes) 0x64f7f3366bb6d38c268dae7aef579e9b encap type espinudp sport 4500 dport 18984 addr 0.0.0.0 anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000 [root@i-pi6sxtgz ~]# ip x p src 10.10.0.0/16 dst 172.16.10.0/24 dir fwd priority 0 ptype main tmpl src 192.168.100.123 dst 192.168.100.2 proto esp reqid 40820 mode tunnel src 10.10.0.0/16 dst 172.16.10.0/24 dir in priority 0 ptype main tmpl src 192.168.100.123 dst 192.168.100.2 proto esp reqid 40820 mode tunnel src 172.16.10.0/24 dst 10.10.0.0/16 dir out priority 0 ptype main tmpl src 192.168.100.2 dst 192.168.100.123 proto esp reqid 39005 mode tunnel
vm1的XFRM状态与策略
root@i-q6fcsdt9:~# ip x s src 192.168.100.2 dst 10.10.0.1 proto esp spi 0x8f0e56d9 reqid 39005 mode tunnel replay-window 0 flag af-unspec auth-trunc hmac(sha256) 0x9da46b46ed7c637863662adf2aa5bafc 96 enc cbc(aes) 0x64f7f3366bb6d38c268dae7aef579e9b encap type espinudp sport 4500 dport 4500 addr 0.0.0.0 anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000 src 10.10.0.1 dst 192.168.100.2 proto esp spi 0x529561e0 reqid 40820 mode tunnel replay-window 0 flag af-unspec auth-trunc hmac(sha256) 0x9ae03071952c554f39767a1b958eeb53 96 enc cbc(aes) 0xc3c404f5719867fc70d4034dbdec24bf encap type espinudp sport 4500 dport 4500 addr 0.0.0.0 anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000 root@i-q6fcsdt9:~# ip x p src 172.16.10.0/24 dst 10.10.0.0/16 dir fwd priority 0 tmpl src 192.168.100.2 dst 10.10.0.1 proto esp reqid 39005 mode tunnel src 172.16.10.0/24 dst 10.10.0.0/16 dir in priority 0 tmpl src 192.168.100.2 dst 10.10.0.1 proto esp reqid 39005 mode tunnel src 10.10.0.0/16 dst 172.16.10.0/24 dir out priority 0 tmpl src 10.10.0.1 dst 192.168.100.2 proto esp reqid 40820 mode tunnel
vm1 ping测试时的XFRM监控输出
root@i-q6fcsdt9:~# ip x monitor Async event (0x10) replay update src 10.10.0.1 dst 192.168.100.2 reqid 0x9f74 protocol esp SPI 0x529561e0
R1上的数据包捕获与XFRM监控结果
R1上捕获到了ESP-in-UDP包,但ip x monitor无输出:
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 16:40:06.078445 52:54:96:c6:c0:9f > 52:54:96:47:db:c1, ethertype IPv4 (0x0800), length 174: (tos 0x0, ttl 63, id 18250, offset 0, flags [DF], proto UDP (17), length 160) 192.168.100.123.18984 > 192.168.100.2.4500: UDP-encap: ESP(spi=0x529561e0,seq=0x85), length 132
[root@i-pi6sxtgz ~]# ip x monitor ^C [root@i-pi6sxtgz ~]#
R1上的端口占用情况
保活脚本绑定了UDP 0.0.0.0:4500:
[root@i-pi6sxtgz ~]# ss -anpu | grep 4500 UNCONN 213760 0 0.0.0.0:4500 0.0.0.0:* users:((\"python3\",pid=39241,fd=3))
核心疑问
- 当ESP-in-UDP包到达R1时发生了什么?
- R1上绑定UDP
0.0.0.0:4500的保活脚本是否会导致XFRM状态失效?
问题分析与解答
核心原因:用户态进程抢占了UDP 4500端口
Linux内核中,IPsec NAT-T的ESP-in-UDP封装数据包是由内核XFRM子系统在IP层处理之前进行解封装的。但如果有用户态进程(这里是Python保活脚本)先绑定了UDP 4500端口,根据Linux套接字的优先级规则,用户态进程会优先接收发送到该端口的数据包,导致内核XFRM子系统根本无法看到这些ESP-in-UDP包,因此:
ip x monitor没有任何输出(XFRM子系统未处理到数据包)- 数据包无法被解封装,也就无法转发到R1的内网网段
172.16.10.0/24
验证与解决方法
- 临时验证:停止R1上绑定UDP 4500的Python脚本,重新在vm1执行ping测试,检查R1的
ip x monitor是否有输出,同时确认内网是否能收到响应。 - 长期解决:修改保活脚本,避免绑定
0.0.0.0:4500端口。可以改为绑定特定IP(比如R1的公网IP192.168.100.2),或者使用其他非4500的端口来维持NAT会话。另外,IPsec NAT-T本身有Keepalive机制(RFC 3948),可以考虑用内核原生的NAT-T Keepalive替代自定义脚本。
内容的提问来源于stack exchange,提问作者Shawn Lu
相关产品推荐
相关产品推荐

