How I used eBPF, Reinforcement Learning, and a healthy dose of paranoia to build an attack surface that shape-shifts faster than hackers can blink.

Let me paint you a picture.

You're a hacker. You've spent three days silently mapping a company's microservice topology — cataloguing IP addresses, probing ports, fingerprinting software versions. You've got the whole network drawn out on your second monitor like you're planning a heist in an Ocean's Eleven sequel. You crack your knuckles. You launch your exploit.

And the entire network has already moved.

Every IP you mapped? Gone. Every port you catalogued? Reshuffled. That vulnerability you found? It's now a honeypot that's recording everything you do, broadcasting your source IP to the entire infrastructure, and feeding your attack patterns into an AI that's actively learning how to make your life worse.

Welcome to Chaos AMTD — my open-source Automated Moving Target Defense framework. It's the cybersecurity equivalent of trying to rob a house that rearranges its rooms every 60 seconds and replaces the front door with a trap that calls the police.

I built the prototype. It works. And I'm going to walk you through exactly how.

The Problem: Cybersecurity Is a Rigged Game

Here's the dirty truth about traditional cybersecurity that nobody at the conference keynote wants to say out loud: the game is rigged against defenders.

Think of it like a goalkeeper facing infinite penalty kicks. The attacker only needs to score once. The defender has to block every single shot, forever, from an opponent who can practice against your exact goal as long as they want before taking the kick.

Your firewall? It's a bouncer at a club with a guest list — great until someone shows up with a fake ID it hasn't seen before. Your IDS/IPS? It's a detective who can only solve crimes that match cases they've already closed. And your WAF? It's basically a very expensive "No Trespassing" sign.

Meanwhile, attackers have generative AI writing polymorphic malware, "living-off-the-land" techniques that use your own system tools against you, and all the time in the world to map your static, predictable, sitting-duck infrastructure.

The problem isn't that our security tools are bad. The problem is that our entire infrastructure is too polite. It sits still. It uses the same IP address for months. It runs the same software stack on every node. It's basically telling attackers: "Take your time, I'll wait."

So I asked myself: what if the infrastructure refused to sit still?

The Idea: What If Your Network Had ADHD?

Moving Target Defense isn't a new concept — NIST and MITRE have been talking about it for years. The core philosophy is beautifully simple: if the attacker's reconnaissance becomes obsolete before they can use it, the attack fails by default.

But here's where most MTD implementations fall flat — they operate on dumb timers. Shuffle the IPs every 5 minutes. Rotate the ports every hour. It's like changing your locks on a fixed schedule and hoping the burglar doesn't figure out the pattern.

Chaos takes a fundamentally different approach. Three ideas power the whole thing:

1. AI-driven mutations, not timers. A Reinforcement Learning agent watches network telemetry in real time. Port scan detected? Mutation happens now. Everything quiet? The system conserves resources while maintaining a low baseline of background shuffling — just enough to keep things unpredictable.

2. Kernel-level speed. We're not doing this in userspace like amateurs. The routing happens via eBPF programs injected directly into the Linux kernel, operating at O(1) complexity. When the mutation controller says "move," the eBPF maps update instantaneously — no network stack restart, no iptables reload that takes longer than my morning coffee.

3. Weaponized leftovers. When a backend IP gets shuffled out, most systems would just delete the old address. Chaos keeps it around as a honeypot. Since all legitimate traffic has already been migrated to the new address via signed session cookies, anyone knocking on the old door is definitionally malicious. Zero false positives. The system logs everything the attacker does and feeds it back to the RL agent.

It's not just defense. It's defense that learns from its attackers and gets better at messing with them over time. It's a security system with a grudge.

The Architecture: Three Tiers of Organized Chaos

Let me break down what I actually built. The framework has three components, and they work together like a well-oiled paranoia machine.

Tier 1: The Mutation Controller (The Brain)

This is the Python/FastAPI service that makes the decisions. It houses two critical sub-systems:

The Entropy Engine computes cryptographically secure randomized mappings — deciding which IPs get shuffled where. In the full Kubernetes vision, this interfaces with the API server to spin up containers on randomized subnets. In my prototype, it selects from a pre-defined pool of standby containers.

The RL Policy Engine is where things get spicy. It models the environment as a Markov Decision Process and uses Proximal Policy Optimization (PPO) to decide the optimal mutation frequency. Why PPO? Because it controls how aggressively the policy evolves — you don't want your defense system to destabilize your own network during training. That would be like hiring a guard dog that also eats the furniture.

The agent's reward function creates a beautiful tension: detecting reconnaissance rewards aggressive mutation, while unnecessary mutations during calm periods get penalized for the latency they introduce. The system learns to be paranoid exactly when it should be, and chill exactly when it can afford to be.

Tier 2: The Shuffling Proxy (The Muscle)

This is the Go-based data plane, and it's where the real engineering wizardry lives.

Here's the problem with traditional Kubernetes networking: kube-proxy uses iptables, and iptables evaluates rules sequentially. When you've got thousands of microservices and thousands of ephemeral IP rules being generated by an MTD controller, your packet traversal path becomes a traffic jam. Enterprise benchmarks have shown that reloading massive iptables rule sets can take hours. Sub-millisecond MTD? Not happening.

Chaos bypasses iptables entirely using eBPF (Extended Berkeley Packet Filter). The eBPF program gets injected directly into the kernel and attaches to the NIC via XDP (eXpress Data Path). Packets get intercepted before they even enter the normal networking stack. The routing lookup happens in O(1) hash maps. When the Mutation Controller says "new IP," the eBPF maps update atomically. No restart. No reload. No drama.

The C code is concise — it reads packet headers, looks up the destination in the route map, rewrites the IP, recalculates the checksum, and issues an XDP_PASS or XDP_TX. All in kernel space. All at wire speed.

But here's the hard part most MTD papers gloss over: session persistence. If you shuffle a backend IP mid-session, you break every active connection. Every logged-in user gets kicked. Every transaction fails. Congratulations, you've defended against hackers by accidentally DDoS-ing yourself.

Chaos solves this with HMAC-SHA256 signed session cookies. On first connection, the proxy issues a chaos_session cookie containing the backend IP, cryptographically signed so it can't be forged. On subsequent requests, the proxy verifies the signature and routes the user to their original backend, regardless of what the "current" active backend is. The mutation is completely invisible to legitimate users.

Tier 3: The Deception Layer (The Trap)

This is my favorite part — and it's what transforms Chaos from "clever defense" to "actively hostile to attackers."

When the Mutation Controller shuffles a backend from IP-A to IP-B, IP-A doesn't get deleted. It gets decommissioned into a honeypot with a configurable TTL (5 minutes in the prototype). The proxy keeps monitoring it.

Here's the beautiful logic: all legitimate traffic has already been migrated via session cookies. So if anyone tries to talk to IP-A… they're using stale reconnaissance data. They're an attacker. Period. The false positive rate approaches zero because the system architecture guarantees that only adversaries would hit those addresses.

The proxy logs everything — source IP, payload, behavioral fingerprints — and feeds it back to the RL agent. The agent studies the methodology and refines future mutation strategies. Meanwhile, the attacker's source IP gets broadcast to the entire infrastructure for global blocking.

And here's the chef's kiss: because these honeypots were real, production systems just seconds ago, they have authentic configurations, real uptime markers, and legitimate protocol responses. Advanced hackers who use tools like Shodan to calculate "Honeyscores" and avoid fake systems? They can't tell the difference. The decommissioned nodes look real because they were real.

It's two-sided deception. The attacker doesn't just fail — they waste resources, generate anxiety about whether their own operations have been compromised, and hand over intelligence to the very system they're trying to attack.

Show Me the Code

Enough theory. Let me show you the prototype in action.

The whole thing spins up with Docker Compose — a proxy container, two backend containers, and a custom bridge network:

docker-compose up --build -d

This gives you:

  • Proxy at 10.0.0.10 (ports 8080 for client traffic, 9090 for management)
  • Backend 1 at 10.0.0.101
  • Backend 2 at 10.0.0.102

Test 1: Hit the proxy, get a session cookie

curl -s -c cookies.txt -D headers.txt http://localhost:8080/
# → {"status":"ok","backend_id":"backend_1"}

You've been routed to backend_1 and issued a signed chaos_session cookie.

Test 2: Trigger a mutation

curl -s -X POST http://localhost:9090/update_map \
  -H 'Content-Type: application/json' \
  -d '{"new_backend_ip": "10.0.0.102"}'
# → {"decommissioned":"10.0.0.101","mapped":"10.0.0.10 to 10.0.0.102","status":"success"}

The active backend is now backend_2. The old IP (10.0.0.101) is now a honeypot.

Test 3: Your session survives the mutation

curl -s -b cookies.txt http://localhost:8080/
# → {"status":"ok","backend_id":"backend_1"}  ← Still routed to YOUR backend!

Even though the "current" backend is backend_2, your cookie pins you to backend_1. Mutation? What mutation? You didn't notice a thing.

Test 4: Check the honeypots

curl -s http://localhost:9090/status
# → {"active_backend":"10.0.0.102","active_honeypots":["10.0.0.101"]}
curl -s http://localhost:9090/honeypot_events
# → Shows any hits on decommissioned addresses

If someone tries to use a stale cookie pointing to the decommissioned IP, the proxy flags it as a HONEYPOT_HIT, invalidates the cookie, and issues a fresh one.

The eBPF Program: Where Packets Go to Get Rewritten

For the kernel-level enthusiasts — here's what the XDP program does in production (the C code compiles and is ready for native Linux deployment):

The program attaches to the NIC and intercepts every packet before it touches the networking stack. It checks three things:

  1. Is this packet headed to a honeypot? → Log it, increment the hit counter, flag it as malicious.
  2. Is this packet headed to the proxy IP? → Look up the current backend in the route map, rewrite the destination IP, recalculate the checksum, and pass it along.
  3. Neither? → Let it through.

The route map and honeypot map are eBPF hash maps — O(1) lookups, atomically updateable from userspace. When the Mutation Controller triggers a shuffle, the Go loader updates the maps. No syscalls. No network restart. No dropped packets.

(Note: Docker Desktop for Mac/Windows virtualizes the network stack in a way that doesn't play nice with generic XDP, so the prototype defaults to a user-space L7 reverse proxy. The eBPF code is production-ready for native Linux — just flip the switch.)

Why This Matters Beyond My GitHub Stars

Let me zoom out for a second.

6G is coming, and it's going to be a cybersecurity nightmare. The whole architecture pushes compute to the edge — thousands of decentralized nodes that are physically and logically exposed. You can't put a heavyweight firewall at every edge node without destroying the sub-millisecond latency that's the entire point of 6G. Global telecom standards bodies have explicitly identified AMTD as a foundational requirement for secure 6G networks. Chaos is built for exactly this use case — lightweight, autonomous, kernel-level fast.

Fintech is getting hammered. Financial platforms face application-layer DDoS floods exceeding 100k requests per second, and zero-day vulnerabilities in third-party modules outpace signature-based detection. Chaos abstracts the entire application infrastructure. Attackers can't map transaction pipelines if the underlying network addresses change before they can finish their scan.

OT/ICS environments are terrifyingly vulnerable. Power grids, water treatment plants, manufacturing lines — they're running on legacy controllers that were never designed for internet exposure. And you can't deploy aggressive IT security playbooks because automated isolation or active scanning can physically damage equipment. Chaos wraps legacy OT assets in a polymorphic overlay without touching the fragile controllers. The PLCs stay static and safe. The access gateways dance.

The Complexity Inversion: Making Hackers Cry

Here's the mathematical beauty of this approach.

Traditional cybersecurity: the defender must be right 100% of the time. The attacker must be right once.

With Chaos: the attacker must be right 100% of the time — mapping the network, finding the vulnerability, and delivering the payload — all within the microseconds before the next mutation cycle. The defender just has to keep the music playing.

This exponentially increases what cryptographers call the "work factor." You can't use pre-packaged exploits against a target that doesn't exist in the same configuration for more than a minute. You'd need bespoke, ultra-low-latency reconnaissance tools that can map and exploit in milliseconds. Building those tools costs serious money and compute. The economic advantage shifts back to the defender.

We went from "the attacker has all the time in the world" to "the attacker is speed-running against a clock they can't see."

Honest Limitations (Because I'm Not Writing a Sales Brochure)

Let me be real about what's hard:

Deployment complexity is significant. This isn't a drop-in WAF replacement. You need expertise in Kubernetes, eBPF/XDP, and kernel-level networking. Misconfigure the eBPF datapath and you get routing loops. Misconfigure the RL reward function and the system either mutates too aggressively (breaking everything) or too conservatively (defending nothing).

Stateful apps need refactoring. Chaos is optimized for stateless, horizontally scalable microservices. If your application stores sessions in local memory, hard-codes IP addresses, or runs as a monolith — you're going to have a bad time. Applications need to externalize state to backing services like Redis or managed PostgreSQL before Chaos can shuffle them freely. The Twelve-Factor App methodology isn't optional here; it's a prerequisite.

The RL "cold start" problem is real. Deploying an untrained agent into production is like handing the car keys to someone who's never driven. The whitepaper solution involves a Sim2Real pipeline — pre-training in a digital twin environment and deploying with hardcoded safety bounds — but that's non-trivial engineering work.

What's Next

The prototype proves the concept. The session persistence works. The deception layer works. The eBPF code compiles and is ready for production Linux XDP.

Next steps: integrating a proper PPO agent from stable-baselines3 (the current prototype uses a heuristic placeholder), benchmarking eBPF routing latency against iptables in simulated 6G edge environments, and expanding the entropy engine to handle Kubernetes-native pod scheduling.

The code is open source, MIT-licensed, and on GitHub. Clone it. Break it. Tell me what I got wrong.

https://github.com/Dprof-in-tech/chaos.git

Because the best defense isn't a wall. It's a shape-shifter.

Isaac Onyemaechi is a software engineer building at the intersection of AI, kernel-level networking, and proactive defense. Find the Chaos AMTD prototype on GitHub.