Safely Apply Remote iptables Changes with iptables-apply
You will apply a new IPv4 or IPv6 firewall ruleset over a remote connection, get a short window to test a new connection, and let iptables-apply restore the previous rules if confirmation does not arrive. 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.
The route
Jump straight to the step you need, or tick off Done means at the end.
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 identifies the local command family, but it does not guarantee that another host uses the same backend or package release. Check the target host itself before applying rules there.
Checkpoint: confirm that 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 block SSH.
2. Prepare and inspect a rules file
iptables-apply accepts a rules file in the format produced by iptables-save and consumes it through iptables-restore. The file is not a list of shell commands. Prepare it with your normal firewall tooling, then inspect it before using 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. Do not paste an unreviewed rules file into a remote shell. A full restore can replace the active filter, NAT, mangle and related tables, so this is a service-disrupting security change. Keep the previous rules available and decide how SSH, DNS, monitoring and your administration path will remain reachable before proceeding.
The default file, if you omit the argument, is /etc/network/iptables.up.rules. Using an explicit path makes a review and rollback plan easier to follow.
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 require root privileges:
$ 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)
The helper first saves the current rules to a temporary file, restores the proposed file, and asks whether a new connection works. The default timeout is 10 seconds. Type y or Y only after testing from a separate connection. Pressing another key, pressing Enter without an affirmative answer, or allowing the timer to expire takes the safe path and restores the old rules.
Checkpoint: use the second session to open a genuinely new connection, not merely to continue an existing one. For SSH, connect from a separate terminal and run a harmless command such as id. A still-open session can hide a rule that blocks 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 a successful confirmation. It is the period in which the helper waits for an affirmative response. Choose a value long enough to test, but keep it finite: if your connection is broken, the process must regain control and revert.
Do not treat a successful exit as proof that the policy is correct. After typing y, check the actual 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. The useful evidence 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 the command with a short timeout, then 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 with whether the timeout or a non-affirmative key caused the rollback. Verify the result from a trusted console with sudo iptables-save. This test changes the live firewall briefly, 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 you should still check the active rules and use your out-of-band access if needed.
6. Keep a confirmed last-good file
Use --write to save the rules only after you answer yes. This 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 because it describes your firewall and can be used to change it. Confirm that it was written only after testing:
$ 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 directly 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)
Use an IPv6 test from a separate connection. Do not assume that an IPv4 test proves IPv6 access is correct. 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 put unquoted user input into it, and do not assume that adding --command makes a shell pipeline safe. 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
- Using
iptables-applywithoutsudoand mistaking a permissions error for a bad rules file. - Testing only the existing SSH connection instead of establishing a new one.
- Answering
ybefore checking IPv4 and IPv6 paths, which makes the new rules eligible for the saved last-good file. - Relying on the default 10 seconds when your test needs longer, or setting an unnecessarily long timeout that delays recovery.
- Applying IPv4 rules with the IPv6 alias, or expecting an IPv4 rule file to configure IPv6.
Done means
- The installed helper and package version were checked on the target host.
- The rules file was reviewed and remains available for recovery.
- A separate connection tested the new policy before confirmation.
- The timeout and automatic rollback behaviour were understood, and ideally tested in a maintenance window.
- A confirmed last-good file was written with restricted permissions when future recovery requires one.
- IPv4 and IPv6 were tested separately when both protocol families are in use.