Home / Alt manpages / iptables-apply(8)

  • iptables-apply(8)
  • Admin command
  • linux

Apply Remote iptables Changes Safely with iptables-apply

A bad firewall rule pushed over SSH can lock you out of a box you can only reach over SSH, and iptables-apply exists precisely to stop that happening. It loads a new ruleset, gives you a short window to prove a new connection still works, and puts the old rules back if confirmation never arrives. The examples match iptables 1.8.10-3ubuntu2, whose command reports version 1.1 for this helper.

Allow 15 to 30 minutes for a prepared rules file, including a deliberate rollback test.

1. Check the installed helper

Run these checks as your normal account. They do not load a ruleset or change the firewall:

$ command -v iptables-apply
/usr/sbin/iptables-apply
$ iptables-apply --version
iptables-apply 1.1 -- a safer way to update iptables remotely
$ dpkg-query -W -f='${Package} ${Version}\n' iptables
iptables 1.8.10-3ubuntu2

The installed backend here is iptables v1.8.10 (nf_tables). That tells you the local command family, not that another host uses the same backend or package release, so check the target host itself before applying rules there.

Checkpoint

Confirm the command exists on the machine you will administer, and that you have a second session or an out-of-band console. A single SSH session is a poor recovery plan if the new rules end up blocking SSH.

2. Prepare and inspect a rules file

iptables-apply accepts a rules file in the format produced by iptables-save and feeds it through iptables-restore. It is not a list of shell commands. Prepare it with your normal firewall tooling, then inspect it before reaching for elevated privileges:

$ RULES_FILE=/path/to/approved-iptables.rules
$ test -r "$RULES_FILE" && sed -n '1,80p' "$RULES_FILE"
$ command -v iptables-save
/usr/sbin/iptables-save
$ command -v iptables-restore
/usr/sbin/iptables-restore

Replace the placeholder with an actual path, and never paste an unreviewed rules file into a remote shell. A full restore can replace the active filter, NAT, mangle and related tables in one go, so this is a service-disrupting security change. Keep the previous rules available, and decide upfront how SSH, DNS, monitoring and your administration path will stay reachable.

The default file, if you omit the argument, is /etc/network/iptables.up.rules. An explicit path makes review and rollback easier to follow later.

3. Apply the file and wait for the prompt

Run the change with sudo, because saving the existing rules and restoring the new ones normally needs root:

$ sudo iptables-apply "$RULES_FILE"
Applying new iptables rules from '/path/to/approved-iptables.rules'... done.
Can you establish NEW connections to the machine? (y/N)
  • It saves first. The helper saves the current rules to a temporary file before restoring the proposed one.
  • The default timeout is 10 seconds. Type y or Y only after testing from a separate connection.
  • Anything else means rollback. Another key, an empty Enter, or letting the timer expire all take the safe path and restore the old rules.

Checkpoint

Use the second session to open a genuinely new connection, not to continue an existing one. For SSH, connect from a separate terminal and run something harmless like id. A still-open session can hide a rule that would otherwise block future access.

4. Give yourself more time when testing

A slow console or a multi-step test may need a longer confirmation window. Set it explicitly, in seconds:

$ sudo iptables-apply --timeout 30 "$RULES_FILE"
Applying new iptables rules from '/path/to/approved-iptables.rules'... done.
Can you establish NEW connections to the machine? (y/N)

The timer is not a grace period after you confirm. It is the window the helper waits in for an affirmative answer. Pick a value long enough to actually test, but keep it finite: if your connection breaks, the process needs to regain control and revert.

Do not treat a successful exit as proof the policy is correct. After typing y, check the real service paths and inspect the active rules:

$ sudo iptables-save | sed -n '1,80p'
$ ssh -o ConnectTimeout=5 [email protected] true
uid=1000(user) gid=1000(user) groups=1000(user)

The exact saved rules and command output depend on the host. What matters is that the intended new connection succeeds and the active rules match the reviewed file.

5. Test the rollback path safely

Before relying on this helper for a production firewall, use a maintenance window and a rules file whose effect you understand. Start with a short timeout, then deliberately do not answer the prompt:

$ sudo iptables-apply --timeout 10 "$RULES_FILE"
Applying new iptables rules from '/path/to/approved-iptables.rules'... done.
Can you establish NEW connections to the machine? (y/N)
Timeout! Something happened (or did not). Better play it safe...
Reverting to old iptables rules... done.

The exact final messages vary depending on whether the timeout or a non-affirmative key caused the rollback. Verify the result from a trusted console with sudo iptables-save. This test does briefly change the live firewall, so do not run it during an outage or against a rules file you cannot restore.

If the new rules are already blocking the session, wait for the timeout rather than killing the helper. If the helper itself fails while applying the file, its documented recovery path also restores the saved rules, but check the active rules and use your out-of-band access anyway.

6. Keep a confirmed last-good file

Use --write to save the rules only after you answer yes. That gives you a known-good rules file for a later rollback or review:

$ GOOD_RULES=/var/lib/firewall/iptables.last-good.rules
$ sudo install -d -m 0750 "$(dirname "$GOOD_RULES")"
$ sudo iptables-apply --timeout 30 --write "$GOOD_RULES" "$RULES_FILE"
Applying new iptables rules from '/path/to/approved-iptables.rules'... done.
Can you establish NEW connections to the machine? (y/N) y
Writing successfully applied rules to '/var/lib/firewall/iptables.last-good.rules'...
... then my job is done. See you next time.

Protect the save file: it describes your firewall and can be used to change it. Confirm it was actually written, not just that the prompt said yes:

$ sudo test -s "$GOOD_RULES" && echo 'last-good rules saved'
last-good rules saved

If you later need to restore that file, apply it through the same confirmation process rather than feeding it straight to iptables-restore during a remote session:

$ sudo iptables-apply --timeout 30 "$GOOD_RULES"

7. Apply IPv6 rules with the alias

Run the equivalent workflow through ip6tables-apply. The helper detects the name it was invoked as and switches to ip6tables-save, ip6tables-restore and IPv6 default paths:

$ sudo ip6tables-apply --timeout 30 /path/to/approved-ip6tables.rules
Applying new ip6tables rules from '/path/to/approved-ip6tables.rules'... done.
Can you establish NEW connections to the machine? (y/N)

Test IPv6 from a separate connection: an IPv4 test proves nothing about IPv6 access. The default IPv6 rules file is /etc/network/ip6tables.up.rules, and the default command file in command mode is /etc/network/ip6tables.up.run.

8. Use command mode only when you need it

The --command option runs an executable instead of restoring a rules file. The command must be a single executable path, not an arbitrary shell fragment:

$ sudo iptables-apply --timeout 30 --command /path/to/configure-firewall
Running command '/path/to/configure-firewall'... done.
Can you establish NEW connections to the machine? (y/N)

The default executable is /etc/network/iptables.up.run. Keep the script narrow, executable and reviewable. Do not feed it unquoted user input, and do not assume --command makes a shell pipeline safe on its own. The helper runs the executable in the background and treats a timeout or failed command as a failure, then restores the old rules.

Common traps

  • Skipping sudo. Running iptables-apply without it and mistaking a permissions error for a bad rules file.
  • Testing the wrong connection. Checking only the existing SSH session instead of establishing a new one.
  • Confirming too early. Answering y before checking IPv4 and IPv6 paths, which also makes the rules eligible for the saved last-good file.
  • Getting the timeout wrong. Sticking with the default 10 seconds when your test needs longer, or picking an unnecessarily long timeout that delays recovery.
  • Mixing up the alias. Applying IPv4 rules with the IPv6 alias, or expecting an IPv4 rule file to configure IPv6.

Done means

  • Helper and version checked. The installed helper and package version were confirmed on the target host.
  • Rules file reviewed. It was inspected and remains available for recovery.
  • New connection tested. A separate connection proved the new policy before confirmation.
  • Rollback understood. The timeout and automatic rollback behaviour were tested, ideally in a maintenance window.
  • Last-good file written. A confirmed last-good file exists with restricted permissions when future recovery might need one.
  • Both protocols tested. IPv4 and IPv6 were tested separately when both families are in use.