nixos/firewall: fix reverse path check failures with IPsec

The endpoint of an IPsec tunnel receives encrypted IPsec packets that
are first decrypted and then forwarded to the intended destination.
The decrypted traffic appears to originate from the same interface it
came in from, so in most cases these packets will fail the reverse path
check even if legitimate.

This change adds an exception to not reject packets that were previously
IPsec-encrypted, meaning the have been accepted, decrypted and are in
the process of being forwarded to their final destinal.

Sources:

  - https://www.kernel.org/doc/Documentation/networking/xfrm_device.txt
  - https://git.netfilter.org/nftables/commit/?id=49f6e9a846c6c8325b95debe04d5ebc3c01246fb
  - https://git.netfilter.org/nftables/commit/?id=8f55ed41d007061bd8aae94fee2bda172c0e8996
  - https://thermalcircle.de/doku.php?id=blog:linux:nftables_demystifying_ipsec_expressions
This commit is contained in:
rnhmjoj 2024-05-09 20:53:46 +02:00
parent 591aaa3f60
commit 3c12ef3f21
No known key found for this signature in database
GPG Key ID: BFBAF4C975F76450
2 changed files with 9 additions and 0 deletions

View File

@ -123,6 +123,9 @@ let
# Allows this host to act as a DHCP4 client without first having to use APIPA
iptables -t mangle -A nixos-fw-rpfilter -p udp --sport 67 --dport 68 -j RETURN
# Allows decrypted packets from an IPsec VPN
ip46tables -t mangle -A nixos-fw-rpfilter -m policy --dir in --pol ipsec -j RETURN
# Allows this host to act as a DHCPv4 server
iptables -t mangle -A nixos-fw-rpfilter -s 0.0.0.0 -d 255.255.255.255 -p udp --sport 68 --dport 67 -j RETURN

View File

@ -82,6 +82,11 @@ in
}
];
networking.nftables.preCheckRuleset = ''
# can't validate IPsec rules
sed '/meta ipsec/d' -i ruleset.conf
'';
networking.nftables.tables."nixos-fw".family = "inet";
networking.nftables.tables."nixos-fw".content = ''
${optionalString (cfg.checkReversePath != false) ''
@ -89,6 +94,7 @@ in
type filter hook prerouting priority mangle + 10; policy drop;
meta nfproto ipv4 udp sport . udp dport { 67 . 68, 68 . 67 } accept comment "DHCPv4 client/server"
meta ipsec exists accept comment "decrypted packets from an IPsec VPN"
fib saddr . mark ${optionalString (cfg.checkReversePath != "loose") ". iif"} oif exists accept
jump rpfilter-allow