我正在尝试使用 strongswan 和 XFRM 接口以及 IPv6(端到端)设置带有基于路由的 VPN 隧道的 Linux 客户端 PC。
strongswan 5.8.2,Linux内核5.15.0
[题外话 - 我尝试使用所有 IPv4 地址(端到端)进行了相同的测试,一切正常]
客户端 PC 2001:3::3 <-> 2001:3::2 路由器 2001:4::2 <-> 2001:4::200 远程 PC
客户端电脑上的 swanctl.conf:
connections {
ipsec-ikev2-vpn {
version = 2
encap = no
dpd_delay = 300s
local_addrs = 2001:3::3
remote_addrs = 2001:3::2
proposals = aes256gcm16-sha384-prfsha384-ecp384
local {
id = Site_B
auth = pubkey
certs= ca.pem
}
remote {
auth = pubkey
}
children {
child1 {
mode = tunnel
local_ts = ::/0
remote_ts = ::/0
if_id_in = 99
if_id_out = 99
start_action = start
dpd_action = clear
esp_proposals = aes256gcm16
}
}
}
}
我在客户端 PC 上创建一个 XFRM 接口(enp4s0np0 是 2001:3::3 接口),为其指定一个 IPv6 地址,并配置到远程局域网的路由:
ip -6 link add xfrm-1 type xfrm dev enp4s0np0 if_id 99
ip -6 addr add 2001:2::1/128 dev xfrm-1
ip -6 link set xfrm-1 up
ip -6 route add 2001:4::/64 dev xfrm-1
然后我在客户端电脑上启动 strongswan,隧道就建立好了
现在问题是 - 当我尝试从客户端 PC ping 远程 PC 时,没有收到回复:
ping6 2001:4::200
PING 2001:4::200(2001:4::200) 56 data bytes
^C
--- 2001:4::200 ping statistics ---
773 packets transmitted, 0 received, 100% packet loss, time 790532ms
因此,我正在尝试找出 ping 不起作用的原因,并修复它...
XFRM 接口上的 tcpdump 显示回复正在到达(在客户端 PC 上):
tcpdump -i xfrm-1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on xfrm-1, link-type RAW (Raw IP), capture size 262144 bytes
13:16:00.352995 IP6 2001:2::1 > 2001:4::200: ICMP6, echo request, seq 39, length 64
13:16:00.353614 IP6 2001:4::200 > 2001:2::1: ICMP6, echo reply, seq 39, length 64
13:16:01.380979 IP6 2001:2::1 > 2001:4::200: ICMP6, echo request, seq 40, length 64
13:16:01.381378 IP6 2001:4::200 > 2001:2::1: ICMP6, echo reply, seq 40, length 64
13:16:02.400866 IP6 2001:2::1 > 2001:4::200: ICMP6, echo request, seq 41, length 64
13:16:02.401506 IP6 2001:4::200 > 2001:2::1: ICMP6, echo reply, seq 41, length 64
路由(在客户端电脑上):
ip -6 route show
::1 dev lo proto kernel metric 256 pref medium
2001:2::1 dev xfrm-1 proto kernel metric 256 pref medium
2001:3::/64 dev enp4s0np0 proto kernel metric 100 pref medium
2001:4::/64 dev xfrm-1 metric 1024 pref medium
fe80::/64 dev enp4s0np0 proto kernel metric 100 pref medium
fe80::/64 dev xfrm-1 proto kernel metric 256 pref medium
fe80::/64 dev wlo1 proto kernel metric 600 pref medium
数据包顺利通过隧道(客户端 PC):
ip -s xfrm state
src 2001:3::3 dst 2001:3::2
proto esp spi 0xcae27194(3403837844) reqid 1(0x00000001) mode tunnel
replay-window 0 seq 0x00000000 flag af-unspec (0x00100000)
aead rfc4106(gcm(aes)) 0xd8cd80445469ab67484a5b4e9e99ad3d3a55a6f1c131c6f8b82eb7648dbacf9844ab92f3 (288 bits) 128
anti-replay context: seq 0x0, oseq 0x362, bitmap 0x00000000
if_id 0x63
lifetime config:
limit: soft (INF)(bytes), hard (INF)(bytes)
limit: soft (INF)(packets), hard (INF)(packets)
expire add: soft 3571(sec), hard 3960(sec)
expire use: soft 0(sec), hard 0(sec)
lifetime current:
89840(bytes), 866(packets)
add 2023-11-27 13:14:54 use 2023-11-27 13:15:07
stats:
replay-window 0 replay 0 failed 0
src 2001:3::2 dst 2001:3::3
proto esp spi 0xcad3be8c(3402874508) reqid 1(0x00000001) mode tunnel
replay-window 32 seq 0x00000000 flag af-unspec (0x00100000)
aead rfc4106(gcm(aes)) 0x5f678c6577e6290566783d136ce67419eab8d989ef2a9085cbcfb7417a997cbf90899686 (288 bits) 128
anti-replay context: seq 0x35e, oseq 0x0, bitmap 0xffffffff
if_id 0x63
lifetime config:
limit: soft (INF)(bytes), hard (INF)(bytes)
limit: soft (INF)(packets), hard (INF)(packets)
expire add: soft 3353(sec), hard 3960(sec)
expire use: soft 0(sec), hard 0(sec)
lifetime current:
89600(bytes), 862(packets)
add 2023-11-27 13:14:54 use 2023-11-27 13:14:55
stats:
replay-window 3 replay 2 failed 0
没有 xfrm 错误统计(客户端电脑):
cat /proc/net/xfrm_stat
XfrmInError 0
XfrmInBufferError 0
XfrmInHdrError 0
XfrmInNoStates 0
XfrmInStateProtoError 0
XfrmInStateModeError 0
XfrmInStateSeqError 0
XfrmInStateExpired 0
XfrmInStateMismatch 0
XfrmInStateInvalid 0
XfrmInTmplMismatch 0
XfrmInNoPols 0
XfrmInPolBlock 0
XfrmInPolError 0
XfrmOutError 0
XfrmOutBundleGenError 0
XfrmOutBundleCheckError 0
XfrmOutNoStates 0
XfrmOutStateProtoError 0
XfrmOutStateModeError 0
XfrmOutStateSeqError 0
XfrmOutStateExpired 0
XfrmOutPolBlock 0
XfrmOutPolDead 0
XfrmOutPolError 0
XfrmFwdHdrError 0
XfrmOutStateInvalid 0
XfrmAcquireError 0
没有进行数据包过滤(客户端电脑):
ip6tables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
正在计数的数据包(客户端 PC):
ip6tables -v -n -L
Chain INPUT (policy ACCEPT 1999 packets, 316K bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all * * ::/0 ::/0
Chain OUTPUT (policy ACCEPT 2817 packets, 382K bytes)
pkts bytes target prot opt in out source destination
我认为这些政策看起来很合理(客户端 PC):
ip xfrm policy
src ::/0 dst ::/0
dir out priority 399999
tmpl src 2001:3::3 dst 2001:3::2
proto esp spi 0xcae27194 reqid 1 mode tunnel
if_id 0x63
src ::/0 dst ::/0
dir fwd priority 399999
tmpl src 2001:3::2 dst 2001:3::3
proto esp reqid 1 mode tunnel
if_id 0x63
src ::/0 dst ::/0
dir in priority 399999
tmpl src 2001:3::2 dst 2001:3::3
proto esp reqid 1 mode tunnel
if_id 0x63
src 0.0.0.0/0 dst 0.0.0.0/0
socket in priority 0
src 0.0.0.0/0 dst 0.0.0.0/0
socket out priority 0
src 0.0.0.0/0 dst 0.0.0.0/0
socket in priority 0
src 0.0.0.0/0 dst 0.0.0.0/0
socket out priority 0
src ::/0 dst ::/0
socket in priority 0
src ::/0 dst ::/0
socket out priority 0
src ::/0 dst ::/0
socket in priority 0
src ::/0 dst ::/0
socket out priority 0
监控输出(客户端电脑):
ip xfrm monitor
Async event (0x10) replay update
src 2001:3::3 dst 2001:3::2 reqid 0x1 protocol esp SPI 0xcae27194
Async event (0x10) replay update
src 2001:3::2 dst 2001:3::3 reqid 0x1 protocol esp SPI 0xcad3be8c
Async event (0x20) timer expired
src 2001:3::3 dst 2001:3::2 reqid 0x1 protocol esp SPI 0xcae27194
Async event (0x20) timer expired
src 2001:3::2 dst 2001:3::3 reqid 0x1 protocol esp SPI 0xcad3be8c
那么为什么 ping 应用程序收不到回复呢?我也尝试过通过隧道运行客户端/服务器应用程序 (iperf),结果相同,客户端 PC 上的 xfrm 接口接收到的传入数据包未被应用程序接收。
谢谢你!
答案1
更新 - 我们找到了问题所在。通过隧道发送的回复将 ESP Header 中的 Next Header 字段设置为值 IPIP (0x04),而不是预期值 IPv6 (0x29)。我们获得了路由器的更新,现在一切正常。