Note
As this is a purposefully insecure system, I have archived it.
Demo environment showing Kubernetes traffic protection at two layers:
- Underlay encryption with Cilium WireGuard
- Service-to-service encryption with Istio mTLS
This repo creates a local kind cluster, deploys a sender-ui and receiver app in a mesh, and runs a privileged sniffer pod to capture packets for inspection!
Caution
The sniffer is intentionally privileged for demo purposes. DO NOT RUN THIS IN PROD PLEASE
When you trigger captures from the UI:
- Underlay capture (
eth0, UDP51871) shows WireGuard-encrypted packets between nodes - Overlay capture (
cilium_wg0, TCP8080) is after WireGuard decryption, but payload still should not reveal app plaintext because Istio mTLS is strict forreceiver
sender-ui(demo-mesh) runs on node labeldemo-role=clientreceiver(demo-mesh) runs on node labeldemo-role=serversniffer(demo-sniffer) runs ondemo-role=client,hostNetwork: true,privileged: true, and usestcpdumpdemo-meshnamespace has sidecar injection enableddemo-sniffernamespace has sidecar injection disabled
Key manifests:
manifests/demo-mesh/receiver.yamlmanifests/demo-mesh/sender-ui.yamlmanifests/demo-sniffer/sniffer.yamlmanifests/demo-mesh/mtls-strict.yamlmanifests/demo-mesh/destination-rule-receiver.yaml
- Linux/macOS/WSL2 shell with Bash
- Docker
- kind
- kubectl
- Helm
Check tool availability:
./scripts/00-ensure-software.shRun scripts in order or just run runall.sh that...runs all scripts in scripts/ sequentially (insane, I know):
bash ./runall.shNote
runall.sh ends with port-forward (scripts/07-port-forward-ui.sh), which keeps the terminal session occupied
If you ran the seventh script (the port foreward one), you can open http://localhost:8080 to see the demo app!
From sender-ui:
- Click
send messageto send plain app traffic through the mesh - Click
send + sniff underlay (eth0 / udp 51871)to capture node-to-node WireGuard traffic - Click
send + sniff overlay (cilium_wg0 / tcp 8080)to capture post-WireGuard interface traffic that should still be mTLS-protected
The UI exposes:
- Last request / inbox data from
sender-uiandreceiver - Raw
tcpdumpoutput from the sniffer pod
Node role labels:
kubectl get nodes -L demo-role -o wideWorkload placement:
kubectl get pods -n demo-mesh -o wide
kubectl get pods -n demo-sniffer -o wideWireGuard status in Cilium:
kubectl -n kube-system exec ds/cilium -- cilium-dbg status | grep -i EncryptionScript-level environment variables:
CLUSTER_NAME(default:wg-istio-demo) used byscripts/01-create-kind-cluster.sh,scripts/04-build-images.sh, anddestroy.shCILIUM_VERSION(default:1.19.1) used byscripts/02-install-cilium-wireguard.shISTIO_VERSION(default:1.29.0) used byscripts/03-install-istio.shKEEP_HELM_REPOS=1preventsdestroy.shfrom removing local Helm repo entriesCONTAINER_CLIcan force image cleanup tool indestroy.sh(docker,nerdctl, orpodman)
Argo CD app definitions are provided under argocd/:
argocd/apps/istio-base.yamlargocd/apps/istio-istiod.yamlargocd/apps/demo-app.yamlargocd/application.yaml
Important
These app specs currently reference https://github.com/ION606/encrypted-k8-msgs. If you run from a fork, update repoURL and targetRevision :)
Destroy cluster and local artifacts:
bash ./destroy.shKeep Helm repo entries while cleaning everything else:
KEEP_HELM_REPOS=1 bash ./destroy.sh