Files
yucca/kubernetes/components/apps/networkpolicies.yaml
T

172 lines
5.5 KiB
YAML

---
# Ingress-only network policies for the yucca namespace — the pods here hold
# the JWT signing key, S3 credentials, and the database, so lateral movement
# from any other compromised pod must not reach them. Egress is deliberately
# NOT restricted in this pass (external RGW/OIDC/Polar egress needs FQDN rules
# — a CiliumNetworkPolicy follow-up). Flow inventory:
# envoy (envoy-system) → yucca-api:3020, web:5173, michael:3010,
# meta:8080 (HTTPRoutes)
# yucca-api → michael = hairpin via the ingress VIP, so it ARRIVES as
# envoy traffic — no direct pod-to-pod allow needed
# web (SSR) → yucca-api:3020
# api/admin-api/worker → CNPG pods :5432 (yucca-db-rw/-ro)
# CNPG replication → CNPG pods :5432 (pod↔pod)
# cnpg-system operator → CNPG pods :8000 (instance manager)
# admin-api / metrics-worker: NO inbound in this component (no HTTPRoute;
# cron worker) — the default-deny is their whole
# policy here. father additionally opens admin-api
# to its netops gateway (apps/prod/htz-fsn1/netops/
# httproutes.yaml, NetBird-only access).
# nothing scrapes this namespace; logs are collected node-side; kubelet
# probes are exempt from NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: yucca
spec:
podSelector: {}
policyTypes: [Ingress]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-yucca-api
namespace: yucca
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: yucca-api
policyTypes: [Ingress]
ingress:
- from:
# The app gateway's proxy pods (GatewayNamespace mode → envoy-system).
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: envoy-system
podSelector:
matchLabels:
app.kubernetes.io/name: envoy
# web's server-side rendering (YUCCA_API_URL=http://yucca-api:3020).
- podSelector:
matchLabels:
app.kubernetes.io/name: web
# futo-backups-bot → /api/internal/discord/* (shared-secret guarded;
# the gateway 404-shadows /api/internal so pod-to-pod is the only way in).
- podSelector:
matchLabels:
app.kubernetes.io/name: futo-backups-bot
ports:
- { port: 3020, protocol: TCP }
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-web
namespace: yucca
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: web
policyTypes: [Ingress]
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: envoy-system
podSelector:
matchLabels:
app.kubernetes.io/name: envoy
ports:
- { port: 5173, protocol: TCP }
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-meta
namespace: yucca
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: meta
policyTypes: [Ingress]
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: envoy-system
podSelector:
matchLabels:
app.kubernetes.io/name: envoy
ports:
- { port: 8080, protocol: TCP }
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-michael
namespace: yucca
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: michael
policyTypes: [Ingress]
ingress:
- from:
# Both public restic clients (${GW_HOST}) and yucca-api's hairpined
# RESTIC_ENDPOINT traffic arrive via the gateway.
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: envoy-system
podSelector:
matchLabels:
app.kubernetes.io/name: envoy
ports:
- { port: 3010, protocol: TCP }
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-database
namespace: yucca
spec:
# CNPG instance pods (primary + streaming replicas).
podSelector:
matchLabels:
cnpg.io/cluster: yucca-db
policyTypes: [Ingress]
ingress:
# Postgres: the app set + instance↔instance streaming replication.
- from:
- podSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values: [yucca-api, yucca-admin-api, yucca-metrics-worker]
- podSelector:
matchLabels:
cnpg.io/cluster: yucca-db
ports:
- { port: 5432, protocol: TCP }
# Instance-manager REST (status/reload) from the CNPG operator.
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: cnpg-system
podSelector:
matchLabels:
app.kubernetes.io/name: cloudnative-pg
ports:
- { port: 8000, protocol: TCP }
# Built-in postgres exporter, scraped by the observability vmagent
# (VMPodScrape yucca-database).
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: observability
podSelector:
matchLabels:
app.kubernetes.io/name: vmagent
ports:
- { port: 9187, protocol: TCP }