feat: add --drop-cidr for VM egress isolation#4
Conversation
6ba6510 to
8cf0862
Compare
|
Rebased onto
Same-node isolation was silently fail-open. Same-node VMs share Also folded in: drop CIDRs validated + canonicalized ( One design call left to you — rule lifecycle. It's still add-only: there's no iptables |
VM-to-VM isolation no longer asks operators to restate the cocoon subnet as a --drop-cidr: --drop-internal-access derives the FORWARD DROP target from the subnet cocoon already knows. --drop-cidr now covers only external ranges (e.g. management networks). Same-node VMs share cni0 and are L2-switched, which bypasses iptables unless bridge-nf-call-iptables=1. Node setup now loads br_netfilter and enables it (verifying, failing closed) whenever a drop target is set, so the isolation is never silently a no-op. Drop CIDRs are validated and canonicalized up front; IPv6 is rejected. The DROP rules are tagged cocoon-net-drop so teardown removes exactly them.
8cf0862 to
4031547
Compare
|
Update — CMGS okayed adding the rule lifecycle, so it's no longer add-only:
One gotcha worth recording: the tag uses a hyphen, not a colon. Still one commit, build + lint green on linux and darwin. |
What
Adds a
--drop-cidrflag (repeatable, on bothinitandadopt) that blocks VM-originated traffic to a destination CIDR. It is persisted topool.jsonand reapplied by the daemon asFORWARDDROP rules inserted at the head of the chain.This gives cocoon VMs egress isolation: a single
--drop-cidr 172.20.0.0/16cuts all VM-to-VM (same- and cross-node, sincebridge-nf-call-iptables=1routes bridged traffic throughFORWARD), and--drop-cidr 10.0.0.0/8cuts access to internal/VPC management ranges — while internet egress and return traffic are unaffected.How it's wired
iptInserthelper, symmetric toiptEnsure, idempotent (Existscheck) and inserts at position 1 so DROP precedes the accept rules.net.ParseCIDRbefore any rule is applied, so a bad value failsinitbeforepool.jsonis written.dropCIDRsisomitempty— existingpool.jsonwithout the field decodes to nil = no drops (backward compatible).Why this is add-only (not reconciling) for now
Intentional, for consistency with the existing iptables code.
setupIPTablesalready usesiptEnsure(append +Existscheck) and never deletes — e.g. changing--subnetleaves the oldMASQUERADE -s <old>rule behind until the next reboot reapplies from current config. The new DROP rules follow the same semantics.Note the asymmetry that already exists in cocoon-net: the cloud-side alias does reconcile (
assignAliasIPreplaces the stalecocoon-podsentry on the node), but host iptables does not. Making the drop rules declarative in isolation would be inconsistent with the surroundingMASQUERADE/FORWARDrules; a proper fix would convert the wholesetupIPTablesto a managed chain (flush + rebuild covering MASQUERADE + FORWARD + drops). That is out of scope here and left as a follow-up.Scenarios covered
--manage-iptables=false(default) skips local iptables but persistsDropCIDRs; the daemon enforces them.--manage-iptables=trueapplies immediately.INPUT, notFORWARD, so--drop-cidrdoes not cover it — documented in the README.Testing
make lint(GOOS=linux + GOOS=darwin): 0 issues.go build ./...+go vet ./...: clean on both platforms.