Found in review of #370.
lnvps_node/src/fw.rs:533-560 builds the input chain in this order:
iif lo accept
ct state {established,related} accept
iif br-lnvps jump source (the anti-spoof check)
The forward chain deliberately does the opposite — the anti-spoof jump comes first, with the comment "Checked before anything else, including established connections" (fw.rs:455-470) — and lnvps_node/src/fw/tests.rs:248-269 asserts that ordering for forward only.
Conntrack lookup is interface-agnostic, so a guest that spoofs the route server's source address and matches an existing LNVPS↔node flow is accepted by rule 2 without ever reaching the source-address check: TCP injection or reset against a live control-API or libvirt session.
Fix is the same as the forward chain — jump to the source check before the conntrack accept — plus the mirror test, whose absence is why the two chains drifted.
Found in review of #370.
lnvps_node/src/fw.rs:533-560builds theinputchain in this order:iif lo acceptct state {established,related} acceptiif br-lnvps jump source(the anti-spoof check)The
forwardchain deliberately does the opposite — the anti-spoof jump comes first, with the comment "Checked before anything else, including established connections" (fw.rs:455-470) — andlnvps_node/src/fw/tests.rs:248-269asserts that ordering forforwardonly.Conntrack lookup is interface-agnostic, so a guest that spoofs the route server's source address and matches an existing LNVPS↔node flow is accepted by rule 2 without ever reaching the source-address check: TCP injection or reset against a live control-API or libvirt session.
Fix is the same as the
forwardchain — jump to the source check before the conntrack accept — plus the mirror test, whose absence is why the two chains drifted.