feat(ebpf): filter IPv6 egress (close the v6 bypass)#60
Merged
Conversation
The kernel guard only enforced IPv4 — non-IPv4 packets passed, so a tool could exfiltrate over IPv6 and defeat the "unbypassable" egress claim. Now both families are default-deny. eBPF: new ALLOW6 map (u128 key = u128::from(Ipv6Addr)); the program branches on IP version and, for v6, loads the 16-byte destination as two u64 halves (64-bit ops keep the verifier happy). Loopback (::1) and infra prefixes (link-local fe80::/10, multicast ff00::/8) always pass, mirroring the v4 loopback exception. Control plane: `allow` / `allow-domain` / the admin socket / policy lowering all accept v4 and v6. Domain resolution injects both families into ALLOW / ALLOW6; allow_insert/remove/list are IpAddr-based. Tests: pasu-rules v6 lowering; admin v6 parse; an IPv6 kernel E2E (self-skips without v6 connectivity — GitHub runners have none — but exercises the v6 path on a v6-capable host; the v4 E2E already proves the updated program verifies). Signed-off-by: Ho Geun Choi <ohyes9711@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Gap
The kernel guard only enforced IPv4 — non-IPv4 packets passed, so a tool could exfiltrate over IPv6 and defeat the "unbypassable egress" claim. (Found in a hardening audit; was documented as a known gap.) Now both families are default-deny.
eBPF
ALLOW6map (u128key =u128::from(Ipv6Addr)).u64halves (64-bit ops only → verifier-friendly), builds theu128key.::1and infra prefixes (link-localfe80::/10, multicastff00::/8) always pass — mirrors the v4 loopback exception so basic v6 networking (NDP) keeps working.Control plane
allow/allow-domain/ admin socket / policy lowering all accept v4 and v6. Domain resolution injects both families;allow_insert/remove/listareIpAddr-based;EgressAllowlistgainsips6,GuardConfiggainsallow6.Tests
ips6.allow 2606:4700:4700::1111,deny ::1).egress_e2e): allowlisted v6 connects / non-allowlisted v6 dropped. Self-skips without v6 connectivity — GitHub runners have no IPv6, so it skips there; it exercises the v6 path on a v6-capable host. The existing v4 E2E already proves the updated eBPF program (ALLOW6 map + v6 branch) loads and verifies on the CI kernel.Docs (README ko/en · deployment.md · CHANGELOG) updated: v4+v6 default-deny, infra prefixes pass.