On a Linux host, `iptables -L` takes tens of seconds before it prints anything. Why does listing rules stall like that, and what do the `-n`, `-v` and `--line-numbers` options change about the output?
answer
- listing tries to be friendly first
- something is being resolved per address
- counters and interfaces are hidden by default
- the number -D and -I take
basics
~20 siptables -L reverse-resolves every address in the ruleset and turns port numbers into service names, so it stalls whenever DNS is slow or dead. Adding -n prints raw numbers, -v adds packet and byte counters plus interface columns, and --line-numbers indexes each rule.
solid answer
~50 sPlain `iptables -L` does name lookups you never asked for: it reverse-resolves every address in the ruleset and maps port numbers to names from `/etc/services`. On a box whose resolver is unreachable — often exactly why you are looking at the firewall in the first place — every lookup waits for a timeout, so the listing crawls. In practice I always list with `iptables -L -n -v --line-numbers`. `-n` kills the name resolution, which fixes the speed and also the accuracy, since an address is unambiguous and a reverse-resolved name is not. `-v` adds the columns you actually debug with: per-rule packet and byte counters and the in/out interface columns, which plain `-L` hides completely. `--line-numbers` prints each rule's index within its chain, and those indexes are what `-I`, `-D` and `-R` take. When I want to copy a rule rather than read a table, I use `iptables -S`, which prints rules as the commands that would recreate them.
code
bash · 4 linesiptables -L -n -v --line-numbers
iptables -L INPUT -n -v -x --line-numbers
iptables -S INPUT
ip6tables -L -n -v --line-numbersgo deeper
Know that -L resolves names and can hang, that -n stops it, and be able to say out loud that -L -n -v --line-numbers is the listing you actually use.
Explain what each column under -v means, especially that the in/out interface columns are hidden without it, and that the chain header counters show traffic handled by the default policy.
Show that you treat the counters as evidence: zero them, reproduce the failure, and reason from which rule moved. Mention that ip6tables is a separate ruleset you check too.
Be ready to argue for a house convention — reviewable rule text from -S under version control rather than ad-hoc reads of a tabular listing — and to explain why human-readable output is the wrong interface for automation.
## What plain `iptables -L` is really doing `iptables` is the userspace command for managing the Linux kernel's IPv4 packet-filter rules. When you run `iptables -L`, it reads the ruleset out of the kernel and then, before printing, tries to make it friendly for a human. Every IPv4 address in a rule is put through a reverse DNS lookup so it can be shown as a hostname, and every port number is looked up in `/etc/services` so `443` can be shown as `https`. Neither of those is free. On a host whose resolver is unreachable — a very plausible state on a machine you are debugging, especially if the firewall itself is blocking DNS — every reverse lookup blocks until it times out. A ruleset with a few dozen distinct addresses then takes tens of seconds to appear, one timeout at a time. Nothing is wrong with the firewall or the kernel; the command is simply sitting in a resolver call. ## `-n` is about correctness as well as speed `-n` (long form `--numeric`) tells iptables to print addresses and ports numerically and skip resolution entirely. The listing then returns instantly, because no network calls happen at all. Speed is only half the reason to use it. A reverse-resolved name is not a faithful rendering of a rule. The rule matches an address; the name shown is whatever PTR record happened to answer at the moment you looked, which may be stale, may be one of several names, or may be a name that no longer maps forward to the same address. Reading `-n` output means reading exactly what the kernel will match on. ## What `-v` adds `iptables -L` on its own prints only `target`, `prot`, `opt`, `source` and `destination`. Adding `-v` widens the table to `pkts`, `bytes`, `target`, `prot`, `opt`, `in`, `out`, `source`, `destination`. Two of those extra columns matter enormously: - **`pkts` and `bytes`** are per-rule counters maintained by the kernel. They are the cheapest evidence you have that a rule is or is not being hit. A rule you just added showing `0 0` while the problem persists tells you the packet never reaches it. - **`in` and `out`** are the interface restrictions. Without `-v`, a rule restricted to `-i lo` looks identical on screen to one that applies to every interface. That is a genuine trap: people conclude a service is open to the world when the accepting rule is loopback-only. The chain header line also gains counters under `-v`, for example `Chain INPUT (policy DROP 12 packets, 900 bytes)` — those are the packets that fell through every rule and were handled by the chain's default policy. Add `-x` (`--exact`) if you want raw counter values instead of the rounded `K`/`M`/`G` forms. ## `--line-numbers` and editing by position `--line-numbers` is valid together with `-L` and prefixes each rule with its position in its chain, starting at 1. Those numbers are the currency of rule editing: - `iptables -I INPUT 4 <rule>` inserts at position 4. - `iptables -D INPUT 4` deletes rule 4. - `iptables -R INPUT 4 <rule>` replaces rule 4. Remember that positions are recomputed after every change: delete rule 4 and the old rule 5 becomes rule 4. When removing several rules by number, work from the bottom of the chain upward, or you will delete the wrong ones. ## `iptables -S` as the other listing `iptables -S` (`--list-rules`) prints the chain policies and then each rule as the argument list that would recreate it, for example `-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT`. It does no name resolution either, and it is faithful about match extensions in a way the tabular `-L` view is not. It is the right listing when you want to copy a rule, diff two hosts, or paste a rule into a change ticket. ```bash # the habit worth memorising iptables -L -n -v --line-numbers # one chain only, exact counters iptables -L INPUT -n -v -x --line-numbers # copy-pasteable form iptables -S INPUT ``` ## One last thing to check `iptables` shows you the IPv4 ruleset and nothing else. IPv6 is a completely separate ruleset managed by `ip6tables`, with its own `-L -n -v`. If a client reaches your host over IPv6, nothing in the `iptables` listing applies to it, and an empty-looking IPv4 chain proves nothing about what that client is experiencing.
- Your listing shows a rule with 0 packets and 0 bytes. What does that tell you, and what does it not tell you?It tells you no packet has matched that rule since the counters were last zeroed — either the traffic never reaches this rule, or it is being handled by an earlier rule, or the traffic is not happening at all. It does not tell you the rule is wrong; a correct rule sitting below a terminating DROP shows exactly the same zeros. Zero the counters with `iptables -Z`, reproduce, and re-read.
- When would you reach for `iptables -S` instead of `iptables -L -n -v`?When I want the rule rather than the report. `-S` prints each rule as the exact argument list that would recreate it, so it is what I copy into a change, diff between two hosts, or paste into a ticket. `-L -v` is the diagnostic view because only it carries the counters; `-S` has no counters at all.
saying these in an interview costs you the question
- Thinks the delay means the kernel or firewall is overloaded
- Reads hostnames from -L as what the rule matches on
- Assumes a rule with no interface shown applies everywhere
- Deletes several rules by number top-down and hits the wrong ones
- Believes iptables -L also covers IPv6 traffic