🛠 Cilium CNI Secure Profile
Salute, I previously described here what CNI is, and I also talked about Cilium with examples, and today I want to share with you the full profile for it.
This profile contains a couple of policies for cluster baseline and butt. Let's take a closer look at it. The profile provides cluster segmentation and additional app‑aware control at the HTTP level, that is, best practice: cluster framework and specific rules.
What does it do?
- Introduces default-deny egress for Pods, except DNS and FQDN, so that a compromised service cannot freely leak data
- CiliumClusterwideNetworkPolicy sets a hard baseline for the entire cluster and basic multi-tenant protection
- Limits paths to the backend only for the database and specific APIs, and frontend for namespaces
- On L7 (HTTP, gRPC, DNS, SQL protocols, requests/methods/URLs within traffic) allows only certain methods, thereby reducing API and preventing calls
apiVersion: "cilium.io/v2"
kind: CiliumClusterwideNetworkPolicy
meta
name: "cluster-baseline-default-deny-egress"
spec:
description: |
Cluster baseline:
- DNS (kube-dns/CoreDNS);
- explicit list of external endpoints
# The policy applies to all endpoints in the cluster
# unless CNP overrides narrow matchLabels
endpointSelector:
matchLabels: {}
egress:
# namespace kube-system
- toEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": kube-system
"k8s-app": kube-dns
toPorts:
- ports:
- port: "53"
protocol: ANY
rules:
dns:
- matchPattern: "*" # any domains
# traffic to a limited list of external hosts
- toFQDNs:
- matchName: "api.payment.example.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
# default-deny for egress
egressDeny:
- {}
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
meta
name: "app-frontend-backend-policy"
namespace: "app-namespace"
spec:
description: |
- ingress: only from frontend to backend
- egress backend: only to the database and external API
- L7 accepts a secure set of methods
# backend‑pods by tag
endpointSelector:
matchLabels:
app: my-backend
ingress:
# traffic from Pods with app=my-frontend
- fromEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": app-namespace
app: my-frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: "GET"
path: "^/healthz$"
- method: "GET"
path: "^/api/public/.*$"
- method: "POST"
path: "^/api/orders$"
- headers:
- "X-API-KEY: .+"
egress:
# backend to the database in the same namespace
- toEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": app-namespace
app: my-database
toPorts:
- ports:
- port: "5432"
protocol: TCP#PostgreSQL
# access to external API limited to cluster CNP via FQDN
- toFQDNs:
- matchName: "api.payment.example.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
#appsec #toolchain #containersecurity #reco #techsolution
