Home / Alt manpages / ipset-translate(8)

  • ipset-translate(8)
  • Admin command
  • linux

Translate an ipset save file into nftables commands safely

You will turn an ipset save file into nftables commands, inspect the assumed table and set types, and check the result before applying it. The translation step is intended to write text, not change the active ruleset. Allow 10 to 20 minutes for a small configuration, plus time to review any rules that used the old ipset.

The examples use the installed ipset package version 7.19 on this machine. The manual page is dated 31 May 2021, so check the output from your own installed build before putting a translated ruleset into service.

1. Confirm the tools and keep a rollback copy

Start in an ordinary shell and confirm that the command is the ipset binary supplied by the package. Saving the current sets is read-only, but reading the kernel's ipset state normally needs elevated privileges.

$ command -v ipset-translate
/usr/sbin/ipset-translate
$ dpkg-query -W -f='${Package} ${Version}\n' ipset
ipset 7.19-1ubuntu2
$ sudo ipset save > /path/to/ipsets-before-migration.ipt

Keep that file unchanged. It is your recovery copy for the ipsets themselves. This guide does not remove sets, flush rules, or alter a service. Do not replace the file with a hand-edited version until you have preserved the original.

Checkpoint: you should have a readable file containing lines such as create and add. If sudo ipset save fails, stop and fix access to the source state first.

2. Translate the saved text to standard output

Pass the save file to the only documented subcommand, restore. The input redirection is important: the utility reads an ipset save format from standard input and prints nftables commands to standard output.

$ sudo ipset-translate restore < /path/to/ipsets-before-migration.ipt > /path/to/ipsets.nft
$ test -s /path/to/ipsets.nft && echo 'translation written'
translation written

On this host, an unprivileged invocation can print Kernel error received: Operation not permitted and return status 1 even though the operation is a text conversion. Running the same command through sudo lets the installed 7.19 binary complete its translation. Do not interpret the need for sudo here as permission to apply the result: this command still only writes the redirected output file.

Read the generated file before doing anything else:

$ sed -n '1,20p' /path/to/ipsets.nft
add table inet global
add set inet global example { type ipv4_addr; size 65536; }
add element inet global example { 192.0.2.10 }

The exact lines depend on your input. The converter uses a table called global in the inet family because ipsets are not attached to a specific nftables table. That is a default for the translation, not proof that global is the right destination in your ruleset.

3. Check the table, types and elements

Look for every add table, add set and add element line. A set with multiple ipset fields becomes an nftables concatenation. For example, an ipset containing an address, protocol and port can become a type like ipv4_addr . inet_proto . inet_service. Confirm that the address family and field order match the rules that will use the set.

$ rg '^(add table|add set|add element)' /path/to/ipsets.nft
add table inet global
add set inet global web_sources { type ipv4_addr; size 65536; }
add element inet global web_sources { 192.0.2.10 }
$ rg -n 'nomatch|comment|counters|timeout|hashsize|maxelem' /path/to/ipsets-before-migration.ipt
12:create web_sources hash:ip family inet counters timeout 300 maxelem 65536

Some ipset options have no direct nftables equivalent or are not implemented by the translator. Timeouts, counters and size-related details need a deliberate review, especially if the set is used for rate limiting or temporary blocking. A translated file that parses successfully is not automatically behaviourally equivalent.

The translator cannot migrate the iptables rules that refer to an ipset with -m set. Find those references separately and design the corresponding nftables rules. Also check for nomatch elements: nftables sets do not provide the same negated-element behaviour, so the upstream migration guidance uses separate positive and negative sets with an explicit rule comparison.

4. Validate the file without loading it

Use nftables' check mode against the generated text. This parses the commands without committing them to the kernel.

$ sudo nft -c -f /path/to/ipsets.nft
$ printf 'nft check status: %s\n' "$?"
nft check status: 0

A non-zero status means the output needs correction or the installed nftables version does not accept part of the translation. Read the reported line number, then compare it with the original input. Do not pipe an unreviewed translation directly to nft -f.

If you need a different table, edit a working copy of the generated file and change its table declaration and every set or element reference consistently. The manual's example uses global; your deployed policy may require an existing table such as filter. Validate the edited copy again. Do not delete the original translation while you are still comparing it.

5. Apply only after the review

Applying the file changes the live nftables ruleset, so treat this as a service-disrupting step. Take a current backup of the existing nftables state and use a maintenance window appropriate to the machine.

$ sudo nft list ruleset > /path/to/nftables-before-migration.nft
$ sudo nft -f /path/to/ipsets.nft

Check the loaded result immediately:

$ sudo nft list table inet global
$ sudo nft list ruleset | rg -n 'web_sources|192\.0\.2\.10'

If the application rules have not been migrated, loading only the sets does not make the old iptables matches work. If the result is wrong, restore the nftables backup with sudo nft -f /path/to/nftables-before-migration.nft if that file is a complete, valid ruleset for your host. Keep the ipset save file until the old firewall path has been retired and tested.

Done means

  • The installed ipset-translate version and its input file are known.
  • The original ipset save output is preserved.
  • The translated commands were reviewed for table name, family, concatenated types and unsupported features.
  • sudo nft -c -f returned status 0 before any live change.
  • References from old iptables rules were migrated separately.
  • A current nftables backup and a tested recovery path exist before application.