Wandering Thoughts archives


'iptables -L' doesn't show you interface matches on rules by default

Today I learned something that I could have noticed if I'd paid enough attention, which is that the default 'iptables -L' output doesn't show you interface matches that are part of rules. In order to see this in 'iptables -L' you have to make it verbose (with -v), which also shows you the volume counters. There is a story here.

Normally I look at my iptables rules with 'iptables -vnL' (and often a particular chain, like INPUT), or with 'iptables --line-numbers -nL' if I'm planning to delete rules and want their line numbers. Recently I noticed that libvirt was doing some things to my iptables setup and I decided to scrub them all out, which meant getting line numbers. When I did this, I saw what I thought was a dangerous accept-all rule (which I assumed was added by libvirt). In the 'iptables --line-numbers -nL' output, things looked like this:

# iptables --line-numbers -nL INPUT
Chain INPUT (policy ACCEPT)
num  target  prot opt source     destination         
1    ACCEPT  all  --

I did various things to try to track this rule down and to remove it reliably. Eventually I had a chance to look at the state of my machine's iptables rules very soon after boot, where I used 'iptables -vnL INPUT'. The rule was there, and at first I was irate. But then I looked closer. In the verbose output there were some additional fields:

# iptables -vnL INPUT
Chain INPUT (policy ACCEPT [...])
 pkts bytes  target prot opt in  out source     destination         
  NNN   NNN  ACCEPT all  --  lo  *

Oh. This dangerous looking rule was actually an 'allow all from loopback' rule to make sure that no local traffic was blocked by other, later rules. At the time I didn't realize that the basic 'iptables -L' output didn't contain this information, so I assumed that I had just failed to fully read output and had jumped to conclusions (it wouldn't be the first time).

(Then I was told and suddenly everything made much more sense.)

The somewhat less convenient alternative to 'iptables -L' is 'iptables -S', which is less readable but shows you the full rule as iptables understands things. For example:

# iptables -S INPUT
-A INPUT -i lo -j ACCEPT

I probably won't switch my habits to using 'iptables -S' for various reasons, but hopefully I'll remember it. If what I care about is the actual rules, I should probably use it over 'iptables -vnL'. Usually what I'm looking at is the traffic volume, though, and that requires 'iptables -vnL'.

The other drawback of 'iptables -S' is that there appears to be no way to get it to list line numbers. If you want to look for bad rules and delete them with line numbers, this leaves you to use 'iptables --line-numbers -vnL' or to go back and forth between 'iptables -S' (to see the exact rules) and 'iptables --line-numbers -vnL' (to get the line numbers for what you've determined you want to get rid of).

(I know, in the bright future we'll all be using nftables instead. The future isn't here yet and I'm sure nftables has its own issues, although I did recently do some firewall stuff through nftables on an Ubuntu 22.04 machine and it went okay.)

linux/IptablesOutputAndInterfaces written at 22:50:57; Add Comment

Page tools: See As Normal.
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.