Apply Default-Deny Network Policies
Deny all pod traffic by default, then allow only the flows each workload needs, so a compromised pod cannot reach unrelated services.
Task
Adopt Kubernetes NetworkPolicies that default to deny and open only required paths.
When to use this
Pods can talk to each other freely, so a single compromised pod can reach databases and internal services across the cluster.
Prerequisites
- A CNI that enforces NetworkPolicy
- An inventory of required pod-to-pod flows
Steps
1. Create a default-deny policy for ingress and egress in each namespace.
Expected output: All traffic is blocked unless explicitly allowed.
2. Add allow policies for DNS egress and the specific service dependencies.
Expected output: Workloads can resolve names and reach their dependencies.
3. Allow ingress only from known sources on the ports actually used.
Expected output: Exposure is limited to intended callers.
4. Test with a curl from a pod that should be blocked.
kubectl exec -it test-pod -- nc -vz app-svc 5432Expected output: The policy is proven to deny.
Troubleshooting
Problem
Workload cannot resolve DNS
Solution
Default-deny egress blocks DNS; add an explicit egress rule to the cluster DNS service.
Problem
Health checks fail
Solution
Allow ingress from the kubelet and ingress controller explicitly; do not weaken the default deny.
Limitations
- NetworkPolicy depends on the CNI enforcing it; some CNIs ignore policies, giving a false sense of security.
- Policies are namespace-scoped and labeling-based, so a mislabel can accidentally allow or block traffic.
Context
Adopt Kubernetes NetworkPolicies that default to deny and open only required paths. Pods can talk to each other freely, so a single compromised pod can reach databases and internal services across the cluster.
Steps
- Create a default-deny policy for ingress and egress in each namespace. Expected: All traffic is blocked unless explicitly allowed.
- Add allow policies for DNS egress and the specific service dependencies. Expected: Workloads can resolve names and reach their dependencies.
- Allow ingress only from known sources on the ports actually used. Expected: Exposure is limited to intended callers.
- Test with a curl from a pod that should be blocked. Expected: The policy is proven to deny.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: { name: default-deny, namespace: prod }
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
# no ingress/egress rules => deny all
Verify
- All traffic is blocked unless explicitly allowed.
- Workloads can resolve names and reach their dependencies.
- Exposure is limited to intended callers.
- The policy is proven to deny.
Limits
- NetworkPolicy depends on the CNI enforcing it; some CNIs ignore policies, giving a false sense of security.
- Policies are namespace-scoped and labeling-based, so a mislabel can accidentally allow or block traffic.