You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi — I've been running matchlock 0.2.8 on Arch and ran into something that looks like a bug around --allow-host on Linux. Writing it up in case it's useful; the diagnosis is tentative (I'm not an expert; exploring this with Claude Opus 4.6).
What I observed
Clean clone, git checkout v0.2.8 (f3f5bb8), go build ./cmd/matchlock ./cmd/guest-init. Arch Linux x86_64, Firecracker backend, kernel 6.16.7-arch1-1.
Manual repro:
$ matchlock run --image alpine:latest --allow-host httpbin.org -- \
sh -c 'nslookup httpbin.org; wget -q -O - http://httpbin.org/get'
;; connection timed out; no servers could be reached
wget: bad address 'httpbin.org'
Inside the guest, /etc/resolv.conf points at 8.8.8.8/8.8.4.4, TCP/443 to raw IPs succeeds, UDP/53 times out, and /etc/hosts has no entry for the allowlisted name.
Running the affected acceptance tests against the same clean build:
All six failures share the shape "wget: bad address 'httpbin.org'" does not contain "\"url\"".
TestDNSResolutionWorksWithInterception passes despite the manual nslookup inside the guest printing ;; connection timed out; no servers could be reached. The assertion at tests/acceptance/network_test.go:445 checks that the nslookup output contains neither SERVFAIL nor can't resolve — neither substring matches the "connection timed out" line, so the assertion passes.
The test-linux job in .github/workflows/ci.yml runs unit tests only; the acceptance suite runs on the acceptance-linux self-hosted runner. I haven't reproduced there and don't know why these tests are green on it.
Workaround for manual use: pair --allow-host with --add-host <name>:192.0.2.1.
Possible root cause
Reading the source, a shape that seems consistent with what I saw:
The Linux allowlist enforcement installs nftables DNAT on ports 80/443 (pkg/net/nftables.go); non-80/443 traffic appears to be routed to the pass-through deny added in Stricter networking #11, which would include UDP/53.
guest-init doesn't seem to be told about allowlisted names, so /etc/hosts isn't populated from the allow-list.
That would leave the guest with no path to turn a hostname into an IP, matching the bad address symptom.
There's a gVisor UDP forwarder at pkg/net/stack_darwin.go:407 with a handleDNS path at :419; I didn't test on macOS, so I don't know whether the same failure reproduces there.
This is just a hypothesis from exploring the code with Claude.
Possible fix direction (high level)
(A) Populate /etc/hosts from the allow-list: synthesize a placeholder HostIPMapping for each concrete allow-host entry and reuse the existing AddHosts → guest-init plumbing.
(B) Alternative: host-side DNS forwarder mirroring handleDNS in stack_darwin.go, wired via nftables. I haven't explored this.
Hi — I've been running matchlock 0.2.8 on Arch and ran into something that looks like a bug around
--allow-hoston Linux. Writing it up in case it's useful; the diagnosis is tentative (I'm not an expert; exploring this with Claude Opus 4.6).What I observed
Clean clone,
git checkout v0.2.8(f3f5bb8),go build ./cmd/matchlock ./cmd/guest-init. Arch Linux x86_64, Firecracker backend, kernel 6.16.7-arch1-1.Manual repro:
Inside the guest,
/etc/resolv.confpoints at 8.8.8.8/8.8.4.4, TCP/443 to raw IPs succeeds, UDP/53 times out, and/etc/hostshas no entry for the allowlisted name.Running the affected acceptance tests against the same clean build:
All six failures share the shape
"wget: bad address 'httpbin.org'" does not contain "\"url\"".TestDNSResolutionWorksWithInterceptionpasses despite the manualnslookupinside the guest printing;; connection timed out; no servers could be reached. The assertion attests/acceptance/network_test.go:445checks that thenslookupoutput contains neitherSERVFAILnorcan't resolve— neither substring matches the "connection timed out" line, so the assertion passes.The
test-linuxjob in.github/workflows/ci.ymlruns unit tests only; the acceptance suite runs on theacceptance-linuxself-hosted runner. I haven't reproduced there and don't know why these tests are green on it.Workaround for manual use: pair
--allow-hostwith--add-host <name>:192.0.2.1.Possible root cause
Reading the source, a shape that seems consistent with what I saw:
pkg/net/nftables.go); non-80/443 traffic appears to be routed to the pass-through deny added in Stricter networking #11, which would include UDP/53.guest-initdoesn't seem to be told about allowlisted names, so/etc/hostsisn't populated from the allow-list.bad addresssymptom.pkg/net/stack_darwin.go:407with ahandleDNSpath at:419; I didn't test on macOS, so I don't know whether the same failure reproduces there.This is just a hypothesis from exploring the code with Claude.
Possible fix direction (high level)
(A) Populate
/etc/hostsfrom the allow-list: synthesize a placeholderHostIPMappingfor each concrete allow-host entry and reuse the existingAddHosts → guest-initplumbing.(B) Alternative: host-side DNS forwarder mirroring
handleDNSinstack_darwin.go, wired via nftables. I haven't explored this.Happy to open a PR for (A). This approach worked for me in https://github.com/nemtsov/matchlock/tree/fix/allow-host-dns-resolution — ~54 lines in one file, unit tests pass, and the manual repro command above works end-to-end after it. All tests except
TestAllowlistGlobPattern(which is a limitation of this approach) pass on that branch.Environment
matchlock 0.2.8 (
f3f5bb8) / Arch Linux x86_64 / kernel 6.16.7-arch1-1 / Firecracker v1.10.1.