2

I'm just beginning to dig into iptables for the first time today, so apologies for any naivete.

For reference, I'm using

  • Ubuntu 22.04.4 LTS (Jammy Jellyfish)
  • iptables v1.8.7 (nf_tables)
  • ufw 0.36.1

Now, I know (or, rather, recently learned) that ufw is just a wrapper for iptables. I decided I wanted to understand what was going on underneath the hood, so I started reading and poking around. What I can't seem to understand is how iptables deals with packets in conjunction with ufw. Let's start with the INPUT chain, which is I believe where any incoming packet would start.

Chain INPUT (policy DROP)
target                   prot opt source   destination
ufw-before-logging-input all  --  anywhere anywhere
ufw-before-input         all  --  anywhere anywhere
ufw-after-input          all  --  anywhere anywhere
ufw-after-logging-input  all  --  anywhere anywhere
ufw-reject-input         all  --  anywhere anywhere
ufw-track-input          all  --  anywhere anywhere

I feel like if I'm understanding everything correctly, then this first line here ufw-before-logging-input all -- anywhere anywhere means that any packet that comes in, on any port, from anywhere, will be passed along to the ufw-before-logging-input chain. If it comes back from that chain without being accepted, dropped, or rejected, then it'll be passed on to the next chain, in this case ufw-before-input, and so on and so forth, until it's accepted, dropped, or rejected (viz., until it encounters a terminating action).

Okay, so let's look at the first chain any packet will be passed along to, ufw-before-logging-input.

Chain ufw-before-logging-input (1 references)
target     prot opt source               destination

Literally nothing here, so we move on to the ufw-before-input chain

Chain ufw-before-input (1 references)
target           prot opt source   destination
ACCEPT           all  --  anywhere anywhere
ACCEPT           all  --  anywhere anywhere     ctstate RELATED,ESTABLISHED
ufw-logging-deny all  --  anywhere anywhere     ctstate INVALID
DROP             all  --  anywhere anywhere     ctstate INVALID
ACCEPT           udp  --  anywhere anywhere     udp spt:bootps dpt:bootpc
ufw-not-local    all  --  anywhere anywhere
ACCEPT           udp  --  anywhere host.name    udp dpt:mdns
ACCEPT           udp  --  anywhere w.x.y.z      udp dpt:num
ufw-user-input   all  --  anywhere anywhere

And this is where I'm confused. The very first line looks like we just accept any packet at all ACCEPT all -- anywhere anywhere but.... my firewall rules work, they block traffic.

So, what am I missing, here?

(Note, tried to post this on Stackoverflow, but they sent me here. Just including this in case you Google it and see this is duplicated elsewhere.)

1 Answer 1

1

So, what am I missing, here?

The -v option for verbose:

-v, --verbose

Verbose output. This option makes the list command show the interface name, the rule options (if any), and the TOS masks. The packet and byte counters are also listed, [...]

You probably used something like:

# iptables -L  ufw-before-input
Chain ufw-before-input (1 references)  
target            prot  opt  source    destination                                        
ACCEPT            all   --   anywhere  anywhere                                           
ACCEPT            all   --   anywhere  anywhere         ctstate RELATED,ESTABLISHED      
ufw-logging-deny  all   --   anywhere  anywhere         ctstate INVALID                  
DROP              all   --   anywhere  anywhere         ctstate INVALID
[...]

which won't display interfaces. Instead with -v:

# iptables -v -L ufw-before-input
Chain ufw-before-input (1 references)
pkts  bytes  target            prot  opt  in   out  source    destination                                        
   6    504  ACCEPT            all   --   lo   any  anywhere  anywhere                                           
  12   1032  ACCEPT            all   --   any  any  anywhere  anywhere         ctstate RELATED,ESTABLISHED      
   0      0  ufw-logging-deny  all   --   any  any  anywhere  anywhere         ctstate INVALID                  
   0      0  DROP              all   --   any  any  anywhere  anywhere         ctstate INVALID                  
[...]

One can see the ACCEPT rule is for input interface lo: to allow inconditionally loopback traffic, and only from the lo interface. Anything else continues chain traversal.

Anyway this format isn't really suitable for reproducibility especially when displaying a ruleset in a Q/A. It might still be useful to check status of special (eg: with memorized state) matches or targets. Better use either iptables -S or iptables-save (for the whole ruleset or at least a whole table).

# iptables -S ufw-before-input
-N ufw-before-input
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-input -m conntrack --ctstate INVALID -j ufw-logging-deny
-A ufw-before-input -m conntrack --ctstate INVALID -j DROP
[...]

iptables -S can also accept the -v option to display counters among other states. Likewise to display counters with iptables-save use iptables-save -c. iptables-save is intended to provide an output suitable for iptables-restore allowing to save and restore rulesets. Also using twice -v (eg: -vv) with iptables displays additional debug information.

1
  • wow. I figured it was something small I was missing. Thank you so much!! Commented Apr 10 at 17:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .