--- # Egress: alles bleibt erlaubt AUSSER dem Metadaten-Dienst (management #0088). # # Warum so schmal? Der Lehrbuch-Schnitt (0.0.0.0/0 except RFC1918) haette hier zwei # Dinge zerrissen, beide ueber 10.0.0.3 (CFGMON im privaten Hetzner-Netz): Alloy # schreibt Metriken und Logs dorthin, und der TURN-Rotations-CronJob erreicht Gitea # ueber einen hostAlias auf dieselbe Adresse. Private Netze bleiben deshalb offen. # # 169.254.0.0/16 ist Link-Local; darin liegt bei Hetzner unter 169.254.169.254 der # Metadaten-Dienst, aus jedem Pod unauthentifiziert abfragbar (nachgemessen 2026-08-19: # HTTP 200 mit instance-id, hostname, region, MAC, Netzkonfiguration). userdata und # public-keys waren LEER - es liegen hier also keine Zugangsdaten offen. Der Gewinn ist # entsprechend bescheiden; der Schnitt kostet aber nichts und schliesst die Klasse. # # ACHTUNG beim Erweitern: Sobald eine Egress-Regel fuer einen Pod existiert, gilt fuer # ihn Default-Deny fuer alles NICHT Aufgefuehrte. Die drei Bloecke unten sind daher # Pflicht, nicht Bequemlichkeit - insbesondere DNS: fehlt es, steht alles, und der # Fehler sieht wie ein Anwendungsproblem aus, nicht wie eine Firewall. # # Rollback: diese eine Policy im Namespace loeschen. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: egress-block-metadata namespace: monitoring spec: # Waehlt alle Pods AUSSER denen mit eigener, engerer Regel (#0088). # Bleibt als Auffangnetz: Eine kuenftige Arbeitslast ohne eigene Policy # landet hier - Metadaten gesperrt, Rest offen - statt voellig ungeregelt. # ⚠️ Der Ausschluss MUSS hier stehen: NetworkPolicies sind additiv. podSelector: matchExpressions: - key: app.kubernetes.io/name operator: NotIn values: - alloy - kube-state-metrics policyTypes: - Egress egress: # 1. DNS - zuerst, weil ohne DNS nichts geht. - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system ports: - protocol: UDP port: 53 - protocol: TCP port: 53 # 2. Cluster-intern: Pods und Services (inkl. API-Server 10.43.0.1). - to: - ipBlock: cidr: 10.42.0.0/16 - ipBlock: cidr: 10.43.0.0/16 # 3. Alles uebrige - Foederation, ACME, SMTP, Registries, privates Netz - # ausser Link-Local. - to: - ipBlock: cidr: 0.0.0.0/0 except: - 169.254.0.0/16 --- # Welle 3 (#0088): Monitoring-Namespace, enge Regeln je Arbeitslast. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: egress-nur-intern namespace: monitoring spec: # Liefert Metriken, holt selbst nichts von aussen. podSelector: matchLabels: app.kubernetes.io/name: kube-state-metrics 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 --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: egress-ops-host namespace: monitoring spec: podSelector: matchLabels: app.kubernetes.io/name: alloy 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 # Der operating-Host im PRIVATEN Netz: Logs nach Loki (3100), Metriken per # remote_write nach Prometheus (9090). Beide Ziele aus der laufenden # Alloy-Konfiguration gelesen, nicht angenommen. - to: - ipBlock: cidr: 10.0.0.3/32 ports: - protocol: TCP port: 3100 - protocol: TCP port: 9090