5

I'm attempting to track the total data being transmitted from a specific set of IP addresses (both IPv4 and IPv6) using nftables with a named counter on the rule. My goal is to be able to track this total over the course of a calendar month so I can bill against usage.

The related rules look like this:

add table stats
add counter stats os-traffic-4
add counter stats os-traffic-6
add chain inet stats INPUT { type filter hook input priority 0; }
add rule ip  stats INPUT ip  saddr 192.168.123.123 counter name os-traffic-4
add rule ip  stats INPUT ip  saddr 192.168.123.234 counter name os-traffic-4
add rule ip  stats INPUT ip  saddr 192.168.123.345 counter name os-traffic-4
add rule ip6 stats INPUT ip6 saddr 1234:1234:1234:1234:1234:1234:1234:1234 counter name os-traffic-6
add rule ip6 stats INPUT ip6 saddr 1234:1234:1234:1234:1234:1234:1234:2345 counter name os-traffic-6
add rule ip6 stats INPUT ip6 saddr 1234:1234:1234:1234:1234:1234:1234:3456 counter name os-traffic-6

I'm using stateful objects (named counters) to sum all of the traffic from the IPv4 and IPv6 addresses respectively, named os-traffic-4 and os-traffic-6. I can then use the command line to get those stats with nft list counter stats os-traffic-6.

My questions are:

  1. Where are these stats stored, I don't see them in a log anywhere and can't find reference in any documentation?

  2. Will these statistics persist past a reboot of the machine or will the counters reset?

  3. If they do reset, how do I restore them at boot time? I believe it's possible to include the counter values when using add rule... packets 1234 bytes 123456 but how do I do it for a named counter and also... #1... where do I get these numbers from?

Thanks for any help!

oucil
  • 445
  • 3
  • 16

1 Answers1

5

I believe that nftables counters are stored in kernel memory only, similar to tables and rules. They may not persist across reboots.

My suggestion to keep permanent record of the counter values is to:

  • Declare your counters in a separate file and include it from your main nftables configuration file.
  • Have the counter declaration file updated with current values.

Depending on the distribution you are using, you may have a nftables.service unit that loads rules from a configuration file. If so, you can design a service that depends of nftables.service and writes counter values to the state file. For example, in Arch Linux, the nftables.service is designed to load firewall rules from /etc/nftables.conf, so you could define these configuration files:

# /etc/nftables.conf

add table stats

# Counter definitions go to '/var/lib/nftables.state'
include "/var/lib/nftables.state"

add chain inet stats INPUT { type filter hook input priority 0; }
add rule ip  stats INPUT ip  saddr 192.168.123.123 counter name os-traffic-4
add rule ip  stats INPUT ip  saddr 192.168.123.234 counter name os-traffic-4
add rule ip  stats INPUT ip  saddr 192.168.123.345 counter name os-traffic-4
add rule ip6 stats INPUT ip6 saddr 1234:1234:1234:1234:1234:1234:1234:1234 counter name os-traffic-6
add rule ip6 stats INPUT ip6 saddr 1234:1234:1234:1234:1234:1234:1234:2345 counter name os-traffic-6
add rule ip6 stats INPUT ip6 saddr 1234:1234:1234:1234:1234:1234:1234:3456 counter name os-traffic-6
# /var/lib/nftables.state

add counter stats os-traffic-4
add counter stats os-traffic-6
# /etc/systemd/system/nftables-persist-counters.service

[Unit]
BindsTo=nftables.service
After=nftables.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/true
ExecStop=/bin/bash -c '/usr/bin/nft list counters > /var/lib/nftables.state'

[Install]
WantedBy=multi-user.target

EDIT: The systemctl reload nftables.service command shall be blocked for the automatic counter storage to work. Therefore, deployment of an additional file is required:

# /etc/systemd/system/nftables.service.d/block-systemctl-reload.conf

[Service]
ExecReload=
  • Great idea using the state file. Really look forward to trying this out tonight, very much appreciate the effort here, thank you! – oucil May 26 '20 at 01:00