Linux Firewall Management

A Linux firewall serves as the first line of defense for system security. At the kernel level, most packet filtering is built on the Netfilter framework. User-space utilities then translate administrative intent into kernel rules. Common front-ends include firewalld, ufw, iptables, and nftables. Knowing how these tools relate to one another—and when to use each—is essential for dependable firewall management.

Modern distributions tend to standardize on specific defaults:

  • firewalld: Default on RHEL, CentOS, and Fedora. It uses zones and supports dynamic rule changes without disrupting active connections.
  • ufw: Common on Ubuntu and Debian. Designed for simplicity, it is ideal for quick host-based firewall setup.
  • nftables: The next-generation rule engine intended to replace iptables. It offers a more consistent syntax and better performance.
  • iptables: The traditional tool still found on older systems and many container environments.

Regardless of the utility chosen, the underlying security model follows the same core principles: deny inbound traffic by default, permit only what is explicitly required, allow established and related connections to continue, and tightly restrict administrative ports such as SSH.

Managing firewalld

firewalld organizes traffic through zones, each representing a level of trust. Frequently used zones include public, trusted, and drop. A zone assigned to a network interface determines which services and ports are reachable from that network.

To start and inspect the service:

sudo systemctl enable --now firewalld
sudo firewall-cmd --state
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --list-all

Opening common web and SSH ports looks like this:

sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

The --permanent flag writes the rule to the persistent configuration. It does not take effect immediately until --reload is executed. Rules added without --permanent are active only in the current runtime and disappear after a reboot or service restart.

Managing ufw

ufw (Uncomplicated Firewall) is the straightforward choice for Ubuntu and Debian administrators. Before enabling it, define the default posture and then open only necessary services:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw limit 22/tcp
sudo ufw enable
sudo ufw status verbose

The limit rule on port 22 helps mitigate brute-force SSH attempts by throttling repeated connections from the same source. To remove a rule by position:

sudo ufw status numbered
sudo ufw delete 2

Managing iptables

iptables structures rules into tables and chains. The filter table is the most common, containing the INPUT, OUTPUT, and FORWARD chains. To inspect existing rules:

sudo iptables -L -n -v --line-numbers
sudo iptables -S

A baseline inbound policy might be configured as follows:

sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT

When working remotely, always permit SSH before setting the default chain policy to DROP. Otherwise, the administrative session may be severed and recovery could require out-of-band access. To make rules survive reboots on Debian-based systems:

sudo apt install iptables-persistent
sudo netfilter-persistent save

Managing nftables

nftables provides a modern replacement for iptables with a unified syntax for IPv4, IPv6, and bridging. Creating a basic filtering table and input chain:

sudo nft add table inet filter
sudo nft add chain inet filter input { type filter hook input priority 0\; policy drop\; }
sudo nft add rule inet filter input iif lo accept
sudo nft add rule inet filter input ct state established,related accept
sudo nft add rule inet filter input tcp dport 22 accept
sudo nft add rule inet filter input tcp dport { 80, 443 } accept

To review the active ruleset:

sudo nft list ruleset

Persistent configuration is typically stored in /etc/nftables.conf. Enable and start the service with:

sudo systemctl enable --now nftables

Typical Scenario: Securing a Web Server

Consider a host that must expose SSH, HTTP, and HTTPS while blocking all other inbound traffic. The implementation follows these steps:

  1. Accept traffic on the loopback interface and packets belonging to established or related connections.
  2. Allow inbound TCP on ports 22, 80, and 443.
  3. Set the default policy for the INPUT chain to DROP.
  4. Save the configuration and reload the firewall.
  5. Verify listening ports with ss -tulnp and test connectivity from an external host.

This approach minimizes the attack surface while preserving essential administrative and public-facing access.

Best Practices and Troubleshooting

  • Back up the current rule set before making changes. Examples include iptables-save > rules.bak or nft list ruleset > nft.bak.
  • When administering a remote server, keep an existing SSH session open until the new rules are confirmed working.
  • Use logs to diagnose dropped packets. Relevant sources include journalctl -u firewalld, dmesg | grep -i nf, and /var/log/ufw.log.
  • Periodically audit open ports and disable services that are no longer needed.
  • Avoid disabling the firewall for extended periods. If an application cannot communicate, refine the specific rule rather than turning off host-based filtering entirely.

Mastering one of these tools—firewalld, ufw, iptables, or nftables—along with a solid understanding of the Netfilter packet-filtering model, enables secure and maintainable firewall administration on the majority of Linux servers.