2 min read

Uncomplicated Firewall (`ufw`), `iptables` and `nftable`

Firewall

  • control network communication
    • port
      • specific
      • range
    • direction
      • entry
      • exit
    • program
      • individual
      • criteria

UFW

  • uncomplicated firewall
    • front for IP Table
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status
sudo journalctl -u ufw --since "5 minutes ago"

See issue 1 in debugging if actual network behaviour deviates from your ufw settings.

IP Table

  • classic low‑level firewall framework built into the Linux kernel
  • complicated to edit directly
    • hence ufw was born
    • being phased out since early 2020s
    • now practically a compatibility layer of nftables
sudo iptables -L -n

# Enable journaling to facilitate debugging
iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: " --log-level 4

You are STRONGLY recommended to NOT* directly edit IP Tables, as it is COMPLICATED.
The only good news is if you messed things up already, a reboot would set things back to last saved state since IP tables are loaded in RAM.
You can revert back to the version in the persistent storage without rebooting :

sudo iptables-restore < /etc/iptables/rules.v4

IP tables would only be written to persistent storage with explicit commands.
It goes without saying that be EXTREMELY careful with those commands. Before you edit, create backups :

sudo cp /etc/iptables/rules.v4 /etc/iptables/rules.v4.bak
sudo cp /etc/iptables/rules.v6 /etc/iptables/rules.v6.bak
sudo iptables-save | sudo tee /etc/iptables/rules.v4 > /dev/null
sudo iptables-save | sudo tee /etc/iptables/rules.v6 > /dev/null

*: The only exception is when your OS shipped with meddling custom iptable rules, courtesy of your Linux distro or cloud provider.

nftables

  • What Linux kernels actually enforce now on a base-level
sudo nft list ruleset
sudo nft list chain ip filter INPUT

Concerning edition, just two words : don't touch.
Just like you shouldn't be writing your kernel on the fly, you shouldn't be touching something so essential to the kernel's normal function every second. Use ufw instead.

Priority and Rule Ordering

  • Firewalls evaluate rules in order of priority within a chain.
  • The default policy (e.g. DROP) applies if no rule matches.
  • An absolute REJECT or DROP rule placed before an ALLOW rule will block traffic even if you later add an allow.
  • UFW rules are inserted into nftables chains, but they may be evaluated after system‑provided rules, which come with your operating system, like Oracle’s default InstanceServices chain on its computing instances. See issue 1 if the firewall behaviour deviates from what is expected from ufw status.

Debugging

  1. "I put in ufw allow 80/TCP, why is my HTTP traffic still blocked ?"

As explained, ufw is just one high-level interface for nftables. There are many ways to create firewall rules. You may have a higher priority REJECT rule that blocked the traffic on port 80 before it reached the ALLOW rule of ufw. Run:

sudo nft list chain ip filter INPUT

to see how the rules were actually enforced against historical traffic at the kernel level.

You will likely find a culprit REJECT everything similar to :

 REJECT --reject-with icmp-host-prohibited

which has higher priority than ufw managed rule sets. If you are using xyz cloud service, this is likely injected by the cloud provider so idiots don't get their system compromised. Annoyingly they don't always tell you to remove it.

Remove it and write ip table to persistent storage :

sudo iptables -D INPUT -j REJECT --reject-with icmp-host-prohibited
sudo iptables-save | sudo tee /etc/iptables/rules.v4 > /dev/null
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6 > /dev/null