基于 IPv6 路由的 VPN 客户端与 Strongswan,数据包到达但未被应用程序接收

基于 IPv6 路由的 VPN 客户端与 Strongswan,数据包到达但未被应用程序接收

我正在尝试使用 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)。我们获得了路由器的更新,现在一切正常。

相关内容