3

A few months ago, I migrated the firewall of a debian laptop from iptables to nftables, using debian's recommended procedure, and all seems to have been fine. Now, months later, I'm scrutinizing the rule-set created by that migration procedure, trying to learn the nftables syntax, and see what seem to be several counter-based rules that I don't understand and suspect might not be correct. I haven't found the nftables wiki to be a helpful educational resource, and haven't found any other on-line educational resource that addresses this kind of question:

The default auto-migrated rule-set included the following:

table inet filter {
  chain INPUT {
    type filter hook input priority 0; policy drop;
    counter packets 123 bytes 105891 jump ufw-before-logging-input                                                                                                                                
    counter packets 123 bytes 105891 jump ufw-before-input
    counter packets 0 bytes 0 jump ufw-after-input
    counter packets 0 bytes 0 jump ufw-after-logging-input
    counter packets 0 bytes 0 jump ufw-reject-input                                                                                                                                               
    counter packets 0 bytes 0 jump ufw-track-input                                                                                                                                                
  }

The first two counter statements are examples of what caught my eye. Am I correct that they are saying "jump to the rules in section ufw-before-foo, but only after the first 123 packets and the first 105891 bytes have been received".

  1. Why not start immediately from packet 0 byte 0?
  2. Why not use a syntax >= which seems to supported by nftables?
  3. Are these numbers arbitrary? Possibly due to a glitch in the migration?

The above rule-set includes a jump to the following chain, with a possibly similar issue. Here's a snippet of it:

  chain ufw-before-input {
    iifname "lo" counter packets 26 bytes 3011 accept
    ct state related,established counter packets 64 bytes 63272 accept
    ct state invalid counter packets 0 bytes 0 jump ufw-logging-deny
    ct state invalid counter packets 0 bytes 0 drop
    ...
  }
  1. Why are the decisions to accept based upon the receiving 26 or 64 prior packets?
  2. A firewall can be flushed arbitrarily at any time after power-up and network discovery/connection, so why drop all those initial packets?

As I mentioned above, these rules have been in place for months, so I'm wondering what negative effect they could possibly have had. The only candidate that I've come up with is that the laptop can sometimes have a difficult time making a wifi connection (especially after resuming from sleep) while a second nearby laptop has no such trouble.

  1. Could these rules dropping packets be the culprit for difficulty negotiating a wifi connection?

1 Answer 1

3

No, the explanation is much simpler: the counter statement has optional arguments packets and bytes which display the number of packets and bytes counted by the counter when a packet reached the rule where it was. Without filter before the counter, any packet (including on loopback) will thus increase the values so it can happen very early and fast. The tool doing conversion saw an iptables default counter and chose to also translate its values for fidelity.

So usually when you write a rule you don't set those values, you put a simple counter alone, and they both get a default of 0. When packets traverse it those values increase. Optionally, especially when used in a named counter stateful object where it can even be displayed-and-reset (using something like nft reset counters), to do some form of accounting, one can set those values when writing the ruleset: usually when restoring the ruleset saved right before reboot. This can only be reset if used as the named variant, not as "inlined" anonymous counter. They cannot be used to alter the match in a rule, there's no other option than to display them.

Any wifi problem you have cannot be caused by any counter statement.

If now you want to use packets count to limit the usage of rules in a nftables firewall, there are a few different methods depending on needs:

  • the other stateful object quota (again which can be used anonymously, but can only be reset if used named). You can then have for example a rule never match or start matching depending on its count.

  • there's the limit statement to count rates. For example if you fear a log rule could flood log files, you can use this to limit the number of logs done. It can also limit the rate to some ressource (usually used with other filters with conntrack).

  • with a recent enough nftables (0.9.2?) and kernel (4.18?), there's the ct count conntrack expression to count the number of established connection using conntrack, usually to limit concurrent access to some ressource (ssh, web server...)

4
  • Great answer, and the links to documentation are especially appreciated! Dec 12, 2019 at 8:02
  • So: 1) the ocurrences of packets n bytes n are cruft that can/should be deleted?; 2) the counter commands might be better placed within rules of the chains being jumped to? Dec 12, 2019 at 8:02
  • 1/ yes for your case it's probably cruft. If you don't even want to use counters, you can even remove them completely. 2/ if the counter is at the start of a rule, it will always match. usually a counter is placed toward the end of the rule, either the last statement, or right before the terminal statement (jump, accept, drop etc). placing it as the first statement in the jump rule without other filter or at the start of the first rule in the jumped chain will count the same values. it's best used when there are filters before the counter, except for a generic accounting
    – A.B
    Dec 12, 2019 at 8:51
  • Got it. Thanks again for the guidance. Dec 12, 2019 at 9:05

You must log in to answer this question.

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