Check and Migrate firewalld Config with firewall-offline-cmd
Run firewall-offline-cmd against a live firewall and you are editing files under a daemon that is not listening to you. This guide gives you a repeatable way to inspect, validate and migrate firewalld configuration with the offline client, while keeping it away from a running firewall. The examples match firewalld 2.1.1, the version installed on the reference system, and take about 20 minutes plus time to review the resulting rules.
The route
Jump straight to the step you need, or tick off Done means at the end.
- You need firewalld installed, root access for the command itself, a maintenance window if you will change the system configuration, and a tested recovery path.
- Offline means offline. The manpage says to use this client only when the firewalld service is not running.
- It is not a safer
firewall-cmd. Do not use it as one on a live host.
1. Confirm the installed command
Check the package version and binary as an ordinary user. These commands only read local metadata:
$ command -v firewall-offline-cmd
/usr/bin/firewall-offline-cmd
$ dpkg-query -W -f='${Package} ${Version}\n' firewalld
firewalld 2.1.1-1
$ firewall-offline-cmd --help
You need to be root to run /usr/bin/firewall-offline-cmd.
The last message is an access check from this installation. Run the client with sudo only after you have confirmed that firewalld is stopped and that you have a backup or rollback plan.
Warning
Do not use the no-option form as a discovery command. With no options, it attempts to migrate /etc/sysconfig/system-config-firewall.
Checkpoint
You have recorded the package version, identified the configuration directories you intend to use, and confirmed that changing them is authorised.
2. Make the service boundary explicit
Before using a state-changing option, check the service state:
$ systemctl is-active firewalld
inactive
Anything other than inactive needs investigation before you continue. Stopping a firewall service can remove live protection and may interrupt connections, so schedule that action rather than hiding it in a longer command:
# sudo systemctl stop firewalld
# sudo systemctl is-active firewalld
inactive
Warning
That command is elevated and service-disrupting. Do not run it on a remote host unless you have console access or another recovery route.
When you have finished, restore the service deliberately, if that is how the host is meant to operate:
# sudo systemctl start firewalld
# sudo systemctl is-active firewalld
active
If the service must stay active, stop here and use the online client or a separate offline configuration tree instead.
3. Validate without migrating legacy input
--check-config checks the permanent default and system configuration, including XML validity and semantics. It is the best first operation after stopping the service:
# sudo firewall-offline-cmd --check-config
A clean run may produce no output and return status 0. Make the status visible when you are recording a change:
# sudo firewall-offline-cmd --check-config
# printf 'exit status: %s\n' "$?"
exit status: 0
A non-zero status means the configuration needs attention. Read the complete diagnostic before trying another option.
If you maintain handwritten files away from the standard location, pair --check-config with --system-config pointing at that directory. Correct the source files before you copy anything into /etc/firewalld. The option changes where the system configuration is read; it does not make malformed XML safe.
# sudo firewall-offline-cmd \
--system-config /srv/firewalld-staging \
--check-config
Checkpoint
The configuration tree you will use passes the check. Keep the output and exit status with the change record, and do not go on until it passes.
4. Migrate a legacy system-config-firewall file
For a specific legacy file, use --migrate-system-config-firewall. Supply an explicit path so there is no doubt which input is being converted:
# sudo firewall-offline-cmd \
--migrate-system-config-firewall=/srv/backup/system-config-firewall
The conversion is incomplete by design.
- Ignored input. The tool can warn about or ignore custom rule files and module settings.
- Translation limits. The compatibility options cover services, ports, forwarding, ICMP blocks, trusted interfaces and masquerading, but those translations have boundaries. For example, the
--masqinterface argument is ignored and the resulting masquerading is IPv4-only. - Warnings are work. Treat them as review items, not harmless noise.
A successful exit does not prove that the resulting policy matches the old firewall. The manpage describes special handling for repeated options: an already-enabled item, an item that was not enabled, or an already-set zone can count as success. If one item succeeds while another has a parsing warning, the overall status can still be zero. Read all the output and inspect the saved configuration afterwards.
Recovery
There is no universal undo for a migration. Keep a copy of the current firewalld configuration before changing it, and restore that copy through your normal configuration-management process if review finds a problem.
Warning
Do not use --reset-to-defaults as an undo button. It resets the configuration to firewalld defaults and can discard deliberate local policy.
5. Apply a small, explicit offline change
The compatibility options can add a service or port to the default zone. Use a known firewalld service name, and query the available names before you pick one:
# sudo firewall-offline-cmd --get-services
cockpit dhcp dhcpv6 dhcpv6-client dns freeipa-ldap freeipa-ldaps ...
# sudo firewall-offline-cmd --service=ssh
The list is host-specific, so the abbreviated line above is illustrative rather than literal output. To add a raw port, use a single port or range followed by a colon and one of tcp, udp, sctp or dccp:
# sudo firewall-offline-cmd --port=8443:tcp
# sudo firewall-offline-cmd --port=50000-50010:udp
These examples change persistent firewall configuration. They do not mean that a running daemon has safely reloaded the new policy, which is another reason to keep the service stopped during the offline workflow. After each change, rerun --check-config and inspect the relevant zone or service files through your normal review process.
Removing a service is also a persistent change:
# sudo firewall-offline-cmd --remove-service=ssh
Warning
Only use that example when SSH access is provided another way and the resulting policy is intentional. Recovery is to restore the backed-up configuration, run --check-config again, then start firewalld during the approved window.
6. Avoid compatibility traps
Several legacy-looking options do not carry their old meaning cleanly:
--addmodule,--removemoduleand--custom-rulesproduce warnings and are ignored.--trust,--masqand--forward-portproduce warnings because their conversion has limitations.- A quiet migration proves nothing. Check the generated configuration rather than assuming it reproduced every netfilter detail.
Direct rules are deprecated in this firewalld release and are intended only as a last resort. The manpage also warns that their behaviour depends on the firewall backend. Prefer services, zones, rich rules or policies where they express the requirement. Do not paste direct arguments from an old script without reviewing the table, chain, priority, address family and backend.
Tip
Use --default-config for an alternate default tree and --system-config for an alternate system tree, and keep those paths separate. Pointing both at the same staging directory can make a test misleading even if the XML is valid.
Done means
- Version recorded. You confirmed firewalld 2.1.1 or noted the version on your own host.
- Service stopped. You verified firewalld was stopped before using the offline client.
- Check run. You ran
--check-configagainst the exact configuration tree in scope. - Warnings reviewed. You did not treat a zero exit status as proof of equivalence.
- Backup kept. You had a recoverable copy before adding, removing or resetting configuration.
- Restart was deliberate. You started the service again only after the resulting policy passed review.