fix(firecracker-netpool): per-TAP anti-spoof so source-IP attribution is sound (PR #354 review)
The /31 point-to-point TAP does NOT make a guest source address unspoofable: root in an agent VM can source another bottle's guest IP on its own bbfc TAP. The isolation table only matched iifname class + port (DNAT) and never bound iifname to its assigned ip saddr — so a spoofed source was DNAT'd to the gateway and attributed to the *victim* bottle, getting the victim's policy/tokens. Source-IP attribution was therefore not actually sound. Add one anti-spoof rule per slot in the isolation forward chain, before the established/DNAT accepts: `iifname bbfcN ip saddr != <guestN> drop`. Generated in the existing setup loop — no new dependency, ~pool_size lines. Legit traffic (correct saddr) is unchanged; a spoofed saddr on any bbfc TAP is dropped before it can be attributed. Apply with a nixos-rebuild (the systemd unit re-runs this script). Codex review blocker; the app-layer identity token (defense-in-depth) is wired separately. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck
This commit is contained in:
@@ -166,6 +166,19 @@ _install_nft() {
|
||||
# Delete-first (create empty, delete, recreate) so a re-applied `up`
|
||||
# lands identical state instead of appending rules / erroring on the
|
||||
# existing base chains — the setup is idempotent regardless of history.
|
||||
|
||||
# Anti-spoof: bind each TAP to its assigned guest IP. The /31 alone
|
||||
# does NOT make the source address unspoofable — root in an agent VM
|
||||
# can source another bottle's guest IP on its own bbfc TAP, and the
|
||||
# gateway attributes egress/policy/tokens by source IP. So drop any
|
||||
# packet whose source isn't the guest address assigned to the exact
|
||||
# TAP it arrived on, before it can be attributed. One rule per slot.
|
||||
local antispoof="" i
|
||||
for i in $(seq 0 $((POOL_SIZE-1))); do
|
||||
antispoof="${antispoof} iifname \"$(iface "$i")\" ip saddr != $(guest_ip "$i") drop
|
||||
"
|
||||
done
|
||||
|
||||
nft -f - <<EOF
|
||||
table inet $TABLE {}
|
||||
delete table inet $TABLE
|
||||
@@ -173,7 +186,7 @@ table inet $TABLE {
|
||||
chain forward {
|
||||
type filter hook forward priority -10; policy accept;
|
||||
iifname != "${PREFIX}*" return
|
||||
ct state established,related accept
|
||||
${antispoof} ct state established,related accept
|
||||
ct status dnat accept
|
||||
drop
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user