Repository navigation
[Prototype] Send actor DNS to the egress PEP over DNS over HTTPS - #3854
Draft
Chuang Wang (chuangw6) wants to merge 5 commits into
Draft
Chuang Wang (chuangw6) wants to merge 5 commits into
Chuang Wang (chuangw6) wants to merge 5 commits into
Conversation
handleConnect verified the actor certificate and confirmed the actor with the control plane inline. Move both into a helper so another handler on the egress filter chain can run the same checks. Signed-off-by: Chuang Wang <chuangw@google.com>
enforce-in-pep is a --dns-egress-policy value under which atunnel sends actor DNS queries to the egress PEP over DNS over HTTPS (RFC 8484) and the PEP enforces policy. Nothing reads the value yet. Policy.AllowsHostname reports whether any rule names a hostname on any port, which is the check for a DNS query. The dns/protocol package gains the DoH path and media type, the EDNS payload size of a query, and a truncated response. ResolvConfNameservers is exported for the egress gateway. Signed-off-by: Chuang Wang <chuangw@google.com>
The egress ext_proc answers GET /dns-query on the egress filter chain. It runs the actor checks a CONNECT gets, then resolves a name that a rule in the actor's EgressPolicy names, on any port, with the gateway pod's resolvers. Any other name, and every name for an actor without a policy, is answered NXDOMAIN with an SOA of TTL 0 and Extended DNS Error 15. Both are HTTP 200 with a DNS message. A denied lookup is logged with the actor, name and type. Envoy needs no route for the request: the handler returns the DNS response as an ext_proc immediate response, which a handler can now do through Result.Immediate. Signed-off-by: Chuang Wang <chuangw@google.com>
With --dns-egress-policy=enforce-in-pep the DNS relay applies no policy. It validates each query as before, then sends it to the egress PEP as an RFC 8484 GET on the pooled mTLS connection that carries the actor's CONNECT tunnels, and returns the PEP's response to the actor. The query goes out with ID 0 and the actor's ID is restored on the response. The relay finds the actor's egress client per query, because the client is activated after the relay starts serving. It answers SERVFAIL when there is no client, the PEP gives no usable response, or the response answers a different question. Over UDP, a response larger than the actor accepts is returned truncated so the resolver retries over TCP. enforce-in-atunnel is unchanged. Signed-off-by: Chuang Wang <chuangw@google.com>
The egress demo gains a /dns endpoint that sends raw A queries with EDNS to the actor's nameserver and reports response codes, Extended DNS Errors and the time each query took. TestActorDNSLatency drives it for an allowed name sequentially and concurrently, a blocked name, lookups over TCP, and lookups after the gateway connection has idled out, and writes the percentiles to the file E2E_DNS_LATENCY_OUT names. It is skipped when that is unset. Signed-off-by: Chuang Wang <chuangw@google.com>
This branch has not been deployed
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.
Prototype for the DNS contract with the egress PEP discussed in #2313. This is a draft for discussion, not for merge.
Today the worker's DNS relay checks each actor DNS query against the actor's EgressPolicy and resolves it itself, so a PEP that keeps its own policy cannot govern DNS. This prototype moves the decision to the PEP.
What it does
--dns-egress-policy=enforce-in-pepis a new mode.enforce-in-atunnelis unchanged.GET /dns-query?dns=<base64url>on the pooled mTLS connection that carries the actor's CONNECT tunnels, and returns the PEP's response to the actor. No new port or address.atenet-egressext_proc answers the query. It runs the actor checks a CONNECT gets, resolves a name that a rule in the actor's EgressPolicy names, and answers any other name NXDOMAIN (SOA with TTL 0, Extended DNS Error 15). Both are HTTP 200 with a DNS message, returned as an ext_proc immediate response. The Envoy config does not change.The commits are ordered for review: a refactor of the CONNECT actor checks, shared helpers, the PEP side, the atunnel side, and a latency test.
Findings
On kind with a gVisor actor, the unchanged
TestActorDNSRequiresPolicy,TestActorEgress,TestActorEgressPolicyDeniesUnlistedHostandTestActorEgressHTTPSByHostnamepass in both modes.Lookup latency inside the actor, median of three alternating runs (single-node kind on Docker Desktop, arm64):
Of the 2.5 ms added to a sequential lookup, about 1.1 ms is the
GetActorcall the PEP makes on every lookup (CONNECT makes it once per tunnel), about 0.13 ms is re-verifying the certificate chain, and the remaining 1.3 ms is the extra hop. TheGetActorcall rises to a median of 3.0 ms at 16 parallel lookups and 5.5 ms at 48. The split came from temporary timing that is not in this PR.With
atenet-egressscaled to zero, the actor gets SERVFAIL after 5 s.How to reproduce
On a kind cluster installed from this branch with the e2e job's settings, switch the mode and wait for the worker pools to roll:
Then run the latency test, which is skipped unless
E2E_DNS_LATENCY_OUTis set:E2E_DNS_LATENCY_OUT=/tmp/enforce-in-pep.json E2E_DNS_EGRESS_POLICY=enforce-in-pep \ hack/run-e2e-kind.sh ./internal/e2e/suites/networking -run '^TestActorDNSLatency$' -v -args --no-colorOpen questions and gaps
enforce-in-atunnelthe relay keeps answering from its last good policy./dns-query.docs/guides/network-egress.mdstill says port 53 bypasses the PEP. It is left alone until the contract is agreed.TestSandboxNamespacesDoNotInheritNodeSettingsandTestSetupSandboxNetworkWithoutVethfail for me under Docker Desktop on unmodifiedmainas well.AI use: AI-assisted (Claude Code). I reviewed and tested it.