Understanding Flannel Networking and Its Security Implications
Flannel is a lightweight, open-source Container Network Interface (CNI) plugin designed primarily for Kubernetes. Its core mission is to assign each node in the cluster a dedicated subnet and manage IP address allocation across the entire cluster. By default, Flannel uses a simple overlay model, encapsulating pod-to-pod traffic via VXLAN, UDP, or host-gateway backends, while storing network state in either etcd or the Kubernetes API. This simplicity makes Flannel easy to deploy and extremely reliable, but it also means that out-of-the-box, Flannel provides no encryption, no network segmentation, and very little built-in access control. All traffic between pods on different nodes travels unencrypted, and any pod can reach any other pod as long as IP routing works. In production environments with sensitive data, multi-tenancy, or compliance requirements, this default behavior is a serious security gap that must be addressed through deliberate hardening.
Why Flannel Security Hardening Matters
🚀 Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →Securing Flannel is about protecting the confidentiality, integrity, and availability of your overlay network. Without hardening, an attacker who gains access to a single pod or a compromised node can easily eavesdrop on cross-node traffic, perform man-in-the-middle attacks, or move laterally to other services that have no network restrictions. Additionally, a misconfigured or unprotected Flannel control plane (like an unencrypted etcd cluster) exposes subnet allocations and node information, potentially allowing an adversary to manipulate routing or steal IP addresses. Hardening addresses these risks by introducing encryption, network policy enforcement, secure backend communication, and least-privilege principles. The result is a defense-in-depth posture where even if one layer fails, others prevent or mitigate a breach.
How to Use Flannel Securely: Core Techniques
Enabling Encryption with IPsec or WireGuard
Flannel supports encrypting all overlay traffic transparently using either IPsec (via strongSwan) or WireGuard. WireGuard is generally preferred for its simplicity, high performance, and modern cryptography. When the WireGuard backend is selected, flanneld automatically manages WireGuard keys, distributing public keys via Kubernetes Node annotations and establishing secure tunnels between nodes. All pod traffic flowing through the overlay is then encrypted end-to-end.
To enable WireGuard encryption, configure the Flannel ConfigMap as follows:
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-flannel-cfg
namespace: kube-system
data:
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "wireguard",
"PersistentKeepaliveInterval": 25,
"ListenPort": 51820
}
}
After updating the ConfigMap, restart the flannel pods. Flannel will generate WireGuard keys automatically and annotate each node with its public key. You can verify the annotations with:
kubectl get nodes -o custom-columns=NAME:.metadata.name,PUBKEY:.metadata.annotations.flannel\.alpha\.coreos\.com/wireguard-pubkey
If you need to pre-provision keys or rotate them manually, you can generate keys and annotate nodes yourself:
# Generate a WireGuard key pair
wg genkey | tee node-private.key | wg pubkey > node-public.key
# Annotate the node with the public key
kubectl annotate node <node-name> flannel.alpha.coreos.com/wireguard-pubkey=$(cat node-public.key)
For environments where WireGuard is not available or IPsec is mandated, you can use the IPsec backend. A basic PSK-based configuration looks like this:
"Backend": {
"Type": "ipsec",
"PSK": "your-strong-pre-shared-key",
"UDPEncap": true
}
Important: Storing the PSK in plain text inside the ConfigMap is a security risk. Whenever possible, use certificate-based IPsec authentication, or rely on the Kubernetes API to manage secrets injected at flannel startup.
Securing Flannel’s Control Plane
Flanneld needs to read and write network configuration and node subnet leases. By default, recent versions use the Kubernetes API as the backing store, which inherits the cluster’s TLS and RBAC protections automatically. If you are still using the legacy etcd backend, it is critical to secure etcd with mutual TLS authentication and restrict access.
To force Flannel to use the Kubernetes API (recommended), ensure the daemonset arguments include:
containers:
- name: kube-flannel
args:
- --kube-subnet-mgr
- --kube-api-url=https://kubernetes.default.svc.cluster.local:443
When the Kubernetes API is used, Flannel communicates only over the cluster’s secure control plane. You must also define strict RBAC roles for the flannel service account so that it can only access the necessary resources (Nodes, ConfigMaps, etc.) and nothing else. A minimal RBAC example:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: flannel-minimal
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch", "patch"]
- apiGroups: [""]
resources: ["nodes/status"]
verbs: ["patch"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: flannel-minimal-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel-minimal
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-system
If you must use etcd, always enable TLS. Provide the CA certificate, client certificate, and client key to flanneld via mounted secrets:
args:
- --etcd-endpoints=https://etcd-cluster:2379
- --etcd-cafile=/etc/etcd-secrets/ca.crt
- --etcd-certfile=/etc/etcd-secrets/client.crt
- --etcd-keyfile=/etc/etcd-secrets/client.key
Make sure the etcd secrets are stored in Kubernetes Secrets with restricted access and mounted as volumes, not baked into the container image.
Applying Network Policies with a Policy Engine
Flannel does not enforce Kubernetes NetworkPolicy objects. To achieve micro-segmentation and limit pod-to-pod communication, you must integrate a network policy engine that operates alongside Flannel’s overlay. A common and lightweight approach is to deploy Calico in policy-only mode, where Calico handles policy enforcement using iptables while Flannel continues to manage IP addressing and routing. This gives you the best of both worlds: Flannel’s simplicity and Calico’s powerful policy engine.
Install Calico for policy-only with Flannel by applying the following manifest (adjust the interface and IP ranges as needed):
kubectl apply -f https://docs.projectcalico.org/manifests/calico-policy-only.yaml
Once Calico is running, you can define NetworkPolicy resources to restrict traffic. For example, a policy that only allows ingress from pods labeled app: frontend to pods labeled app: backend on port 8080:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: production
spec:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
policyTypes:
- Ingress
Even with Flannel’s overlay, this policy will be enforced by Calico’s iptables rules on every node, blocking unauthorized traffic before it enters the pod. You can also create default-deny policies to enforce a zero-trust model across namespaces.
Best Practices for Flannel Security Hardening
- Prefer the Kubernetes API backend over etcd. It reduces the attack surface and automatically benefits from RBAC and TLS. Only use etcd if you have a specific reason and always secure it with mutual TLS.
- Always enable encryption. Use WireGuard for modern, high-performance encryption with minimal configuration overhead. If WireGuard is not possible, IPsec with certificate authentication is a robust alternative.
- Combine Flannel with a network policy engine. Calico policy-only, Cilium, or Antrea can enforce micro-segmentation and zero-trust networking on top of the Flannel overlay. Start with a default-deny policy and open only required paths.
-
Run Flannel with least-privilege RBAC. Avoid granting
cluster-adminto the flannel service account. Restrict it to Nodes, ConfigMaps, and necessary coordination resources. - Restrict node-level network access. Use cloud security groups, firewall rules, or host-level iptables to limit inbound connections to Flannel’s ports (e.g., UDP 8472 for VXLAN, UDP 51820 for WireGuard, UDP 4500/500 for IPsec) only from other nodes in the cluster.
- Rotate encryption keys regularly. For WireGuard, you can automate key rotation by deleting the node annotation; Flannel will regenerate and redistribute keys. For IPsec PSK, rotate the shared key and restart flannel pods (preferably with a rolling update).
- Disable the host-gw backend in multi-tenant or untrusted networks. Host-gw relies on direct routing without encapsulation, meaning pod traffic may be exposed to the underlying network infrastructure. Use VXLAN or WireGuard backends instead.
- Protect Flannel configuration and secrets. Use Kubernetes RBAC to restrict who can read or modify the Flannel ConfigMap and any associated secrets. An attacker with write access to the ConfigMap could redirect traffic or disable encryption.
- Keep Flannel and its dependencies updated. Regularly apply security patches to Flannel, the CNI plugins, and the kernel. Newer versions often bring security improvements and bug fixes.
- Harden the node operating system and container runtime. Flannel pods run privileged; ensure the node itself is secure, use minimal base images, and enforce Pod Security Standards to reduce the risk of container escape.
- Monitor overlay traffic and Flannel logs. Integrate Flannel’s logs into a centralized logging system and set up alerts for unexpected backend changes, repeated connection failures, or unusual node annotations. Tools like Prometheus can scrape Flannel’s metrics endpoint.
Practical Implementation: A Step-by-Step Security Hardening Example
Let’s walk through hardening a typical Flannel deployment to include WireGuard encryption and Calico policy enforcement. We assume you already have a Kubernetes cluster with Flannel installed via the standard manifest.
Step 1: Switch to WireGuard encryption.
Edit the kube-flannel-cfg ConfigMap to set the backend type to wireguard as shown earlier. Delete the existing flannel pods so they restart with the new configuration:
kubectl delete pods -n kube-system -l app=flannel
Verify that each node now has a flannel.alpha.coreos.com/wireguard-pubkey annotation, and that flannel pods are running without errors.
Step 2: Deploy Calico policy-only engine.
Apply the Calico policy-only manifest and ensure the calico-node pods are running alongside flannel:
kubectl apply -f calico-policy-only.yaml
kubectl get pods -n kube-system -l k8s-app=calico-node
Step 3: Create default-deny network policies.
Start with a blanket deny-all policy in a test namespace to validate enforcement:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: test-ns
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Then selectively allow required flows using more specific policies as shown earlier. Test connectivity between pods to confirm isolation.
Step 4: Lock down RBAC for Flannel.
Replace the default ClusterRole binding with the minimal one described above. Ensure the flannel service account is used by the daemonset and that no overly permissive bindings exist.
Step 5: Apply firewall restrictions on node interfaces.
On each node, restrict inbound UDP on port 51820 (WireGuard) and 8472 (VXLAN, if still used) to only the IP addresses of other cluster nodes. In cloud environments, update security groups; on bare metal, use iptables or nftables rules.
After these steps, you have a Flannel-based network that encrypts all overlay traffic, enforces micro-segmentation via network policies, operates with minimal Kubernetes permissions, and limits network exposure at the node level.
Conclusion
Flannel’s simplicity and reliability make it a popular choice for Kubernetes networking, but its default configuration leaves significant security gaps. By enabling encryption with WireGuard or IPsec, securing the control plane, integrating a network policy engine, and following least-privilege principles, you transform Flannel into a robust, defense-in-depth networking layer suitable for production and regulated environments. The techniques and best practices outlined in this tutorial give you a clear roadmap to harden Flannel without sacrificing its ease of use. Regularly audit your configuration, keep components updated, and continuously monitor overlay traffic to maintain a strong security posture as your cluster evolves.