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 ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

2. Set the default-deny policy

iptables -P INPUT DROP && iptables -P FORWARD DROP

3. Equivalent firewalld zone policy

firewall-cmd --permanent --add-service=https && firewall-cmd --reload
success
public (active)
  services: ssh http https

4. Persist iptables rules across reboot

iptables-save > /etc/iptables/rules.v4

Validation & 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.15
Advanced: 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-persistent or 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.