diff --git a/README.md b/README.md index 298558d..31ae231 100644 --- a/README.md +++ b/README.md @@ -283,6 +283,12 @@ readiness, pod restart storms, unavailable deployments, node/PVC storage pressure, Traefik 5xx spikes, website availability, and Gitea/Pi-hole scrape coverage. Keep this set small so alerts remain actionable. +Application egress is controlled with Kubernetes NetworkPolicies where the lab +owns the workload. The website namespace defaults to denied egress and allows +only DNS, Redis, and the Debian Ollama endpoint. The security lab namespace is +isolated from the cluster and LAN while allowing DNS plus outbound HTTP/HTTPS +for controlled practice targets. + Focused doctor commands run narrower read-only checks and print the most likely next step: diff --git a/README.md.tmpl b/README.md.tmpl index d7d661a..33e7fc1 100644 --- a/README.md.tmpl +++ b/README.md.tmpl @@ -283,6 +283,12 @@ readiness, pod restart storms, unavailable deployments, node/PVC storage pressure, Traefik 5xx spikes, website availability, and Gitea/Pi-hole scrape coverage. Keep this set small so alerts remain actionable. +Application egress is controlled with Kubernetes NetworkPolicies where the lab +owns the workload. The website namespace defaults to denied egress and allows +only DNS, Redis, and the Debian Ollama endpoint. The security lab namespace is +isolated from the cluster and LAN while allowing DNS plus outbound HTTP/HTTPS +for controlled practice targets. + Focused doctor commands run narrower read-only checks and print the most likely next step: diff --git a/apps/security-lab/network-policy.yaml b/apps/security-lab/network-policy.yaml index e312e34..cda4959 100644 --- a/apps/security-lab/network-policy.yaml +++ b/apps/security-lab/network-policy.yaml @@ -1,5 +1,48 @@ apiVersion: networking.k8s.io/v1 kind: NetworkPolicy +metadata: + name: security-lab-default-deny-egress + namespace: security-lab +spec: + podSelector: {} + policyTypes: + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: security-lab-allow-web-egress + namespace: security-lab +spec: + podSelector: + matchLabels: + homelab.dev/security-lab-app: "true" + policyTypes: + - Egress + egress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + ports: + - protocol: UDP + port: 53 + - protocol: TCP + port: 53 + - to: + - ipBlock: + cidr: 0.0.0.0/0 + except: + - 10.96.0.0/12 + - 192.168.100.0/24 + ports: + - protocol: TCP + port: 80 + - protocol: TCP + port: 443 +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy metadata: name: security-lab-default-deny-ingress namespace: security-lab diff --git a/apps/website/kustomization.yaml b/apps/website/kustomization.yaml index 9cb3a02..586a584 100644 --- a/apps/website/kustomization.yaml +++ b/apps/website/kustomization.yaml @@ -2,4 +2,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - namespace.yaml + - network-policy.yaml - web-app.yaml diff --git a/apps/website/network-policy.yaml b/apps/website/network-policy.yaml new file mode 100644 index 0000000..8fcc739 --- /dev/null +++ b/apps/website/network-policy.yaml @@ -0,0 +1,56 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: website-default-deny-egress + namespace: website-production +spec: + podSelector: {} + policyTypes: + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: website-allow-required-egress + namespace: website-production +spec: + podSelector: + matchLabels: + app: php-website + policyTypes: + - Egress + egress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + ports: + - protocol: UDP + port: 53 + - protocol: TCP + port: 53 + - to: + - podSelector: + matchLabels: + app: website-redis + ports: + - protocol: TCP + port: 6379 + - to: + - ipBlock: + cidr: 192.168.100.73/32 + ports: + - protocol: TCP + port: 11434 +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: website-redis-deny-egress + namespace: website-production +spec: + podSelector: + matchLabels: + app: website-redis + policyTypes: + - Egress diff --git a/docs/jeannie.1.md b/docs/jeannie.1.md index 9d45567..dcaae4d 100644 --- a/docs/jeannie.1.md +++ b/docs/jeannie.1.md @@ -57,6 +57,11 @@ Prometheus alerts They cover node readiness, restart storms, unavailable deployments, storage pressure, Traefik 5xx, and core service visibility. +NetworkPolicies +: Owned application namespaces include egress policies. The website can reach +DNS, Redis, and the Debian Ollama endpoint; the security lab can reach DNS and +external web targets while remaining isolated from cluster and LAN ranges. + `validate` : Run non-mutating repository checks used by the GitOps promotion flow: inventory, generated docs, Bash syntax, shellcheck, YAML parsing, OpenTofu