Eval cells reach the public internet through Docker's embedded DNS resolver
#2.976 aberto em 13 de ago. de 2026
Métricas do repositório
- Stars
- (1 estrela)
- Métricas de merge de PR
- (Métricas PR pendentes)
Description
The cell egress contract says every byte the subject sends leaves through the audited mitmproxy. Docker's embedded resolver at 127.0.0.11 is an exception, and it is a bidirectional one: it forwards any name it does not own to the host's upstream resolvers, so query labels carry data out and TXT/CNAME answers carry data back. Neither mitmproxy nor egress_filter.py sees any of it, and hits.jsonl records none of it.
This is not a rule that is missing. packages/eval/harbor/egress-proxy/network-policy exempts namespace-local destinations in both chains:
chain output { fib daddr type local return ... }
chain egress { fib daddr type local accept ... }
127.0.0.11 is local in the shared namespace, so it is exempt from the redirect and from the reject. The exemption is load-bearing — it is what keeps the loopback provider proxies reachable — and the resolver cannot be told apart from them at layer 3.
Reproduction
With the checked-in policy live in a real cell, the subject holding no NET_RAW:
UDP 53 -> 8.8.8.8 [Errno 1] Operation not permitted
TCP -> public redirected to gost, empty allowlist, no data
ICMP Operation not permitted
TXT google.com @127.0.0.11 449 bytes, 7 records, real SPF data
TXT o-o.myaddr.l.google.com the host's public egress IP
The last one can only be synthesised by Google's authoritative nameserver observing the query, so the query provably crossed the public internet and the answer came back. Reproduced independently by three reviewers of #2960 and again while adjudicating them.
Why the subject needs the resolver at all
Only to resolve maka-eval-mitmproxy, because the proxy is named in HTTPS_PROXY. Under proxy-only egress an HTTP proxy does remote name resolution itself, so nothing else in the cell needs DNS. The exemption buys one hostname lookup and costs an unaudited channel.
Candidate designs
Both change how the cell is addressed rather than what the ruleset says.
- Give the proxy a fixed address in an overlay-declared network and address it by IP, then reject
127.0.0.11outright. Costs a pinned subnet, which can collide on an arbitrary host. - Publish the proxy's address into the certificate volume the subject already mounts, have the relay write it into
/etc/hostsbefore the subject starts, and reject127.0.0.11. Reuses existing plumbing; needs care with the sidecar's own resolution when the policy is re-applied.
A third is the network-topology end state already noted in #2960 — the subject in an internal network whose only route out is the proxy. Docker does not forward external queries for an internal-only sandbox, so that closes this as a side effect.
Scope
Not a regression: the exemption predates #2960, which found it while tightening everything around it. #2960 corrects the README claim and states the gap rather than closing it.