Watch Firewall Rules Change Live with xtables-monitor
When a firewall rule appears from nowhere, xtables-monitor is how you catch the process that put it there, live. You will finish with two practical ways to watch an iptables ruleset: a live stream of ruleset changes, and a trace of selected packets as they pass through the rules. The examples use xtables-monitor 1.8.10 from iptables 1.8.10, on the nf_tables backend.
The route
Jump straight to the step you need, or tick off Done means at the end.
- Time: about fifteen minutes for a read-only monitoring session.
- You need: a shell, iptables-nft, and access to the host's netfilter interfaces. Root is usually required for the monitor and for any rule change.
Safety boundary
Monitoring alone does not edit the firewall, but a TRACE rule does change packet-filtering configuration. Do not add one to a busy production firewall without a narrow match and a removal command already typed out.
1. Confirm the installed backend
Start with ordinary, read-only checks. None of these need elevated privileges:
$ command -v xtables-monitor
/usr/sbin/xtables-monitor
$ iptables --version
iptables v1.8.10 (nf_tables)
$ xtables-monitor --help
xtables-monitor 1.8.10 (nf_tables)
Usage: xtables-monitor [ -t | -e ]
The important detail is (nf_tables). The monitor reads events from the nftables-backed iptables path. The installed manual is explicit that rules added through iptables-legacy cannot be seen here, so a silent session is not proof that nobody is touching the firewall until you have checked which command family is actually in use.
Checkpoint
Record the version and backend. If iptables --version reports legacy, this guide's monitoring examples are watching the wrong door entirely.
2. Watch ruleset changes
Open a terminal and start the event monitor. It is long-running. Add sudo if the unprivileged attempt cannot reach the netfilter event socket:
$ sudo xtables-monitor --event
It runs until you stop it with Ctrl-C, reporting table, chain and rule creation together with the program that caused each change. The exact sequence depends on the host and whatever tool is making the change.
In another terminal, make a harmless, deliberate change, but only if you are authorised to alter this firewall. This creates a temporary chain and then removes it:
$ sudo iptables -N XT_MONITOR_TEST
$ sudo iptables -X XT_MONITOR_TEST
Back in the monitor, expect lines equivalent to -N XT_MONITOR_TEST and -X XT_MONITOR_TEST. Event output can also carry nft-native table and chain detail, so do not build a parser that assumes every line looks like an iptables command.
Recovery
If the second command was never run, the test chain is still sitting in the ruleset. Remove it with sudo iptables -X XT_MONITOR_TEST, but only after checking it has no references; the command refuses to delete a chain still in use.
3. Understand the event checkpoint
When iptables-nft restores or rebuilds a ruleset, the monitor can show a new table, base chains and several rules before a NEWGEN line. The manual's example uses NEWGEN to mark the moment the new ruleset generation actually becomes active, complete with the process ID and program name.
That distinction matters during incident work. A rule-creation line only means an update was described to the monitor. The generation event is what tells you when the changed ruleset went live. Capture the whole sequence, program name included, rather than just the one rule that caught your eye.
If the monitor immediately prints cannot bind to nfnetlink socket: Operation not permitted, the process lacks the access it needs in that environment. Try the same command with sudo. If it still fails inside a container or restricted service, the missing capability may sit outside that container's control; do not weaken host security just to get a diagnostic stream working.
4. Add a narrow TRACE rule
xtables-monitor --trace watches trace events generated by packets marked with the iptables TRACE target. Starting the monitor alone does not cause anything to be traced; you still need a rule that selects the packets.
For a controlled HTTP test, start the monitor first:
$ sudo xtables-monitor --trace --ipv4
Then, in a second terminal, add a deliberately narrow rule. This one selects at most one new TCP connection per second to port 80 arriving at the IPv4 raw table's PREROUTING chain:
$ sudo iptables -t raw -A PREROUTING -p tcp --dport 80 --syn -m limit --limit 1/s -j TRACE
Generate a matching connection, or wait for one if the host serves HTTP. The monitor should print TRACE lines for the packet, a PACKET line with interface and header information, then the eventual chain or policy result. A packet identifier in the trace lets you tie lines from the same packet together. This is diagnostic data, not a substitute for reading the full ruleset.
TRACE is security-sensitive: it changes the firewall's rule path and exposes packet metadata. Keep the match specific. Do not run a catch-all TRACE rule on a busy interface unless you have measured the impact and hold a maintenance window.
5. Remove the TRACE rule
Remove the exact rule as soon as the capture is complete. This is an elevated, state-changing command:
$ sudo iptables -t raw -D PREROUTING -p tcp --dport 80 --syn -m limit --limit 1/s -j TRACE
The deletion has to match the rule you added. Confirm it is gone with a read-only listing:
$ sudo iptables -t raw -S PREROUTING
# the TRACE rule should no longer be listed
If you changed the port, protocol or limit, use the same values in the delete command. If the rule landed in a different position or picked up extra matches, inspect iptables -t raw -S PREROUTING and remove the exact rule shown there. Do not flush the raw table as a shortcut; that can take unrelated production rules with it.
6. Filter the address family
The monitor supports -4 or --ipv4 for IPv4 and -6 or --ipv6 for IPv6. Use one when the other protocol family would just be noise for your investigation:
$ sudo xtables-monitor --event --ipv4
$ sudo xtables-monitor --trace --ipv6
These filters only change what the monitor reports. They do not convert an IPv4 rule into an IPv6 rule, and they add or remove nothing from firewall policy.
Common traps
- No output does not mean no activity. Check the command is actually iptables-nft, that the monitor can open its netfilter socket, and that the address family matches the traffic you expect.
- Do not confuse event and trace modes.
--eventwatches ruleset updates.--tracewatches packets a TRACE rule has already tagged. - Do not leave TRACE enabled. Keep the delete command ready in your terminal history before adding the rule, then verify it is gone.
- Do not assume a stable output format. nft-native records, iptables command-style records and generation metadata can all show up in one event stream.
- Legacy rules are invisible here. Anything added through iptables-legacy cannot be monitored by this tool.
Done means
- Backend confirmed: iptables 1.8.10 and the nf_tables backend.
- Event monitoring proven: you started and stopped it without changing firewall policy.
- Generation events understood: you can recognise one and identify the updating process.
- TRACE used and cleaned up: a narrow match, added and then removed.
- Final check done: the raw-chain listing is clean and unrelated firewall rules are untouched.