🛡 Project 03 — Firewall Configuration Lab¶
Type: Defense lab (Linux VM) Modules: 05 (Firewalls & Access Control) Difficulty: ⭐⭐⭐
🎯 Objective¶
Build a realistic iptables security policy on a Linux gateway from a default-deny baseline: allow only the traffic a small office actually needs, forward external requests to an internal web server, and rate-limit a common brute-force vector.
🛠 Setup¶
A single Linux VM acting as the gateway, with (conceptually or physically) three zones:
| Zone | Represents | Interface (example) |
|---|---|---|
| LAN | Internal office network, includes a management subnet | eth0 |
| DMZ | An internal web server reachable from outside | eth1 (or a second VM if you have one available) |
| WAN | The internet-facing interface | eth2 |
If you only have one spare VM, you can simulate the DMZ web server on the gateway itself (e.g. python3 -m http.server 80) and test from a second "outside" VM or your host machine.
🧩 Tasks¶
🔹 Part A — Default-Deny Baseline¶
- Set default-deny policies:
- Allow loopback and established/related return traffic first (order matters):
- Allow SSH only from the management subnet:
- Allow HTTP/HTTPS to the DMZ web server through the FORWARD chain:
🔹 Part B — NAT and Rate Limiting¶
- Add a DNAT rule so external traffic hitting the gateway's WAN IP on port 80 is forwarded to the internal web server:
- Add a matching FORWARD rule to allow the translated traffic, and a masquerade rule for return traffic if needed.
- Add a basic SSH rate-limit to mitigate brute-force attempts:
🔹 Part C — Verify¶
- Review the full ruleset:
sudo iptables -L -v -nandsudo iptables -t nat -L -v -n. - From the management subnet, confirm
sshsucceeds; from outside it, confirmsshis blocked. - From an outside VM,
curl http://<gateway_wan_ip>/and confirm it reaches the DMZ web server. - Run
nmapfrom an outside VM against the gateway and confirm only the intended ports respond. - Trigger the SSH rate limit with repeated rapid connection attempts and confirm the 5th+ attempt within the window is dropped.
✅ Verification Checklist¶
- INPUT and FORWARD default policies are DROP; only explicitly allowed traffic passes.
- SSH succeeds from the management subnet and is blocked from everywhere else.
- External HTTP/HTTPS requests reach the DMZ web server via DNAT.
-
nmapfrom outside shows only the intended ports open. - Repeated rapid SSH attempts get rate-limited/dropped.
📦 Deliverables¶
- Final ruleset from
iptables-save. - A short explanation of each rule (what it matches, why it's ordered where it is).
nmapoutput from before and after applying the policy.
🚀 Stretch Goals¶
- Convert the entire ruleset to
nftablessyntax and verify equivalent behavior. - Add logging for dropped packets (
-j LOG --log-prefix "DROPPED: ") and reviewjournalctl/dmesgfor blocked attempts. - Add an explicit anti-spoofing rule dropping packets on the WAN interface that claim a source address from the LAN/DMZ ranges.
See also notes: [[05-05-iptables-fundamentals]], [[05-06-writing-iptables-rules]], [[05-07-acls-dmz-and-segmentation]], [[05-08-firewall-limitations-and-evasion]]