Repository navigation
Verify source addresses of egress NAT traffic - #388
chez-shanpu wants to merge 2 commits into
Conversation
…ting packets from unknown peers Signed-off-by: Tomoki Sugiura <tomoki-sugiura@cybozu.co.jp>
a4a4b52 to
6f265c5
Compare
|
@chez-shanpu I have a suggestion about metrics.
|
Signed-off-by: Tomoki Sugiura <tomoki-sugiura@cybozu.co.jp>
|
@terassyi Thank you! I've addressed both of them. Can you take another look? |
Summary
This PR hardens egress NAT by verifying the source addresses of tunneled packets on both NAT servers and NAT clients.
NAT servers now accept packets only from registered client Pods, and only when the source address is the client Pod's own IP address.
NAT clients accept only returning packets of the connections they initiated.
The number of packets dropped by the source address verification on NAT servers is exported as metrics.
Changes
NAT server (coil-egress)
NatServer.AddClientinstalls a rule in both theFORWARDandINPUTchains. The rule drops packets from the client's FoU link unless their source address is the client Pod's IP address.-i fou4_<hex> ! -s <clientIP> -m comment --comment coil-peer-src-fou4_<hex> -j DROPiifname "fou4_<hex>" ip saddr != <clientIP> counter drop(tagged withcoil-peer-src-fou4_<hex>as UserData)NatServer.DelClientremoves the rule.podWatchercalls it right after deleting the FoU link.coil_ipip4/coil_ipip6), so they decapsulate packets only from registered peers.NAT client (coild)
NewFoUTunnelis split intoNewClientFoUTunnelandNewServerFoUTunnel.NatClientdrops new flows (ct state new) from the flow based devices in theFORWARDandINPUTchains.EgressWatchercalls the newNatClient.EnsureFlowBasedDevRulesso that client Pods that already exist get these rules when coild is upgraded.Metrics (coil-egress)
coil_egress_nftables_peer_src_dropped_packets_totalandcoil_egress_nftables_peer_src_dropped_bytes_total. They are the sums of the counters of the source address verification rules in theFORWARDandINPUTchains, with the same labels as the existing metrics.coil-invalid-drop(UserData for nftables, a comment for iptables).coil_egress_nftables_invalid_{packets,bytes}_totalfind the rule by the tag instead of taking the first rule with a counter in theFORWARDchain, so they no longer depend on the order of the rules.netfilterpackage asRuleTagInvalidDropandRuleTagPeerSrcPrefix.Docs
docs/usage.md.docs/cmd-coil-egress.md.Behavior changes
kube-proxy --masquerade-all, or for client Pod addresses outside--cluster-cidr.Tests
pkg/nat/netfilter: rule setup, idempotency and removal in both chains, and the tags of the rules.EnsureFlowBasedDevRulesis also tested without a priorInit.pkg/fou: tests for the client and server roles.pkg/metrics: unit tests for finding rules by tags (both the nftables UserData and the iptables comment) and summing their counters.pkg/test: integration tests checking that packets with an unexpected source address from a registered client, and FoU packets from an unregistered peer, are dropped.controllers: thenat.Servermock gainsDelClient, and the pod watcher tests now check that clients are unregistered.🤖 Generated with Claude Code