feat: Default-deny ingress NetworkPolicy for matrix namespace
Auto-Deploy on Push / verify-and-notify (push) Canceled after 0s
Auto-Deploy on Push / verify-and-notify (push) Canceled after 0s
Ingress-only default-deny plus per-component allow rules, using named container ports throughout (not Service ports) after the authentik port-mismatch incident. Traefik -> element-web/element-admin/haproxy (fronts both matrix.axion1337.chat and well-known)/MAS; synapse <- haproxy+MAS; postgres <- synapse+MAS; RTC signalling via Traefik, RTC media NodePorts left open to the internet by design; monitoring scrape allows for synapse/postgres/rtc-sfu metrics; ACME solver allow. coturn (hostNetwork) needs nothing - NetworkPolicy doesn't apply to it. Part of issue #10.
This commit is contained in:
Regular → Executable
+2
-1
@@ -29,4 +29,5 @@ resources:
|
|||||||
# HelmRelease (muss ganz unten stehen, damit die ConfigMaps vorher da sind!)
|
# HelmRelease (muss ganz unten stehen, damit die ConfigMaps vorher da sind!)
|
||||||
- element-server-suite.yaml
|
- element-server-suite.yaml
|
||||||
# Custom Apex Ingress für Element Web + Well-Known auf axion1337.chat
|
# Custom Apex Ingress für Element Web + Well-Known auf axion1337.chat
|
||||||
- apex-ingress.yaml # Custom Apex Ingress für Element Web + Well-Known auf axion1337.chat
|
- apex-ingress.yaml # Custom Apex Ingress für Element Web + Well-Known auf axion1337.chat
|
||||||
|
- networkpolicy.yaml
|
||||||
@@ -0,0 +1,290 @@
|
|||||||
|
# Default-deny ingress for the matrix namespace, with explicit allow rules per component.
|
||||||
|
# Egress is intentionally untouched (federation to arbitrary Matrix servers, ACME, SMTP,
|
||||||
|
# DNS all stay unrestricted).
|
||||||
|
#
|
||||||
|
# Lesson learned deploying the authentik namespace's equivalent policy: NetworkPolicy
|
||||||
|
# filters on the pod's actual container port, not the Service's external port (e.g.
|
||||||
|
# authentik-server's Service maps 80->9000). Wherever a Service here uses a *named*
|
||||||
|
# targetPort, this file references that name directly instead of guessing a number -
|
||||||
|
# Kubernetes resolves it from the pod spec, which is safer than a hardcoded port.
|
||||||
|
#
|
||||||
|
# matrix-stack-postgres already effectively has no dedicated chart NetworkPolicy of its
|
||||||
|
# own (unlike authentik-postgresql's Bitnami one) - the rules below are the only gate.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default-deny-ingress
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
---
|
||||||
|
# axion1337.chat (root) -> Element Web
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-element-web
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: element-web
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: element
|
||||||
|
---
|
||||||
|
# admin.axion1337.chat -> Element Admin
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-element-admin
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: element-admin
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: http
|
||||||
|
---
|
||||||
|
# axion1337.chat/docs/setup -> Element desktop setup docs (our own nginx)
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-element-web-docs
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: element-web-docs
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8080
|
||||||
|
---
|
||||||
|
# matrix.axion1337.chat AND the well-known delegation both front through haproxy
|
||||||
|
# (matrix-stack-synapse and matrix-stack-well-known Services both target haproxy's
|
||||||
|
# named ports, not synapse-main directly).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-haproxy
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: haproxy
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: haproxy-synapse
|
||||||
|
- protocol: TCP
|
||||||
|
port: haproxy-403
|
||||||
|
- protocol: TCP
|
||||||
|
port: haproxy-wkd
|
||||||
|
---
|
||||||
|
# account.axion1337.chat (Traefik) + matrix.axion1337.chat (also routes to MAS for some
|
||||||
|
# paths) + synapse-main calling MAS's internal port for session/token introspection.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-mas
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: matrix-authentication-service
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8080
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: synapse-main
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8081
|
||||||
|
---
|
||||||
|
# Synapse itself: reached via haproxy (same namespace), calls from MAS (provisioning),
|
||||||
|
# metrics scraped by Alloy (monitoring namespace).
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-synapse
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: synapse-main
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: haproxy
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: matrix-authentication-service
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: synapse-http
|
||||||
|
- protocol: TCP
|
||||||
|
port: synapse-health
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: monitoring
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: synapse-metrics
|
||||||
|
---
|
||||||
|
# mrtc.axion1337.chat (Traefik) for the auth handshake, plus Alloy scraping metrics.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-rtc-authorisation-service
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: matrix-rtc-authorisation-service
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: matrix-rtc-sfu
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: http
|
||||||
|
---
|
||||||
|
# The SFU: mrtc.axion1337.chat (Traefik) for signalling, Alloy for metrics, and the
|
||||||
|
# NodePort-exposed WebRTC media ports need to stay open to the internet by design -
|
||||||
|
# that's the actual point of a TURN/SFU media relay, not a mistake.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-rtc-sfu
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: matrix-rtc-sfu
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: http
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: monitoring
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: metrics
|
||||||
|
- from:
|
||||||
|
- ipBlock:
|
||||||
|
cidr: 0.0.0.0/0
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 30001
|
||||||
|
- protocol: UDP
|
||||||
|
port: 30002
|
||||||
|
---
|
||||||
|
# Postgres: only Synapse and MAS need data access; Alloy scrapes the exporter.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-postgres
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: postgres
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: synapse-main
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: matrix-authentication-service
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 5432
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: monitoring
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 9187
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-acme-solver
|
||||||
|
namespace: matrix
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
acme.cert-manager.io/http01-solver: "true"
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 8089
|
||||||
|
|
||||||
|
# Note: coturn runs with hostNetwork: true, so NetworkPolicy does not apply to it at all -
|
||||||
|
# it's already gated by the Hetzner Cloud Firewall instead. Nothing to write here.
|
||||||
Reference in New Issue
Block a user