Skip to content

Commit eed4d27

Browse files
authored
Merge pull request #428 from huang195/fix/retire-cluster-cidrs
Chore: Retire CLUSTER_CIDRS injection (DNS exemption is resolv.conf-driven)
2 parents 17b0e60 + 4be8629 commit eed4d27

6 files changed

Lines changed: 16 additions & 91 deletions

File tree

charts/kagenti-operator/values.yaml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,9 @@ defaults:
225225
# always-on enforce-redirect egress guard (proxy-sidecar / lite). MUST match
226226
# the authbridge listener.transparent_proxy_addr (default :8082).
227227
transparentPort: 8082
228-
# In-cluster CIDRs (pods/services/DNS) left direct by the enforce-redirect
229-
# guard; external TCP is REDIRECTed to the transparent listener and external
230-
# non-TCP is dropped. The default is Kind-shaped (pods 10.244/16 + services
231-
# 10.96/16). OpenShift/EKS MUST override — e.g. OCP services 172.30.0.0/16
232-
# (outside 10/8) + pods 10.128.0.0/14 — or in-cluster service traffic breaks.
233-
clusterCIDRs:
234-
- "10.0.0.0/8"
228+
# Cluster DNS is kept direct by proxy-init itself (it reads the pod's
229+
# /etc/resolv.conf nameservers), so there is no in-cluster CIDR knob to set —
230+
# works on Kind / OpenShift / EKS / NodeLocal-DNSCache with no per-cluster config.
235231

236232
# Resource defaults (conservative for dev)
237233
# Note: requests must be <= limits

kagenti-operator/internal/webhook/config/defaults.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ func CompiledDefaults() *PlatformConfig {
3535
// Transparent listener port — must match the authbridge proxy-sidecar
3636
// preset (listener.transparent_proxy_addr default :8082).
3737
TransparentPort: 8082,
38-
// Kind-shaped default (pods 10.244/16 + services 10.96/16). OCP/EKS
39-
// MUST override (see ProxyConfig.ClusterCIDRs doc).
40-
ClusterCIDRs: []string{"10.0.0.0/8"},
4138
},
4239
Resources: ResourcesConfig{
4340
EnvoyProxy: corev1.ResourceRequirements{

kagenti-operator/internal/webhook/config/types.go

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package config
22

33
import (
44
"fmt"
5-
"net"
65

76
corev1 "k8s.io/api/core/v1"
87
)
@@ -52,16 +51,6 @@ type ProxyConfig struct {
5251
// external TCP egress to. It MUST match the authbridge proxy-sidecar
5352
// listener.transparent_proxy_addr (default :8082).
5453
TransparentPort int32 `json:"transparentPort" yaml:"transparentPort"`
55-
56-
// ClusterCIDRs are the in-cluster ranges (pods / services / DNS) that the
57-
// enforce-redirect guard allows direct; external TCP is REDIRECTed to the
58-
// transparent listener and external non-TCP is dropped. The default
59-
// 10.0.0.0/8 is Kind-shaped (pods 10.244/16 + services 10.96/16). OCP/EKS
60-
// MUST override this (e.g. OCP services 172.30.0.0/16, pods 10.128.0.0/14 —
61-
// 172.30/16 is outside 10/8) or in-cluster service traffic will be dropped.
62-
// Egress enforcement is always-on for proxy-sidecar / lite, so this is
63-
// always consumed there; envoy-sidecar (transparent redirect) does not use it.
64-
ClusterCIDRs []string `json:"clusterCIDRs" yaml:"clusterCIDRs"`
6554
}
6655

6756
type ResourcesConfig struct {
@@ -98,11 +87,6 @@ func (c *PlatformConfig) DeepCopy() *PlatformConfig {
9887
copy(result.TokenExchange.DefaultScopes, c.TokenExchange.DefaultScopes)
9988
}
10089

101-
if c.Proxy.ClusterCIDRs != nil {
102-
result.Proxy.ClusterCIDRs = make([]string, len(c.Proxy.ClusterCIDRs))
103-
copy(result.Proxy.ClusterCIDRs, c.Proxy.ClusterCIDRs)
104-
}
105-
10690
// Deep copy ResourceRequirements — ResourceList is a map that would be shared
10791
result.Resources.EnvoyProxy = deepCopyResourceRequirements(c.Resources.EnvoyProxy)
10892
result.Resources.ProxyInit = deepCopyResourceRequirements(c.Resources.ProxyInit)
@@ -147,23 +131,6 @@ func (c *PlatformConfig) Validate() error {
147131
if c.Proxy.UID < 1 {
148132
return fmt.Errorf("proxy.uid must be >= 1 (got %d): the proxy must not run as root and the egress-enforcement exemption keys on this UID", c.Proxy.UID)
149133
}
150-
// ClusterCIDRs drive the only in-cluster allowance in the enforce-redirect
151-
// guard, which is always-on for proxy-sidecar / lite. Validate at load time so
152-
// a misconfig fails fast with a clear message rather than: (a) an empty list
153-
// silently falling back to the Kind-shaped 10.0.0.0/8 default in
154-
// init-iptables.sh, or (b) a malformed entry crashing the proxy-init container
155-
// under `set -e` with a cryptic iptables error.
156-
if len(c.Proxy.ClusterCIDRs) == 0 {
157-
return fmt.Errorf("proxy.clusterCIDRs must be non-empty (set the cluster's pod+service CIDRs)")
158-
}
159-
// Syntactic validation only — overlapping ranges and IPv4/IPv6 mixing are
160-
// accepted (iptables handles both, and the init script splits v4/v6 itself);
161-
// we only reject malformed strings here.
162-
for _, cidr := range c.Proxy.ClusterCIDRs {
163-
if _, _, err := net.ParseCIDR(cidr); err != nil {
164-
return fmt.Errorf("proxy.clusterCIDRs entry %q is not a valid CIDR: %w", cidr, err)
165-
}
166-
}
167134
if c.Images.EnvoyProxy == "" {
168135
return fmt.Errorf("images.envoyProxy is required")
169136
}

kagenti-operator/internal/webhook/config/types_test.go

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,6 @@ package config
22

33
import "testing"
44

5-
// ClusterCIDRs drive the only in-cluster allowance in the always-on
6-
// enforce-redirect guard, so they must always be present and valid — an empty
7-
// list (silent 10/8 fallback in the init script) or a malformed entry
8-
// (init-container CrashLoop under set -e) must be rejected at config load.
9-
func TestValidate_ClusterCIDRs(t *testing.T) {
10-
tests := []struct {
11-
name string
12-
mutate func(*PlatformConfig)
13-
wantErr bool
14-
}{
15-
{"default CIDRs ok", func(c *PlatformConfig) {}, false},
16-
{"empty CIDRs rejected", func(c *PlatformConfig) { c.Proxy.ClusterCIDRs = nil }, true},
17-
{"malformed CIDR rejected", func(c *PlatformConfig) {
18-
c.Proxy.ClusterCIDRs = []string{"10.0.0.0/8", "garbage"}
19-
}, true},
20-
{"valid OCP-shaped CIDRs ok", func(c *PlatformConfig) {
21-
c.Proxy.ClusterCIDRs = []string{"10.128.0.0/14", "172.30.0.0/16"}
22-
}, false},
23-
}
24-
for _, tt := range tests {
25-
t.Run(tt.name, func(t *testing.T) {
26-
c := CompiledDefaults()
27-
tt.mutate(c)
28-
err := c.Validate()
29-
if tt.wantErr && err == nil {
30-
t.Errorf("expected validation error, got nil")
31-
}
32-
if !tt.wantErr && err != nil {
33-
t.Errorf("unexpected validation error: %v", err)
34-
}
35-
})
36-
}
37-
}
38-
395
// TransparentPort is the REDIRECT target for the enforce-redirect guard; it must
406
// be a valid, non-privileged port (the proxy binds it as a non-root user).
417
func TestValidate_TransparentPort(t *testing.T) {

kagenti-operator/internal/webhook/injector/container_builder.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -462,28 +462,27 @@ const mandatoryOutboundExclude = "8080"
462462
// - "enforce-redirect" (proxy-sidecar): a fail-closed egress guard that
463463
// REDIRECTs external TCP bypassing the forward proxy to the transparent
464464
// listener (TRANSPARENT_PORT) and DROPs non-TCP. Driven by PROXY_UID +
465-
// CLUSTER_CIDRS + TRANSPARENT_PORT; the exclude args do not apply.
465+
// TRANSPARENT_PORT; the exclude args do not apply. Cluster DNS is kept
466+
// direct by the init script reading the pod's resolv.conf nameservers.
466467
func (b *ContainerBuilder) BuildProxyInitContainer(mode ProxyInitMode, outboundPortsExclude, inboundPortsExclude string) corev1.Container {
467468
var env []corev1.EnvVar
468469
switch mode {
469470
case ProxyInitModeEnforceRedirect:
470471
// PROXY_UID is exempted (its egress is not redirected) and MUST match the
471-
// proxy container's RunAsUser (both derive from b.cfg.Proxy.UID).
472-
// CLUSTER_CIDRS are allowed direct; external TCP is REDIRECTed to
473-
// TRANSPARENT_PORT (the proxy's transparent listener), external non-TCP is
474-
// dropped. The redirect-only exclude vars are unused in this mode.
475-
clusterCIDRs := strings.Join(b.cfg.Proxy.ClusterCIDRs, ",")
472+
// proxy container's RunAsUser (both derive from b.cfg.Proxy.UID). External
473+
// TCP is REDIRECTed to TRANSPARENT_PORT (the proxy's transparent listener),
474+
// external non-TCP is dropped. Cluster DNS is left direct by the init script
475+
// itself (it reads the pod's resolv.conf nameservers — no CIDR knob needed).
476+
// The redirect-only exclude vars are unused in this mode.
476477
env = []corev1.EnvVar{
477478
{Name: "MODE", Value: string(ProxyInitModeEnforceRedirect)},
478479
{Name: "PROXY_UID", Value: fmt.Sprintf("%d", b.cfg.Proxy.UID)},
479-
{Name: "CLUSTER_CIDRS", Value: clusterCIDRs},
480480
{Name: "TRANSPARENT_PORT", Value: fmt.Sprintf("%d", b.cfg.Proxy.TransparentPort)},
481481
}
482482
builderLog.Info("building ProxyInit Container",
483483
"mode", "enforce-redirect",
484484
"proxyUID", b.cfg.Proxy.UID,
485-
"transparentPort", b.cfg.Proxy.TransparentPort,
486-
"clusterCIDRs", clusterCIDRs)
485+
"transparentPort", b.cfg.Proxy.TransparentPort)
487486
case ProxyInitModeRedirect:
488487
outboundValue := buildOutboundExcludeValue(outboundPortsExclude)
489488
inboundValue := buildPortExcludeValue(inboundPortsExclude, "inbound-ports-exclude")

kagenti-operator/internal/webhook/injector/container_builder_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package injector
1818

1919
import (
2020
"strconv"
21-
"strings"
2221
"testing"
2322

2423
"github.com/kagenti/operator/internal/webhook/config"
@@ -304,8 +303,9 @@ func TestBuildProxySidecarContainer_RunAsProxyUID(t *testing.T) {
304303
}
305304
}
306305

307-
// enforce-redirect mode emits MODE / PROXY_UID / CLUSTER_CIDRS / TRANSPARENT_PORT
308-
// and none of the redirect-only vars (POD_IP, OUTBOUND_PORTS_EXCLUDE).
306+
// enforce-redirect mode emits MODE / PROXY_UID / TRANSPARENT_PORT, no CLUSTER_CIDRS
307+
// (DNS exemption is resolv.conf-driven in the init script), and none of the
308+
// redirect-only vars (POD_IP, OUTBOUND_PORTS_EXCLUDE).
309309
func TestBuildProxyInitContainer_EnforceRedirect(t *testing.T) {
310310
cfg := config.CompiledDefaults()
311311
builder := NewContainerBuilder(cfg)
@@ -324,8 +324,8 @@ func TestBuildProxyInitContainer_EnforceRedirect(t *testing.T) {
324324
if want := strconv.FormatInt(cfg.Proxy.UID, 10); got["PROXY_UID"] != want {
325325
t.Errorf("PROXY_UID = %q, want %q", got["PROXY_UID"], want)
326326
}
327-
if want := strings.Join(cfg.Proxy.ClusterCIDRs, ","); got["CLUSTER_CIDRS"] != want {
328-
t.Errorf("CLUSTER_CIDRS = %q, want %q", got["CLUSTER_CIDRS"], want)
327+
if _, ok := got["CLUSTER_CIDRS"]; ok {
328+
t.Error("enforce-redirect must not set CLUSTER_CIDRS (DNS exemption is resolv.conf-driven in the init script)")
329329
}
330330
if want := strconv.FormatInt(int64(cfg.Proxy.TransparentPort), 10); got["TRANSPARENT_PORT"] != want {
331331
t.Errorf("TRANSPARENT_PORT = %q, want %q", got["TRANSPARENT_PORT"], want)

0 commit comments

Comments
 (0)