Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firewall is not working for IPSec NAT-T #53

Open
kouhj opened this issue Mar 2, 2025 · 8 comments
Open

Firewall is not working for IPSec NAT-T #53

kouhj opened this issue Mar 2, 2025 · 8 comments

Comments

@kouhj
Copy link

kouhj commented Mar 2, 2025

Tested two OpenWRT 24.10 routers to setup a site to site IPSec connection with Strongswan when the WAN interfaces are over NATed network. After the firewall config were modified to accept the incoming ESP protocol and UDP 500, 4500 ports on the WAN interface (The default config of OpenWRT, which accepts redirecting ESP and UDP 500 to LAN, does not seem to work even to establish the connection), the two routers were able to establish the IPSec connection, and the following commands all reported normal results:
swanctl --list-sas
ip xfrm state
ip xfrm policy
ip route show table 220

BUT the normal site to site traffic just can get through when tested with ping.
If the firewall is stopped on the router that initiates the ping, it worked just fine to reach the other router. And unreachable again if the firewall is re-enabled.

Followed these articles,
https://docs.strongswan.org/docs/latest/howtos/forwarding.html
https://docs.strongswan.org/docs/latest/howtos/trafficDumps.html
and found that the LAN traffic can pass the postrouting chain of the mangle table with this command iptables -t mangle -I POSTROUTING -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5. The key seems how to add a nftables rule in POSTROUTING chain of the nat table like the command iptables -t nat -I POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT pointed out in the Strongswan doc mentioned above.

Tried the following and no luck:
nft insert rule inet fw4 srcnat oif WAN ipsec out reqid 1 counter accept
nft insert rule inet fw4 mangle_postrouting oif WAN ipsec out reqid 1 counter accept

The reqid 1 is confirmed with swanctl --list-sas

Any ideas how to make IPSec NAT-T work with fw4? Thanks!

@brada4
Copy link

brada4 commented Mar 2, 2025

Does iptables-translate (or iptables-nft) do the conversion for you?
https://git.netfilter.org/iptables/tree/extensions/libxt_policy.txlate

@kouhj
Copy link
Author

kouhj commented Mar 3, 2025

No. this tools does not work:
iptables-translate -t mangle -I POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT
nft # -t mangle -I POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT

I did the conversion by myself as in the previous post by adding a rule to mangle_postrouting chain or srcnat before the masquerading. The rule can be added but it did not ACCEPT the packet before it SNAT the sender IP, so the original unencapsulated packet was sent to the WAN device. So the IPSec communication failed.

@brada4
Copy link

brada4 commented Mar 3, 2025

Maybe something like meta ipsec exists meta ipsec missing ?

@brada4
Copy link

brada4 commented Mar 3, 2025

Also meta secpol 0|1 might be related, check if combination works.
Proper chain-prepend is to make a file like this, repeating hook spec of particular chain. The dynamic zone chains are not guaranteed to be there.

chain input {
 policy idem hook idem priority idem;
 iif "lo" meta idunno exists accept/return
}

And save it to /etc/nftables.d/something.nft , kept over sysupgrade unlike other options.
Probably best practice dummy is some general use linux latest version, OpenWrt has every rarely used ipt or nft keyword as a separate kmos/iptables-mod/nft-mod, so first get syntax right then add modules to match.

@kouhj
Copy link
Author

kouhj commented Mar 3, 2025

Following this article: https://thermalcircle.de/doku.php?id=blog:linux:nftables_demystifying_ipsec_expressions, I stopped firewall4 and import the following nft rules and it worked just fine.

table ip nat {
        chain postrouting {
                type nat hook postrouting priority srcnat; policy accept;
                oif  $WANDEV ipsec out reqid 1 accept
                oif $WANDEV masquerade
        }
}
table ip filter {
        chain forward {
                type filter hook forward priority filter; policy drop;
                iif br-lan oif $WANDEV accept
                iif $WANDEV oif br-lan ct state established,related accept
                iif $WANDEV oif br-lan ipsec in reqid 1 ct state new accept
        }
}

So next step is how to integrate with firewall...

@kouhj
Copy link
Author

kouhj commented Mar 3, 2025

Finally managed to make it work by adding a custom nft rule:

cat  > /etc/nftables.d/20-ipsec-natt.nft <<EOF
chain srcnat_wan {
        ipsec out reqid 1 counter accept
}

chain forward_wan {
        ipsec in reqid 1 ct state new accept
}
EOF

Good for a simple setup, but still something to do for multiple connections.
Thanks a lot!

@brada4
Copy link

brada4 commented Mar 3, 2025

Probably worth researching how to integrate rules into firewalld and amending strongswan docs with Your translation.

@brada4
Copy link

brada4 commented Mar 3, 2025

multiple interfaces - prepend rulw iif {$wan_devices, $wwan_devices } filter your way. There is no "multiple source zones" option in fw4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants