Migrating Debian Buster from iptables to nftables

In the next major release, Debian will be changing firewall providers from iptables to nftables. There’s many more features and a more streamlined config syntax with nftables, so this will be a welcome change. Unfortunately, it means learning a lot of new stuff and leaving the comfort of the existing and well-documented land of iptables.

Here’s what you need to do in order to migrate your Debian machine from iptables to nftables.

Before we begin

For this guide, we’ll assume you’re using Debian Buster (Debian 10).

During this process, we’ll be removing your current firewall rules and putting a new firewall system in place. Be aware that the following undesirable issues may arise:

  • Your machine will be opened up to unwanted traffic during the time when the existing rules are purged and nftables is brought online.
  • If you’re working over SSH on a remote machine, you could block yourself out of access to the machine. Before you begin, ensure you have a way to access the machine via low-level terminal from your hosting provider in case you cannot SSH in.

Migration steps

Step one — Migrate your iptables rules to nftables rules

  • See my example nftables.conf file.
  • Ensure your rules are stored in /etc/nftables.conf. This file will be read when nftables starts.

Step two — Validate the rules you’ve written are error-free

sudo nft -c -f /etc/nftables.conf
  • If there is no output, it means your conf file is error-free.
  • Otherwise, the interpreter will print out each line with errors and point you towards the issues.

Step three — Put your new rules into effect

First, clear any legacy rules that are in place. (WARNING: This will remove all firewall rules in place, possibly leaving your machine open to unwanted traffic.)

sudo iptables -F
sudo nft flush ruleset

Ensure the nftables ruleset is empty by listing the rules:

sudo nft list ruleset

Restart nftables to load your rules:

sudo systemctl restart nftables

List rules to ensure your rules were loaded

sudo nft list ruleset

Compare the printed rules to the rules you added to /etc/nftables.conf.

Step four — Uninstall iptables

Note: Uninstalling iptables strangely removes nftables, probably because of the legacy connection between the two systems. Don’t worry, we’ll put nftables right back. (You might want to copy your rule file /etc/nftables.conf to another location, just in case it’s wiped out during this step.)

Make a backup copy of your nftables rules, just in-case:

cp /etc/nftables.conf ~/nftables.conf.bak

Remove the existing rules:

sudo apt autoremove --purge iptables iptables-persistent

Re-install nftables:

sudo apt install nftables

Put your nftables rules back into place:

sudo cp ~/nftables.conf.bak /etc/nftables.conf

Set nftables to load on every boot

sudo systemctl enable nftables

Blacklist iptables kernel modules to prevent them from loading on boot. Edit /etc/modprobe.d/iptables-blacklist.conf and add the following lines:

blacklist x_tables
blacklist iptable_nat
blacklist iptable_raw
blacklist iptable_mangle
blacklist iptable_filter
blacklist ip_tables
blacklist ipt_MASQUERADE
blacklist ip6table_nat
blacklist ip6table_raw
blacklist ip6table_mangle
blacklist ip6table_filter
blacklist ip6_tables

Set Debian’s defaults to use nftables instead of iptables:

sudo update-alternatives --set iptables /usr/sbin/iptables-nft
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-nft
sudo update-alternatives --set arptables /usr/sbin/arptables-nft
sudo update-alternatives --set ebtables /usr/sbin/ebtables-nft

Reboot the machine, and you’re all set! With any luck, your machine will come back online and you won’t have locked yourself out of SSH.