Projects

Firewall Fleet Orchestrator

A drift-detecting security orchestrator — central policy as the source of truth, SHA256 change detection, and Ansible pushing validated rules across a managed EC2 fleet.

Python · Ansible · AWS EC2 · iptables · SHA256

Production

Personal lab project on AWS EC2. The drift-detection approach developed here later informed the production firewall platform listed under selected work.

The problem

Configuring firewall rules on one server is trivial. Doing it across dozens of nodes, keeping them consistent, making the change survive a reboot, and knowing whether the applied state still matches the intended state — that is where it stops being a shell command and becomes a system.

The specific failure this addresses: you cannot tell whether a fleet is in the state you think it’s in. Someone changes a rule by hand during an incident, nobody records it, and from then on your intent and your reality have quietly diverged.

SOURCE OF TRUTH blacklist.json central policy, version controlled DRIFT DETECTION Python engine SHA256 of policy vs last applied hash changed? unchanged → no deployment ORCHESTRATION Ansible playbook push → validate → apply, fleet-wide MANAGED FLEET EC2 node · iptables EC2 node · iptables EC2 node · iptables iptables-services survives reboot FEEDBACK SMTP notifier — HTML fleet report
Policy as data, hashed to detect change, orchestrated by Ansible, persisted across reboot, and reported back on success.

How it works

Policy as data. Rules live in a central JSON blacklist, version controlled. Nothing is configured by logging into a node.

Drift detection via hashing. A Python engine computes a SHA256 digest of the current policy and compares it against the last successfully applied digest. If they match, nothing happens — no deployment, no churn, no risk. If they differ, a deployment is triggered.

That comparison is the whole point. It converts “run the playbook periodically and hope” into “act only when intent has actually changed,” and it means a deployment is always attributable to a specific policy change.

Orchestrated application. Once drift is detected, an Ansible playbook pushes the rendered rules to every managed node, validates them before committing, and applies them across the fleet in one operation.

Persistence. iptables-services ensures each node retains its rules through a reboot. A firewall that evaporates on restart is worse than none, because it reports healthy while doing nothing.

Feedback. A Python SMTP notifier sends a formatted HTML report when a fleet-wide update completes, so a change produces a record rather than silence.

The pipeline running

Orchestrator log output showing policy loaded from JSON, changes detected, rules deployed, syntax validation passed, and an alert email dispatched.
The full cycle in one run — policy loaded, drift detected, rules deployed, syntax validated before commit, and the notification dispatched. Nothing happens when the hash is unchanged.
Ansible playbook run showing tasks to install iptables-services, enable iptables, push the rules file, apply rules and save for persistence, with a play recap of ok=6 changed=5 across two nodes.
Ansible applying the change fleet-wide. Note the ordering: install, enable, push, apply, then save for persistence — a ruleset that vanishes on reboot is worse than none, because it reports healthy while doing nothing.
iptables -L -n -v output on a managed node showing INPUT policy DROP, loopback and established traffic accepted, SSH permitted, and blacklisted source addresses dropped.
Resulting state on a managed node — INPUT policy DROP, loopback and established traffic allowed, SSH permitted, blacklisted sources dropped. Default-deny with an explicit allowlist.

What I would change

Verify the result, not just the input. The hash proves the policy changed. It does not prove the applied state on each node matches it. The honest next step is reading rules back from each host after apply and comparing against what was rendered — closing the loop from “deployment succeeded” to “state confirmed.”

Detect out-of-band changes. The system detects changes to the policy file. It does not detect someone editing rules directly on a node. Runtime comparison against the rendered artifact would catch that, and it is the higher-value form of drift detection.

Email is a weak feedback channel. A report nobody opens is not monitoring. Metrics exported for alerting would be the better mechanism.

Where it led

This was the prototype for a problem I later solved at production scale — a database-backed policy compiler with role-tiered access, time-boxed exceptions and multi-layer deployment safety, described under selected work. The drift-detection idea started here.