Loading the wrong ruleset with iptables-restore can flush your existing firewall in one go. This builds a repeatable way to validate a file before you commit it, using iptables 1.8.10 on the nf_tables backend. Allow about 20 minutes, plus time to prepare a ruleset that matches your host.
You need a shell, the iptables package, a ruleset file, and an administrator account. Reading files and checking the installed version are ordinary commands; testing and restoring firewall rules need elevated privileges here. A mistake can interrupt SSH, web traffic or other services, so keep an existing console or out-of-band login available before you commit a change.
Confirm which implementation and version will process the file. This avoids applying advice for a different binary or backend:
$ iptables-restore --version
iptables-restore v1.8.10 (nf_tables)
$ command -v iptables-restore
/usr/sbin/iptables-restore
$ command -v ip6tables-restore
/usr/sbin/ip6tables-restore
The installed manpage documents the two commands as aliases for the IPv4 and IPv6 forms of the same operation. Both accept rules on standard input or from a file argument. The package version is distribution-specific, so keep this check in your incident runbook.
A restore file normally contains table sections, chain policies and rules. A small filter-table example looks like this:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
COMMIT
The table header selects the table, the colon lines define built-in chains and their policies, and COMMIT ends the transaction for that table. In a real file, keep the rules produced by your firewall design or a trusted backup. Do not paste an example with an ACCEPT policy into a production host unless that is deliberately what you want.
Check the file as the same account that will run the restore:
$ sed -n '1,160p' /path/to/firewall.rules
$ test -r /path/to/firewall.rules && echo "ruleset is readable"
ruleset is readable
Checkpoint: identify whether the file contains IPv4 or IPv6 addresses, and whether it holds more than one table. Use iptables-restore for IPv4 syntax and ip6tables-restore for IPv6. Do not assume an IPv4 ruleset can be passed unchanged to the IPv6 command.
Use --test before committing rules. It parses and constructs the ruleset without committing it, which is a safety check, not full proof the policy is correct:
$ sudo iptables-restore --test /path/to/firewall.rules
$ printf 'test exit status: %s\n' "$?"
test exit status: 0
Use the IPv6 command for an IPv6 file:
$ sudo ip6tables-restore --test /path/to/firewall-v6.rules
$ printf 'IPv6 test exit status: %s\n' "$?"
IPv6 test exit status: 0
On this installation, an unprivileged test reached the ruleset check and then failed with a root-required permission error, which is why the examples use sudo. A non-zero status means the file was not accepted by the command as run: read the diagnostic before editing the rules blindly, and test the exact file, command and table combination you plan to commit.
Without an option, restore flushes the previous contents of each table represented by the input, deleting the existing rules there before loading the supplied state. That is often right for replacing a complete saved ruleset, but dangerous for a partial file.
Use --noflush when you deliberately want to keep existing table contents and add or update what the input describes:
$ sudo iptables-restore --test --noflush /path/to/firewall.rules
$ printf 'non-flushing test exit status: %s\n' "$?"
non-flushing test exit status: 0
This does not make a partial ruleset safe by itself. A duplicate rule, an unexpected chain policy or a rule that depends on an existing chain can still produce a broken firewall. Decide explicitly between a complete replacement and a deliberate merge, and record that decision in the change notes.
Warn anyone using the host, then run the same command without --test. This is the state-changing step:
$ sudo iptables-restore /path/to/firewall.rules
$ printf 'restore exit status: %s\n' "$?"
restore exit status: 0
A zero status only says the restore command completed successfully. It does not say SSH remains reachable, that a service is reachable from the intended network, or that the rules express your security policy: verify those separately, from a permitted console and an appropriate test client.
Warning: there is no generic undo flag. Recovery means restoring a known-good backup, for example:
$ sudo iptables-restore /path/to/known-good-firewall.rules
$ sudo ip6tables-restore /path/to/known-good-firewall-v6.rules
Do not run the recovery files unless you have checked they match this host. If the new rules block your only remote session, use the out-of-band console or the provider's rescue path.
--wait. Handles concurrent xtables users. Without it, the command exits if it cannot get the exclusive xtables lock immediately; give it a bounded number of seconds when you want a restore to wait rather than fail at once. It does not fix a broken or permanently held lock; if it times out, look at other firewall automation and avoid launching several restore jobs at once.--table NAME. Restores only the named table even if the input contains others. That filter is easy to misread: it does not validate the ignored tables, so if you later restore the whole file, those other sections still need their own test.--counters. Restores packet and byte counter values from the input, useful for a stateful backup but usually unwanted for a fresh policy deployment.--verbose. Prints additional processing detail, and can be repeated for more debug output.--modprobe PATH. Selects the modprobe executable when module loading needs a non-default path.$ sudo iptables-restore --wait 10 /path/to/firewall.rules
$ sudo iptables-restore --test --table filter /path/to/firewall.rules
Use the matching save command to inspect the active ruleset after a successful restore, if it is available on the host:
$ sudo iptables-save | sed -n '1,160p'
$ sudo ip6tables-save | sed -n '1,160p'
Compare the output with the intended backup, then test the services that matter. A restore changes kernel firewall state immediately; it does not automatically create a persistent file or configure boot-time loading. Persistence is a separate distribution or service-management task, and needs testing on its own.
--test run.--noflush.--wait when concurrent firewall automation made locking relevant.