Guide demonstrating how to enable and verify Cilium IPsec encryption between pods by capturing and comparing unencrypted and encrypted traffic and inspecting encapsulation and cilium_host outer addresses
This guide demonstrates how to enable and verify IPsec encryption between pods using Cilium. We’ll use a simple three-node cluster (control-plane, worker1, worker2) connected via a single router. The workflow:
Deploy pods on worker1 and worker2.
Generate pod-to-pod traffic (ICMP/HTTP).
Capture traffic on the router before enabling encryption (unencrypted).
Enable Cilium encryption (IPsec).
Capture traffic again (encrypted) and verify in Wireshark.
Inspect node host interfaces to understand encapsulation addresses.
Topology (logical):
Overview of steps
Verify pods are scheduled and reachable across nodes.
Capture unencrypted traffic on the router (validate visibility).
Add IPsec keys as a Kubernetes secret.
Enable encryption in the Cilium Helm values and upgrade.
Capturing unencrypted traffic on the router
Run tcpdump on the router interface connected to the cluster (ens38 in this demo). Save to unencrypted.pcap. Packet capture requires elevated privileges.
Run tcpdump with sudo if you get “Operation not permitted” — packet capture needs root privileges.
Copy
user1@router:~$ sudo tcpdump -nnvv -i ens38 -w unencrypted.pcap[sudo] password for user1:tcpdump: listening on ens38, link-type EN10MB (Ethernet), snapshot length 262144 bytes^C172 packets captured172 packets received by filter0 packets dropped by kernel
Open unencrypted.pcap in Wireshark. With encryption disabled you will observe pod-to-pod traffic in cleartext for non-encrypted protocols (ICMP, HTTP). Note that application protocols using their own encryption (TLS) remain encrypted at the application layer — you will see TLS records but not the decrypted payload.
You can expand a frame to view ICMP or HTTP payload in hex/ASCII to confirm visibility when encryption is not enabled.Enable IPsec encryption in Cilium
Cilium supports IPsec or WireGuard for node-to-node encryption. The following demonstrates enabling IPsec.
Create the Kubernetes secret containing IPsec keys in kube-system. The key entry format:
key-id rfc4106(gcm(aes)) <PSK-in-hex> <key-size-in-bits>Generate a 16-byte (128-bit) key as an example and create the secret:
Open encrypted.pcap in Wireshark. With Cilium IPsec enabled you should no longer see ICMP or HTTP payloads in cleartext for inter-node pod flows. Instead, you will typically see:
Encapsulating Security Payload (ESP) frames (the encrypted inner payload).
Possibly additional encapsulation like VXLAN + ESP depending on Cilium configuration.
Large frame sizes due to encapsulation overhead.
Example encrypted-frame excerpt:
Copy
Frame 9: 1448 bytes on wire (11584 bits)Internet Protocol Version 4, Src: 192.168.211.128, Dst: 192.168.44.128User Datagram Protocol, Src Port: 51422, Dst Port: 8472Virtual eXtensible Local Area NetworkInternet Protocol Version 4, Src: 10.0.1.124, Dst: 10.0.2.104Encapsulating Security Payload ESP SPI: 0x00000003 (3) ESP Sequence: 15
You should see ESP where the inner protocol (ICMP/HTTP) is not visible — the payload is encrypted and Wireshark cannot display inner protocol fields.Why captures show cilium_host (node) IPs as outer addresses
When Cilium encrypts node-to-node traffic it encapsulates pod IPs inside an outer packet that uses node-local Cilium host addresses. Each node typically has a cilium_host interface with a /32 address reserved for encapsulation. For example:
Copy
user1@worker1:~$ ip addr4: cilium_host@cilium_net: <...> mtu 1500 ... link/ether ee:c1:7f:8d:6b:fe brd ff:ff:ff:ff:ff:ff inet 10.0.1.124/32 scope global cilium_host
Worker2 will have its own cilium_host (e.g., 10.0.2.104/32). On the wire you will therefore see outer source/destination addresses set to these host addresses and ESP as the protocol; the inner (encrypted) packet contains the original pod IPs and payload.Recap and key takeaways
Before enabling Cilium encryption, router captures show pod payloads (ICMP, HTTP) in cleartext.
After enabling Cilium IPsec, inter-node traffic is encapsulated and encrypted — Wireshark shows ESP (and possibly VXLAN) and you cannot read the inner ICMP/HTTP payloads from the router capture.
Cilium uses node-local host interfaces (cilium_host) for outer addresses; the receiving node decrypts and forwards the inner pod traffic to the destination pod.
Use IPsec or WireGuard depending on your operational and performance requirements.