Estou com um problema com dir out mark
a política do XFRM. Configurei mark_in
o mark_out
StrongSwan e estabeleci uma conexão IPsec. Também adicionei algumas regras simples do IPTables para marcar pacotes e verificar apenas se a correspondência funciona (é apenas para fins de teste, então permite tudo, exceto os pacotes relacionados ao IPsec que não correspondem) .
eth3 está conectado aos clientes deste lado do túnel
eth8 é usado para o túnel
Configuração do 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
}
}
}
Política 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
Configuração do 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
Quando envio pacotes do outro lado do túnel, tudo funciona bem e recebo a resposta. O problema está nos dir out
pacotes deste lado do túnel. Sei que eles recebem a marca, pois são descartados pela regra após a verificação da política, mas não correspondem à política do XFRM e, mesmo que eu não os descarte, eles não são criptografados pelo XFRM.
Se eu comentar -A IPsec -m mark --mark 0x1000/0xff000 -j DROP
a regra, o pacote é enviado para o outro lado sem criptografia, embora a marca esteja definida no pacote.
Rastreamento após queda de comentário :
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
Despejo 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
O inverso está ok:
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
Eu sei que o problema é com mark_out
, porque se eu comentar, tudo funciona como esperado, mas preciso marcar.
A marcação de entrada
FORWARD
é muito tardia. A consulta da política IPsec de saída ocorre antes disso, quando a decisão de roteamento é tomada.Embora algumas manipulações de pacotes causem uma nova decisão de roteamento e consulta de política (como um NAT em
POSTROUTING
ou a definição de uma marca emOUTPUT
), esse não é o caso ao definir uma marca emFORWARD
ouPOSTROUTING
.Então você tem que marcar esses pacotes em
PREROUTING
.Observe também que esse
-m policy
é um nome um tanto impróprio. Ele não realiza, de fato, uma consulta explícita de política IPsec. Ele compara com os estados IPsec atribuídos ao pacote, portanto, só tem efeito se uma consulta de política já tiver ocorrido anteriormente.