feat: Stop emitting iptables errors on dual-stack hosts; add IPv6 sandbox support#10
Merged
Conversation
Hosts with both v4 and v6 nameservers in resolv.conf (Fedora 43 + IPv6 routers being a common case) caused the sandbox startup script to run `iptables -A OUTPUT -d <v6-addr>`, which iptables rejects with "host/network not found". Sandbox still worked (v4 path was unaffected), but two error lines printed at every launch. Split the resolv.conf nameserver list by address family and only feed the v4 entries to iptables. v6 entries are logged but otherwise dropped — the sandbox is IPv4-only by design (slirp4netns IPv4 NAT only, iptables-only rules), so those nameservers were never reachable from inside the sandbox anyway. This is the symptom fix. Adding actual IPv6 sandbox support is the follow-up commit on this branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends the network-filtered sandbox to also filter IPv6 egress on hosts
that support it. The v4 path is unchanged; v6 is enabled when both
conditions hold:
- kernel v6 is enabled (/proc/sys/net/ipv6/conf/all/disable_ipv6 == 0)
- ip6tables is on PATH
Either missing → sandbox stays v4-only (status quo). A partial v6 filter
would leave the sandbox with v6 connectivity and no egress rules, which
is worse than no v6 at all.
Changes:
- slirp4netns invoked with --enable-ipv6 when supported (both the
unshare-orchestration shell path and the bwrap+exec.Command path)
- resolv.conf inside sandbox gets `nameserver fd00::3` (slirp4netns v6
forwarder) alongside 10.0.2.3 when v6 is on
- parallel ip6tables ruleset mirroring iptables: loopback, DNS port 53,
allowed v6 nameservers, AAAA-resolved AllowNet hosts (via getent
ahostsv6), final REJECT with icmp6-adm-prohibited
- doctor reports ip6tables and surfaces the chosen v6/v4-only mode
- sandbox script prelude (tap0 wait, resolv.conf bind) extracted to
shared helpers to cut duplication between the unshare and bwrap paths
Manually verified on Fedora 42 (host has v4+v6 nameservers in resolv.conf,
which was the issue #8 repro shape): startup is silent, ip6tables OUTPUT
chain ends with REJECT, iptables OUTPUT chain ends with REJECT.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
StructLint — All checks passed78 rules validated against
|
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Jun 8, 2026
machado144
added a commit
that referenced
this pull request
Jun 8, 2026
…ng PRs (#11) ## What Two CI-health fixes surfaced while merging #9 and #10: ### 1. `vuln` was genuinely red — bump Go 1.25.10 → 1.25.11 `govulncheck` found two **reachable** stdlib vulnerabilities, newly reachable once #9 added the dashboard HTTP server (`internal/web/server.go:75`): | Vuln | Package | Fixed in | |------|---------|----------| | GO-2026-5039 | `net/textproto` | go1.25.11 | | GO-2026-5037 | `crypto/x509` | go1.25.11 | Bumping the `go` directive to `1.25.11` clears both. ### 2. `review` step → `continue-on-error` The `review` job (advisory `reviewforge` AI review) has been failing on an **expired `GEMINI_API_KEY`**. It isn't a required check, but a hard failure leaves a red ✗ and pushes PRs into `UNSTABLE`/`BLOCKED` merge state. Marking the step `continue-on-error` keeps it informational without gating merges. > Note: this only stops it *blocking*. `GEMINI_API_KEY` still needs renewing for reviews to actually run again. ## Verified locally (go1.25.11 toolchain) - `go test -short ./...` — pass - `govulncheck ./...` — **0 vulnerabilities affecting the code** (was 2) Lint/test are unaffected by a go-directive bump and a workflow YAML change. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
machado144
added a commit
that referenced
this pull request
Jun 8, 2026
## What A docs audit + refresh to bring all four user-facing doc surfaces back in sync with what actually ships. Recent PRs (dashboard #9, IPv6 #10, Go bump #11, and earlier masking) added features and changed defaults that never made it into the docs. Kept it useful and tight — no bloat, just fixing what was missing or wrong. ## Gaps fixed | Area | Before | After | |------|--------|-------| | `aigate serve` / web dashboard | undocumented everywhere | documented in README, user guide, AI ref, `help-ai` | | Audit log (`~/.aigate/audit.jsonl`) | undocumented | own section in user guide + `help-ai`, with event examples | | Default config example (user guide) | missing `*.p12`, `terraform.tfstate`, `*.tfvars`, `ncat/netcat/rsync/ftp`, `registry.npmjs.org`, `proxy.golang.org`, and the whole `mask_stdout` block | matches `InitDefaultConfig` | | `aws_secret` preset | absent (docs said "5 presets") | added; correct description (`AWS_SECRET_ACCESS_KEY=` match), "6 presets" | | Go version | badge `1.24+`, "From Source (Go 1.24+)" | `1.25+` (go.mod is 1.25.11) | | README Features | claimed cgroups resource limits are **enforced** | removed — the user guide correctly notes they're *not yet* enforced | | AI architecture map | missing `audit_service.go`, `masker.go`, `internal/web/`, `setup.go`, `help_ai.go`, escape tests | added, plus a note on the append-only audit log + read-only dashboard design | | `help-ai` | no `doctor`, no `serve`/dashboard | added `doctor` to setup + a DASHBOARD & AUDIT LOG section | ## Files - `README.md` - `docs/user/README.md` - `docs/AI/README.md` - `actions/help_ai.go` (the `aigate help-ai` output) ## Verified - `go build ./...` and `go test -short ./...` pass - pre-commit hooks green: structlint, gofmt, govet, golangci-lint 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.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.
Closes #8.
What
iptables; closes the noise from ipv6 error with nftables #8.slirp4netns --enable-ipv6+ parallelip6tableschain (loopback, DNS, allowed v6 nameservers, AAAA-resolvedallow_net, final REJECT).ip6tables.Safety
ip6tablesis on PATH. Either missing → v4-only (status quo).allow_net.Verified
iptablesandip6tablesOUTPUT chains end with REJECT.dupehound: clones 122 → 118, no new prod dead code.🤖 Generated with Claude Code