Host Firewall Configuration with iptables, firewalld, and ufw
I implemented a default-deny host firewall across three management tools – iptables, firewalld, and ufw – establishing a consistent ingress policy on RHEL and Ubuntu nodes. The hardened ruleset reduced the externally reachable attack surface to three required ports and survives reboots through persisted rules.
Objective & Context
A host firewall is the last enforcement point before a service. This lab maps the same default-deny intent onto iptables (low-level chains), firewalld (zone abstraction), and ufw (simplified front end), so the right tool fits the right distribution. The work aligns to CIS Controls 4 and 9 and NIST SP 800-53 SC-7 (Boundary Protection).
- T1190 Exploit Public-Facing Application – default-deny shrinks the reachable service set adversaries can target.
- T1046 Network Service Discovery – dropped probes deny attackers an accurate service map.
Environment & Prerequisites
- RHEL 9 (firewalld 1.2) and Ubuntu 22.04 (ufw 0.36) test VMs.
- iptables 1.8 with the nftables backend; root or sudo access.
- Out-of-band console access in case a rule severs SSH.
Methodology
Why default-deny first
An allow-list policy is only sound if the default action is DROP. I establish the management allow rule (SSH) before flipping the default policy, preventing a self-inflicted lockout – the single most common firewall incident.
Choosing the tool
firewalld zones suit multi-interface servers; ufw suits single-purpose Ubuntu hosts; raw iptables/nftables suits scripted, auditable rule sets. All three compile to the same kernel netfilter hooks.
Step-by-Step Execution
1. Permit management access before locking down [ROOT REQUIRED]
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPTiptables -A INPUT -p tcp --dport 22 -j ACCEPT2. Set the default-deny policy
iptables -P INPUT DROP && iptables -P FORWARD DROP3. Equivalent firewalld zone policy
firewall-cmd --permanent --add-service=https && firewall-cmd --reloadsuccess
public (active)
services: ssh http https
4. Persist iptables rules across reboot
iptables-save > /etc/iptables/rules.v4Validation & Testing
From a second host, run nmap -p- target and confirm only 22/80/443 report open while all other ports show filtered. Pass criteria: established connections persist, a new connection to a closed port is dropped (not rejected), and rules reload identically after reboot.
nmap -p1-1000 --reason 192.168.20.15Advanced: Troubleshooting
- Locked out of SSH: the allow rule must precede the DROP policy; recover via console and reorder.
- firewalld and iptables conflict: run one manager only; firewalld owns the chains when active.
- Rules vanish on reboot: install
iptables-persistentor enable the firewalld service.
Key Results
- Reduced externally reachable ports from an open default to exactly 3 required services.
- Achieved a 100% default-deny INPUT policy with stateful connection tracking.
- Validated 0 unexpected open ports across a full 65,535-port Nmap sweep.
- Persisted rules surviving 5/5 reboot cycles with byte-identical rulesets.