Order an ACL so the first match is the right one
Task
Build an access control list on the router and prove the two properties the exam tests: rules are matched top to bottom and the first match wins, and anything not explicitly permitted hits an implicit deny at the end. You will make the classic ordering mistake on purpose so you can see it, then fix it.
Steps
- Set the default. Make the FORWARD chain deny by default so that only what you permit will pass:
sudo iptables -P FORWARD DROP. This is the implicit deny made explicit, and it is the safe base every ACL should start from. - Add the specific rule you actually want: allow Host A to reach Host B only on SSH.
sudo iptables -A FORWARD -s 192.168.10.10 -d 192.168.20.10 -p tcp --dport 22 -j ACCEPT. Test it: SSH from A to B works, and a ping does not, because you permitted one port and nothing else. - Now make the ordering mistake. Insert a broad allow above the specific one:
sudo iptables -I FORWARD 1 -s 192.168.10.0/24 -j ACCEPT. Re-test — now ping works too, because the broad rule matched first and the traffic never reached the specific rule. The narrow rule has become dead code. - Read the match counters to see it.
sudo iptables -L FORWARD -n -v --line-numbersshows packet counts per rule; the broad rule at line 1 is counting and the specific rule below it is stuck at zero — that zero is how you spot a shadowed rule. - Fix the order: delete the broad rule (
sudo iptables -D FORWARD 1) and confirm ping fails again while SSH still works. Specific before general.
Verify
sudo iptables -L FORWARD -n -v --line-numbers
nc -z -w 3 192.168.20.10 22; echo "A to B ssh exit $?"
ping -c 1 -W 2 192.168.20.10; echo "A to B ping exit $?"
With the ACL correct, the SSH test must succeed (exit 0) and the ping must fail (non-zero) — the same host permitted on one port and denied on another. The per-rule counters in the first command are the real deliverable: a rule sitting at zero packets while traffic clearly flows is a rule something above it is shadowing.
Notes
Two more traps the objective builds questions around. The return path: on a stateless ACL, permitting A-to-B does not permit B-to-A, and a connection that completes its handshake and then hangs is usually a missing return rule — which is why real firewalls are stateful and match the reply automatically. And the implicit deny itself: a packet that matches no rule is dropped, so an ACL that forgets a legitimate flow produces a timeout with no log entry unless you add an explicit logging deny at the end.
The habit worth forming: write the deny-by-default first, add the narrowest permits that make the application work, and read the counters to confirm traffic is hitting the rule you intended rather than one higher up you had forgotten.