How to check the active iptables backend

Backend mismatches make firewall checks look empty or contradictory when one command reads the legacy iptables API and another reads nftables compatibility rules. The version suffix on the iptables command shows which backend automation or an administrator is about to inspect.

iptables can be delivered as the legacy command or as the xtables-nft compatibility command, which accepts iptables syntax while storing rules through the nf_tables kernel API. The active command reports either (legacy) or (nf_tables), and Debian or Ubuntu hosts usually expose the selected implementation through update-alternatives.

Version, alternatives, and inventory commands read state only. They do not switch alternatives, flush rules, or install a new firewall stack, so use the matching iptables-save, iptables-legacy-save, iptables-nft-save, or nft command only after the active backend is known.

Steps to check the active iptables backend:

  1. Print the active IPv4 iptables backend.
    $ iptables --version
    iptables v1.8.11 (nf_tables)

    (nf_tables) means the command uses the nftables compatibility backend. (legacy) means the command uses the older legacy kernel API.

  2. Check the IPv6 command separately when the host has IPv6 firewall rules.
    $ ip6tables --version
    ip6tables v1.8.11 (nf_tables)

    iptables and ip6tables usually follow the same backend on Debian and Ubuntu hosts, but checking both avoids reading IPv4 and IPv6 rules through different command families.

  3. Inspect the selected alternative on Debian or Ubuntu hosts.
    $ update-alternatives --display iptables
    iptables - auto mode
      link best version is /usr/sbin/iptables-nft
      link currently points to /usr/sbin/iptables-nft
      link iptables is /usr/sbin/iptables
      slave iptables-restore is /usr/sbin/iptables-restore
      slave iptables-save is /usr/sbin/iptables-save
    /usr/sbin/iptables-legacy - priority 10
      slave iptables-restore: /usr/sbin/iptables-legacy-restore
      slave iptables-save: /usr/sbin/iptables-legacy-save
    /usr/sbin/iptables-nft - priority 20
      slave iptables-restore: /usr/sbin/iptables-nft-restore
      slave iptables-save: /usr/sbin/iptables-nft-save

    If the command is managed by alternatives, the line that says currently points to should match the backend shown by iptables --version.

  4. Read the active filter table through the current iptables command.
    $ sudo iptables -S
    -P INPUT ACCEPT
    -P FORWARD ACCEPT
    -P OUTPUT ACCEPT

    This reads the backend selected by the plain iptables command. Use sudo iptables-legacy -S or sudo iptables-nft -S only when deliberately checking a backend that is not currently selected.

  5. Dump restore-format rules from the active backend when a full ruleset inventory is needed.
    $ sudo iptables-save
    # Generated by iptables-save v1.8.11 (nf_tables) on Fri Jun  5 21:45:09 2026
    *filter
    :INPUT ACCEPT [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [0:0]
    -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
    COMMIT
    # Completed on Fri Jun  5 21:45:09 2026

    A host with no rules in the selected backend may return no output from iptables-save. In that case, iptables -S still confirms the selected filter table policies.

  6. Compare the native nftables view only when the version suffix says (nf_tables).
    $ sudo nft list ruleset
    table ip filter {
    	chain INPUT {
    		type filter hook input priority filter; policy accept;
    		tcp dport 22 counter packets 0 bytes 0 accept
    	}
    }

    When iptables reports (nf_tables), matching rules can appear through both iptables-save and nft list ruleset. When iptables reports (legacy), native nft output may be empty even though legacy iptables rules exist.