netpol: wave 2 — four workloads keep exactly one destination (#0088)

Both backups reach the Hetzner storage box over SSH; the TURN rotation and
Wiki.js reach rohana. Everything else is now refused for them.

Two separate policies rather than entries in egress-nur-intern, because a
policy's egress rules apply to every pod it selects: hanging the storage
box off the shared policy would hand it to fourteen workloads that have no
business there.

rohana is allowed as 10.0.0.3/32, not as its public address. The DNS
pointer from the previous commit sends the public name down the private
path, and the certificate is valid there - both measured after the change,
not assumed. So the group's one deliberate Gitea exception no longer leaves
the cluster at all.

Congruence checked before pushing, and this is the check worth keeping:
twenty names are excluded from the broad rule and exactly the same twenty
are covered by a narrow one. An entry on one side only would either cut a
workload off completely or leave the restriction inert, and neither is a
syntax error.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F2Q4Ri8NGwyTZzScvKnWFM
This commit is contained in:
Thore Cimbal
2026-08-21 12:00:00 +00:00
co-authored by Claude Opus 5
parent 69c9ef13a1
commit 0a7b8f4bf1
+96
View File
@@ -461,6 +461,11 @@ spec:
- wikijs-gruppenpruefung
- haproxy
- draupnir
# Welle 2 (#0088): je genau ein Ziel, eigene Policy unten.
- synapse-backup
- wikijs-backup
- turn-secret-rotation
- wikijs
# Welle 1 (#0088): kein externer Bedarf nachweisbar.
- matrix-rtc-authorisation-service
- wikijs-config
@@ -589,3 +594,94 @@ spec:
cidr: 10.42.0.0/16
- ipBlock:
cidr: 10.43.0.0/16
---
# Welle 2 (#0088): Arbeitslasten mit genau EINEM externen Ziel.
#
# Eigene Policies statt Aufnahme in egress-nur-intern: Die Egress-Regeln einer
# Policy gelten fuer ALLE von ihr gewaehlten Pods. Haenge man die Storage Box an
# egress-nur-intern, bekaemen sie auch die vierzehn, die sie nicht brauchen.
#
# ⚠️ Die Namen stehen zusaetzlich in der NotIn-Liste von egress-block-metadata.
# Ohne das bliebe die breite Erlaubnis bestehen und diese Regeln waeren
# wirkungslos - NetworkPolicies sind additiv.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-storage-box
namespace: matrix
spec:
podSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- synapse-backup
- wikijs-backup
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
- to:
- ipBlock:
cidr: 10.42.0.0/16
- ipBlock:
cidr: 10.43.0.0/16
# Hetzner Storage Box, borg ueber SSH. Einziges Ziel ausserhalb des
# Clusters - kein privater Weg dorthin bekannt (Stand 2026-08-21).
- to:
- ipBlock:
cidr: 91.98.246.178/32
ports:
- protocol: TCP
port: 23
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-rohana
namespace: matrix
spec:
podSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
# Schreibt den rotierten TURN-Schluessel nach Gitea - die einzige
# bewusste Gitea-Ausnahme der Gruppe (AGENTS.md).
- turn-secret-rotation
# git-storage von Wiki.js: https://rohana.axion1337.de/sorb/ThreadNetWiki.git
# (aus der laufenden Konfiguration gelesen, nicht angenommen).
- wikijs
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
- to:
- ipBlock:
cidr: 10.42.0.0/16
- ipBlock:
cidr: 10.43.0.0/16
# rohana ueber das PRIVATE Netz. Der oeffentliche Name zeigt seit
# coredns-custom.yaml hierher; das Zertifikat gilt auch auf diesem Weg.
- to:
- ipBlock:
cidr: 10.0.0.3/32
ports:
- protocol: TCP
port: 443