The passthrough chain from #2019 dialed the ORIGINAL_DST filter state, which the CONNECT leg filled with the address the actor connected to. The SNI picked the chain, the actor's own resolution picked the destination, so a passthrough rule for one name let an actor reach any IP by claiming that name in the ClientHello. We fix it by: - The passthrough chain is now `sni_dynamic_forward_proxy` then `tcp_proxy` to a new raw forward-proxy cluster, `egress_forward_proxy_passthrough`, on the shared egress_dns_cache. The gateway resolves the SNI itself and sends the bytes to it. - The CONNECT leg answers the dialed port under dev.ate.egress:dialed_port; the outer chain copies it into envoy.upstream.dynamic_port, shared with the inner listener, which both the SNI filter and the cluster read before their configured port. > It's a good idea to open an issue first for discussion. - [x] Tests pass - [x] Appropriate changes to documentation are included in the PR
Envoy Dataplane Image
This directory contains the build definition and custom extensions for the Envoy dataplane container image (envoy-dataplane) used by Agent Substrate's atenet-egress gateway.
Directory Contents
cmd/dataplane/envoy/
├── Dockerfile # Multi-stage build for the Envoy dataplane image
└── dynamic-modules/
└── egress-policy/ # Rust Envoy Dynamic Module for egress policy enforcement
Dockerfile: Multi-stage container build that:- Compiles the Rust dynamic module (
envoy-substrate-egress-policy) into a shared library (libenvoy_substrate_egress_policy.so) in arust:bookwormbuilder stage. - Packages the compiled
.sointo theenvoyproxy/envoy:v1.39-latestruntime image under/usr/local/lib/libenvoy_substrate_egress_policy.soand setsENVOY_DYNAMIC_MODULES_SEARCH_PATH=/usr/local/lib.
- Compiles the Rust dynamic module (
dynamic-modules/egress-policy/: A Rust crate using the Envoy Dynamic Modules SDK (envoy-proxy-dynamic-modules-rust-sdk) that implements a custom Envoy listener filter for Substrate egress policy evaluation. Seedynamic-modules/egress-policy/README.mdfor module-specific build, test, and Envoy configuration details.
Building and Deployment
During a build from source, ate-setup builds the image from this directory via docker buildx, pushes it to $KO_DOCKER_REPO/envoy-dataplane, and its resolved digest replaces the ${ENVOY_DATAPLANE_IMAGE} placeholder in the egress manifests (manifests/ate-install/atenet-egress*.yaml).
A pre-built install (ate-setup deploy --image-repo REPO --image-tag TAG) builds nothing and pins REPO/envoy-dataplane:TAG instead, so a release publishes it with the other images:
make build-release-images KO_DOCKER_REPO=REPO VERSION=TAG
make build-envoy-dataplane builds just this image. It targets KO_DEFAULTPLATFORMS, or linux/amd64 when unset; set DOCKERFILE_PLATFORMS to override. Building another architecture compiles Rust under QEMU, which must be registered with binfmt (e.g. docker run --privileged --rm tonistiigi/binfmt --install arm64).
To build the image locally without pushing it:
docker buildx build -t envoy-dataplane cmd/dataplane/envoy