feat(outline)!: NetworkPolicy, on by default
Major, as every chart in this rollout is. Inbound 3000 only; outbound DNS plus 5432, 6379 and 443. Those three egress ports are the STANDARD ones and not the configured ones, which is this chart's real limitation and is written into values.yaml, the template header and NOTES.txt rather than left to be discovered: Outline's database, Redis and OIDC provider all arrive as connection URLs inside 1Password items that the chart never parses, so it cannot know where they listen and cannot validate a guess. A dependency on another port is blocked, and because all three probes hit /_health - which checks Postgres and Redis - the symptom is a pod that never becomes Ready rather than an error anyone reads. networkPolicy.egress.extraPorts is the escape hatch. That same property is what makes this chart the right place for the enforcement experiment in the next commit. Also reverts the cyberchef fixture from the first experiment: with the probe port restricted to an address that is not the node's, the install-test went GREEN, so the claim that it catches a blocked probe path does not hold as written. The next commit establishes whether policies are enforced in CI at all. Part of #5
This commit is contained in:
6 files changed
+385
-25
No files matched your search
@@ -235,3 +235,57 @@ FORCE_HTTPS IS ON
|
||||
header. Turned on, Outline redirects to https itself — which loops
|
||||
endlessly if that header does not reach the pod.
|
||||
{{- end }}
|
||||
{{- if .Values.networkPolicy.enabled }}
|
||||
|
||||
NETWORKPOLICY IS ACTIVE — WHAT IT CAPS, AND WHAT IT DOES NOT
|
||||
{{ .Release.Name }}-{{ .Chart.Name }}-networkpolicy selects this workload's pods.
|
||||
Inbound: TCP 3000 only. Outbound: DNS, TCP 5432 (Postgres), 6379 (Redis),
|
||||
443 (OIDC discovery){{ with .Values.networkPolicy.egress }}{{ with .extraPorts }}, plus TCP {{ join ", " . }}{{ end }}{{ end }}.
|
||||
|
||||
THOSE EGRESS PORTS ARE THE STANDARD ONES, NOT YOUR CONFIGURED ONES. The
|
||||
database, Redis and OIDC URLs all live inside 1Password items that this chart
|
||||
never parses, so it cannot know where your dependencies listen. A dependency
|
||||
on another port is blocked — and since all three probes hit /_health, which
|
||||
checks Postgres and Redis, the symptom is a pod that never becomes Ready
|
||||
rather than a connection error anyone sees. Add the real port to
|
||||
networkPolicy.egress.extraPorts.
|
||||
|
||||
Three limits belong in the same breath, because none of them is visible in
|
||||
the object itself:
|
||||
|
||||
- EGRESS IS BY PORT, NEVER BY DESTINATION. A NetworkPolicy matches CIDRs and
|
||||
selectors and cannot express a hostname, so every egress rule permits its
|
||||
port to ANY address. That is a limit of the object, not a shortcut — this
|
||||
cluster's CNI (Canal: Flannel plus Calico) has no FQDN rule either. An
|
||||
outbound port the chart does not know about is BLOCKED: add it to
|
||||
networkPolicy.egress.extraPorts, and expect to find out through an
|
||||
application-level connection error rather than through this object.
|
||||
{{- if .Values.networkPolicy.probeSources }}
|
||||
- THE PROBE PATH IS RESTRICTED in this release, because
|
||||
networkPolicy.probeSources is set to
|
||||
{{ join ", " .Values.networkPolicy.probeSources }}
|
||||
Probes come from the IP of the WORKER NODE running the pod. If none of those
|
||||
CIDRs covers the node this pod lands on, the kubelet's probes are dropped
|
||||
and THE POD NEVER BECOMES READY — the rollout then times out and the symptom
|
||||
looks like a broken application. Compare
|
||||
|
||||
kubectl -n {{ .Release.Namespace }} describe pod -l app={{ .Release.Name }}-{{ .Chart.Name }}-sfs
|
||||
|
||||
against `kubectl get node -o wide`.
|
||||
{{- else }}
|
||||
- THE PROBED PORT IS OPEN INSIDE THE CLUSTER. networkPolicy.probeSources is
|
||||
empty, so that rule carries no source selector at all and any pod the CNI
|
||||
routes to can reach it. Not from the internet — but this is NOT pod-level
|
||||
isolation. Narrowing it means listing the worker node IPs in
|
||||
networkPolicy.probeSources, because the kubelet probes from the node's own
|
||||
address and the chart cannot know it; a wrong guess there leaves the pod
|
||||
permanently un-Ready.
|
||||
{{- end }}
|
||||
- IT IS ONLY A BOUNDARY WHERE THE CNI ENFORCES POLICIES. Where it does not,
|
||||
this object is accepted and filters nothing, so everything reads as
|
||||
configured while nothing is filtered. `kubectl -n {{ .Release.Namespace }} get networkpolicy`
|
||||
shows the object exists; only a connection attempt from an unrelated
|
||||
namespace shows that it bites.
|
||||
|
||||
Switch it off with networkPolicy.enabled: false.
|
||||
{{- end }}
|
||||
Reference in new issue
Block a user