feat(networkproxy): Add TLS MITM, automatic CA management, header injection, and IPv6 support#323
Open
feat(networkproxy): Add TLS MITM, automatic CA management, header injection, and IPv6 support#323
Conversation
…edicated listeners to handle requests
Add an overflow check before make() to resolve CodeQL go/allocation-size-overflow warning. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Remove the +1 from the make() capacity expression; the overflow check for mozLen+caLen is sufficient. The final append may reallocate once if a separator newline is inserted, which is negligible for this data size and eliminates the CodeQL go/allocation-size-overflow alert. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
63ea236 to
122bafa
Compare
Add MITM-aware default resource values and a CRD field for per-policy override, so users can fine-tune proxy sidecar CPU/memory without modifying global configuration. Key changes: CRD & Types: - Add ProxyResourceOverride type with Requests/Limits fields - Add NetworkProxyConfig.Resources field (json:"resources") - Built-in defaults: non-MITM 50m/64Mi→500m/256Mi, MITM 100m/128Mi→1000m/512Mi Resource computation (internal/policy/proxy_resources.go): - DefaultProxyResources(mitmEnabled) returns built-in defaults - ResolveProxyResources(override, mitmEnabled) merges user overrides with defaults (field-level merge, unset fields retain defaults) - MarshalProxyResourcesJSON() for webhook sidecar injection Webhook & Controller integration: - mutation.go: replace hardcoded resource JSON with dynamic computation - update.go: remove hardcoded Resources from proxyContainer template, call ResolveProxyResources() for Deployment/StatefulSet/DaemonSet - validate.go: add validateProxyResources() ensuring limits >= requests Immutable proxy field enforcement: - ValidateUpdatePolicy() gains oldProxyConfig parameter to block modifications to ProxyUID/ProxyPort/ProxyAdminPort after creation - Webhook passes real old ProxyConfig (nil→zero-value for "first set" edge case); controller passes nil to skip check - Add ptrInt64Equal/ptrUint16Equal helpers for nil-safe comparison Policycacher selective update: - updateProxyConfigMutableFields() refreshes only MITM and Resources in cache, preserving immutable ProxyUID/Port/AdminPort from the add-time snapshot
nicke1wh
approved these changes
Apr 28, 2026
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.
Summary
This PR implements Phase 2 of the NetworkProxy enforcer: TLS Man-in-the-Middle (MITM) termination with automatic per-policy CA management, HTTP header injection (API key injection), and anti-Domain-Fronting protection. It also migrates the NetworkProxy configuration store from ConfigMap to Secret, adds IPv6 support, introduces configurable sidecar resource quotas, and reorganizes the profile generation code.
Major Changes
1. TLS MITM with Auto-Generated Per-Policy CA
The
MITMConfigCRD has been redesigned:caSecretRef: vArmor now automatically generates a self-signed CA (ECDSA P-256, 10-year validity) per policy. Users no longer need to manually create and manage CA Secrets.headerMutations: Per-domain HTTP header injection rules for injecting API keys, authorization tokens, or custom headers into decrypted requests.HeaderActionsupports either a literalvalueor asecretRefpointing to a user-managed Kubernetes Secret.secretRefat reconcile time and inlines the value into the Envoy xDS configuration.Certificate lifecycle:
domainschange, only the leaf certificate is re-signed (CA remains stable so the CA bundle exposed to application containers does not churn).mitm.domains(including wildcard and IP SANs).Anti-Domain-Fronting protection:
:authorityheader.mitm.domainseven if they do not need key injection, to gain full anti-fronting coverage.2. CA Bundle Injection into Application Containers
To make application containers trust the per-policy MITM CA without user configuration:
go:embed) and appends the policy's MITM CA to produceca-bundle.crt.ca-bundle.crtalongside xDS configuration and certificate material.mitm-ca-bundle.crt→ca-certificates.crt) into every target container at/etc/varmor/ca-bundle/.SSL_CERT_FILE(Go, Rust, .NET)REQUESTS_CA_BUNDLE(Python requests)NODE_EXTRA_CA_CERTS(Node.js — append semantics)CURL_CA_BUNDLE(curl/libcurl)Compatibility: Works for Go, Python, Node.js, curl out of the box. Java (JKS truststore) is not supported in Phase 2.
Known risk: The injected environment variables cause runtimes to ignore the image's built-in CA store. Custom CAs added to the container image will be lost. This will be addressed in Phase 3 via
CASecretRef.3. ConfigMap → Secret Migration
The NetworkProxy configuration store is migrated from ConfigMap to Kubernetes Secret:
bootstrap.yaml,lds.yaml,cds.yaml), MITM certificates, and the CA bundle are stored in a single unified Secret per policy.varmor-network-proxy-config→ Envoy sidecar/etc/envoy/(bootstrap + xDS)varmor-network-proxy-mitm-tls→ Envoy sidecar/etc/envoy/tls/(leaf cert/key + upstream CA bundle)varmor-network-proxy-mitm-ca-bundle→ App containers/etc/varmor/ca-bundle/(public CA bundle only)configmapspermission removed;secrets(get, create, update, delete) added.varmor-*ConfigMaps after upgrading.4. Translator / Renderer Extension for MITM
classifyEgress(): HTTPS traffic matching MITM domains is routed to MITM filter chains instead of Phase 1 TLS passthrough.buildMITMChains(): Generates up to two filter chains — a DNS chain (server_names) and an IP/CIDR chain (prefix_ranges). They are split because Envoy applies AND semantics betweenserver_namesandprefix_rangesin the same match./etc/envoy/tls/leaf.crtandleaf.key.mitm_upstreamcluster usesauto_sniandauto_san_validationto preserve the original upstream SNI and certificate validation. The upstream trust store uses the concatenated Mozilla + vArmor CA bundle.OVERWRITE_IF_EXISTS_OR_ADDsemantics at the virtual host level.tls_chainto avoid generating dead rules.5. IPv6 Support for NetworkProxy Enforcer
Added detection of cluster single-stack vs dual-stack configuration. The controller now creates dedicated listeners to handle both IPv4 and IPv6 egress traffic correctly.
6. Code Organization Refactoring
internal/networkproxy/*.go→internal/networkproxy/profile/(translator, renderer, tests, MITM resolver).internal/networkproxy/mitm/package: CA generation (ca.go), leaf signing (leaf.go), Mozilla bundle management (bundle.go), and comprehensive unit tests.internal/networkproxy/profile/networkproxy.goas the orchestration entry point (Kubernetes object lifecycle) andinternal/networkproxy/profile/mitm_resolver.gofor Controller-side Secret resolution.7. Example Policies
Added 11 example YAMLs under
test/examples/7-networkproxy-mitm/covering:8. Configurable Sidecar Resource Quotas
MITM mode requires the sidecar to perform dual TLS handshakes (client-side + upstream), consuming significantly more resources than a plain L4 proxy. The previously hard-coded defaults (50m/64Mi requests, 200m/128Mi limits) were insufficient for MITM workloads.
MITM-aware default resources:
Defaults are provided by
DefaultProxyResources(mitmEnabled bool)ininternal/policy/proxy_resources.go.CRD per-policy override:
A new
ProxyResourceOverridetype is added toNetworkProxyConfig, supporting field-level merge — users only specify the fields they want to override, and the rest retain the defaults:ResolveProxyResources(override, mitmEnabled)performs the field-level merge and is called by both the Webhook (mutation.go) and the Policy Controller (update.go).Validation:
validateProxyResources()invalidate.goensures that when bothrequestsandlimitsspecify the same resource type,limitsmust be greater than or equal torequests.Immutable proxy fields:
ProxyUID,ProxyPort, andProxyAdminPortare now enforced as immutable during policy updates. The validation path receives the oldProxyConfigto detect mutations, while the controller reconcile path passesnilto skip this check.Phase 3 direction:
A cluster-level default override via the
varmor-configConfigMap is planned, forming a three-tier merge chain: per-policy override → global ConfigMap → built-in defaults.9. Dependency Updates
v1.38-latest.Files Changed
apis/varmor/v1beta1/networkproxy.go,zz_generated.deepcopy.go, CRD YAMLsinternal/networkproxy/mitm/ca.go,leaf.go,bundle.go,certs/mozilla.peminternal/networkproxy/profile/translator*.go,renderer.go,networkproxy.go,mitm_resolver.gointernal/policy/*_controller.go,update.go,proxy_config_propagator.go,validate.go,proxy_resources.gointernal/webhooks/mutation.go,server.goconfig/k8s-resource/rbac/manager-clusterrole.yaml, Helm templates*_test.goacrossmitm/,profile/,policy/,webhooks/test/examples/7-networkproxy-mitm/*.yamlTest Plan
go test ./internal/networkproxy/mitm/...— CA generation, leaf signing, bundle concatenation, renewal semanticsgo test ./internal/networkproxy/profile/...— MITM chain generation, translator / renderer output, dead-rule filteringgo test ./internal/policy/...— Controller reconcile with resolved headers, Secret size guards, error handlinggo test ./internal/webhooks/...— Pod mutation with MITM volumes and env varsKnown Limitations
/32IP is configured inmitm.domains, plaintext HTTP traffic to that IP cannot reach thehttp_chaindue to Envoy filter chain matching semantics (prefix_rangescauses less-specific chains to be eliminated). L7 rules for that IP will not execute. Use domain-based rules instead.keytool -importis required.SSL_CERT_FILEetc. override the image's default CA store. Custom CAs baked into the image are lost until Phase 3CASecretRef.secretRef.nameto trigger reconcile and hot reload.varmor-*ConfigMaps from Phase 1 must be manually deleted after upgrade.Future Work (Phase 3)
CASecretRef: Allow users to supply their own CA for MITM signing.passthroughDomains: Explicitly declare domains that cannot be MITM'd (e.g., due to certificate pinning) and accept the Domain-Fronting risk.varmor-configConfigMap.