k8s-security.pro
#23 Network Security professional

Cilium Network Policy

eBPF-based network policies with Cilium providing L3/L4/L7 traffic control, DNS-aware filtering, and HTTP-level security rules.

CIS Benchmark
5.3.2
MITRE ATT&CK
T1046T1071

Overview

This template implements Cilium-native network policies that go beyond standard Kubernetes NetworkPolicy resources. Cilium uses eBPF (extended Berkeley Packet Filter) to enforce network rules directly in the Linux kernel, providing L7 (application layer) visibility and control. This means you can write policies that filter based on HTTP methods, paths, DNS names, and more — something impossible with standard NetworkPolicy.

Security threat addressed: Standard Kubernetes NetworkPolicy only operates at L3/L4 (IP and port). Attackers can abuse allowed ports to send malicious HTTP requests, exfiltrate data via DNS tunneling, or access unauthorized API endpoints. Cilium’s L7 policies close these gaps.

When to use: Use this template when Cilium is your cluster’s CNI. These policies complement or replace standard NetworkPolicy with more granular controls.

Threat Model

  • L7 attack prevention: Block specific HTTP methods or paths even when the port is allowed.
  • DNS tunneling defense: Restrict DNS queries to only approved domains, blocking DNS-based exfiltration.
  • API-level access control: Enforce path-based authorization at the network layer, independent of application code.

MITRE ATT&CK:

  • T1046 — Network Service Scanning: Cilium’s identity-based policies prevent reconnaissance even on allowed ports.
  • T1071 — Application Layer Protocol: L7 filtering blocks abuse of allowed protocols for C2 or exfiltration.

YAML Source

# L3/L4 default deny with Cilium
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: default-deny
  namespace: production  # ACTION REQUIRED: Change to your namespace
  labels:
    app.kubernetes.io/name: k8s-security
    app.kubernetes.io/part-of: k8s-security-pro
    app.kubernetes.io/managed-by: k8s-security-pro
spec:
  endpointSelector: {}
  ingress:
  - {}
  egress:
  - {}

---
# L7 HTTP-aware policy — allow only GET/POST to API
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: api-l7-policy
  namespace: production
  labels:
    app.kubernetes.io/name: k8s-security
    app.kubernetes.io/part-of: k8s-security-pro
    app.kubernetes.io/managed-by: k8s-security-pro
spec:
  endpointSelector:
    matchLabels:
      app: api-server
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: frontend
    toPorts:
    - ports:
      - port: "8080"
        protocol: TCP
      rules:
        http:
        - method: GET
          path: "/api/v1/.*"
        - method: POST
          path: "/api/v1/.*"

---
# DNS-aware egress — only allow specific external domains
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: dns-egress-policy
  namespace: production
  labels:
    app.kubernetes.io/name: k8s-security
    app.kubernetes.io/part-of: k8s-security-pro
    app.kubernetes.io/managed-by: k8s-security-pro
spec:
  endpointSelector:
    matchLabels:
      app: backend
  egress:
  # Allow DNS
  - toEndpoints:
    - matchLabels:
        k8s:io.kubernetes.pod.namespace: kube-system
        k8s-app: kube-dns
    toPorts:
    - ports:
      - port: "53"
        protocol: UDP
  # Allow specific external domains only
  - toFQDNs:
    - matchName: "api.stripe.com"  # ACTION REQUIRED: Add your domains
    - matchName: "api.github.com"
    toPorts:
    - ports:
      - port: "443"
        protocol: TCP

Deployment

  1. Verify Cilium is installed: cilium status
  2. Apply the policies: kubectl apply -f 23_cilium_network_policy.yaml
  3. Monitor enforcement: cilium monitor --type policy-verdict
  4. Check dropped traffic: hubble observe --verdict DROPPED

Verification

# List Cilium policies
kubectl get ciliumnetworkpolicies -n production

# Check endpoint policy status
cilium endpoint list -o json | jq '.[].status.policy'

# Test L7 policy (should be blocked — DELETE not allowed)
kubectl exec deploy/frontend -n production -- curl -X DELETE http://api-server:8080/api/v1/resource

# Verify DNS egress (should work)
kubectl exec deploy/backend -n production -- nslookup api.stripe.com

Further Reading

Get Full Access to This Template

This template is included in the Professional tier and above.

View Pricing Plans