dir out mark
我在 xfrm 策略方面遇到了问题。我已经在 strongswan 配置中设置了mark_in
,mark_out
并建立了 ipsec 连接。我还添加了一些简单的 iptables 规则来标记数据包,并仅在匹配成功时进行检查(这仅用于测试目的,因此除了不匹配的 ipsec 相关数据包外,其他所有数据包都会被允许通过)。
eth3 连接到隧道此侧后面的客户端
eth8 用于隧道
StrongSwan配置:
connections {
tun_p1 {
local_addrs=1.1.1.2
remote_addrs=1.1.1.1
send_cert=never
unique=replace
version=2
mobike=no
keyingtries=5
dpd_delay=30
dpd_timeout=90
rekey_time=3600s
over_time=120s
rand_time=60
children {
tun_1 {
local_ts=3.3.3.0/24
remote_ts=2.2.2.0/24
mode=tunnel
ipcomp=no
dpd_action=trap
start_action=start
close_action=none
rekey_time=28800s
# Marks are here
mark_out=0x1000/0xff000
mark_in=0x100000/0x100000
}
}
local {
auth=psk
id=1.1.1.2
}
remote {
auth=psk
id=1.1.1.1
}
}
}
XFRM 政策:
root@ubuntu-24:~# ip xfrm policy
src 3.3.3.0/24 dst 2.2.2.0/24
dir out priority 375423
mark 0x1000/0xff000
tmpl src 1.1.1.2 dst 1.1.1.1
proto esp spi 0xc862dc7c reqid 1 mode tunnel
src 2.2.2.0/24 dst 3.3.3.0/24
dir fwd priority 375423
mark 0x100000/0x100000
tmpl src 1.1.1.1 dst 1.1.1.2
proto esp reqid 1 mode tunnel
src 2.2.2.0/24 dst 3.3.3.0/24
dir in priority 375423
mark 0x100000/0x100000
tmpl src 1.1.1.1 dst 1.1.1.2
proto esp reqid 1 mode tunnel
IPtables配置:
*raw
:PREROUTING ACCEPT
:OUTPUT ACCEPT
-A PREROUTING -i eth3 -j TRACE
COMMIT
*mangle
:PREROUTING ACCEPT
:POSTROUTING ACCEPT
:INPUT ACCEPT
:OUTPUT ACCEPT
:FORWARD ACCEPT
:IPsec -
-A PREROUTING -i eth8 -p esp -d 1.1.1.2 -s 1.1.1.1 -j MARK --set-mark 0x100000/0x100000
-A FORWARD -i eth3 -o eth8 -j MARK --set-mark 0x1000/0xff000
-A POSTROUTING -j IPsec
-A IPsec -m mark --mark 0x1000/0xff000 -m policy --dir out --pol ipsec --mode tunnel --tunnel-src 1.1.1.2 --tunnel-dst 1.1.1.1 -j RETURN
-A IPsec -m mark --mark 0x1000/0xff000 -j DROP
COMMIT
*nat
:PREROUTING ACCEPT
:POSTROUTING ACCEPT
:OUTPUT ACCEPT
COMMIT
*filter
:INPUT ACCEPT
:OUTPUT ACCEPT
:FORWARD ACCEPT
:PolicyFilterChain -
-A FORWARD -j PolicyFilterChain
-A PolicyFilterChain -m state --state NEW,ESTABLISHED,RELATED -m mark --mark 0x100000/0x100000 -m policy --dir in --pol ipsec --mode tunnel --tunnel-src 1.1.1.1 --tunnel-dst 1.1.1.2 -j ACCEPT
-A INPUT -i eth8 -p udp --sport 500 --dport 500 -d 1.1.1.1 -s 1.1.1.2 -j ACCEPT
-A INPUT -i eth8 -p esp -d 1.1.1.2 -s 1.1.1.1 -j ACCEPT
COMMIT
当我从隧道另一端发送数据包时,一切正常,我收到了响应。问题出在dir out
隧道这一侧的数据包上。我知道它们会被标记,因为它们在策略检查后会被规则丢弃,但它们与 xfrm 策略不匹配,即使我没有丢弃它们,它们也没有被 xfrm 加密。
如果我注释-A IPsec -m mark --mark 0x1000/0xff000 -j DROP
规则,则数据包将以未加密的形式发送到另一端,尽管数据包上设置了标记。
评论删除后追踪:
TRACE: raw:PREROUTING:policy:2 IN=eth3 OUT= MAC=00:50:56:9f:3d:99:00:50:56:9f:c8:bc:08:00 SRC=3.3.3.3 DST=2.2.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=42626 DF PROTO=ICMP TYPE=8 CODE=0 ID=2584 SEQ=1
TRACE: mangle:PREROUTING:policy:2 IN=eth3 OUT= MAC=00:50:56:9f:3d:99:00:50:56:9f:c8:bc:08:00 SRC=3.3.3.3 DST=2.2.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=42626 DF PROTO=ICMP TYPE=8 CODE=0 ID=2584 SEQ=1
TRACE: nat:PREROUTING:policy:1 IN=eth3 OUT= MAC=00:50:56:9f:3d:99:00:50:56:9f:c8:bc:08:00 SRC=3.3.3.3 DST=2.2.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=42626 DF PROTO=ICMP TYPE=8 CODE=0 ID=2584 SEQ=1
TRACE: mangle:FORWARD:rule:1 IN=eth3 OUT=eth8 MAC=00:50:56:9f:3d:99:00:50:56:9f:c8:bc:08:00 SRC=3.3.3.3 DST=2.2.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=42626 DF PROTO=ICMP TYPE=8 CODE=0 ID=2584 SEQ=1
TRACE: mangle:FORWARD:policy:2 IN=eth3 OUT=eth8 MAC=00:50:56:9f:3d:99:00:50:56:9f:c8:bc:08:00 SRC=3.3.3.3 DST=2.2.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=42626 DF PROTO=ICMP TYPE=8 CODE=0 ID=2584 SEQ=1 MARK=0x1000
TRACE: filter:FORWARD:rule:1 IN=eth3 OUT=eth8 MAC=00:50:56:9f:3d:99:00:50:56:9f:c8:bc:08:00 SRC=3.3.3.3 DST=2.2.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=42626 DF PROTO=ICMP TYPE=8 CODE=0 ID=2584 SEQ=1 MARK=0x1000
TRACE: filter:PolicyFilterChain:return:3 IN=eth3 OUT=eth8 MAC=00:50:56:9f:3d:99:00:50:56:9f:c8:bc:08:00 SRC=3.3.3.3 DST=2.2.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=42626 DF PROTO=ICMP TYPE=8 CODE=0 ID=2584 SEQ=1 MARK=0x1000
TRACE: filter:FORWARD:policy:2 IN=eth3 OUT=eth8 MAC=00:50:56:9f:3d:99:00:50:56:9f:c8:bc:08:00 SRC=3.3.3.3 DST=2.2.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=42626 DF PROTO=ICMP TYPE=8 CODE=0 ID=2584 SEQ=1 MARK=0x1000
TRACE: mangle:POSTROUTING:rule:1 IN=eth3 OUT=eth8 MAC=00:50:56:9f:3d:99:00:50:56:9f:c8:bc:08:00 SRC=3.3.3.3 DST=2.2.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=42626 DF PROTO=ICMP TYPE=8 CODE=0 ID=2584 SEQ=1 MARK=0x1000
TRACE: mangle:IPsec:return:2 IN=eth3 OUT=eth8 MAC=00:50:56:9f:3d:99:00:50:56:9f:c8:bc:08:00 SRC=3.3.3.3 DST=2.2.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=42626 DF PROTO=ICMP TYPE=8 CODE=0 ID=2584 SEQ=1 MARK=0x1000
TRACE: mangle:POSTROUTING:policy:2 IN=eth3 OUT=eth8 MAC=00:50:56:9f:3d:99:00:50:56:9f:c8:bc:08:00 SRC=3.3.3.3 DST=2.2.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=42626 DF PROTO=ICMP TYPE=8 CODE=0 ID=2584 SEQ=1 MARK=0x1000
TRACE: nat:POSTROUTING:policy:1 IN=eth3 OUT=eth8 MAC=00:50:56:9f:3d:99:00:50:56:9f:c8:bc:08:00 SRC=3.3.3.3 DST=2.2.2.2 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=42626 DF PROTO=ICMP TYPE=8 CODE=0 ID=2584 SEQ=1 MARK=0x1000
TCP转储:
root@ubuntu-24:~# tcpdump -i eth8 proto 50 or host 3.3.3.3 -nn
17:58:41.992237 IP 3.3.3.3 > 2.2.2.2: ICMP echo request, id 2603, seq 1, length 64
^C
1 packet captured
1 packet received by filter
0 packets dropped by kernel
反转就可以了:
root@ubuntu-24:~# tcpdump -i eth8 proto 50 or host 3.3.3.3 -nn
18:00:04.880886 IP 1.1.1.1 > 1.1.1.2: ESP(spi=0xc98cba8d,seq=0x2), length 136
18:00:04.881265 IP 2.2.2.2 > 3.3.3.3: ICMP echo request, id 59100, seq 1, length 64
18:00:04.882554 IP 3.3.3.3 > 2.2.2.2: ICMP echo reply, id 59100, seq 1, length 64
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
我知道问题出在mark_out
,因为如果我对其进行评论,一切都会按预期进行,但我需要标记。
标记
FORWARD
太晚了。出站 IPsec 策略查找在路由决策做出之前就已经发生了。虽然某些数据包操作会导致新的路由决策和策略查找(例如 中的 NAT
POSTROUTING
或在 中设置标记),但在或OUTPUT
中设置标记时情况并非如此。FORWARD
POSTROUTING
因此您必须标记这些数据包
PREROUTING
。还要注意,这
-m policy
有点用词不当。它实际上并没有进行显式的 IPsec 策略查找。它只是根据分配给数据包的 IPsec 状态进行匹配,因此只有事先进行过策略查找才会生效。