Introduction
Starting with Linux kernel 3.3, there’s a new module called nfnetlink_acct.
This new feature added by Pablo Neira brings interesting accountig capabilities to Netfilter.
Pablo has made an extensive description of the feature in the commit.
System setup
We need to build a set of tools to get all that’s necessary:
- libmnl
- libnetfilter_acct
- nfacct
The build is the same for all projects:
git clone git://git.netfilter.org/PROJECT cd PROJECT autoreconf -i ./configure make sudo make install
nfacct
This command line tool is here to set up and interact with the accounting subsystem. To get the help you can use the man page or run:
# nfacct help nfacct v1.0.0: utility for the Netfilter extended accounting infrastructure Usage: nfacct command [parameters]... Commands: list [reset] List the accounting object table (and reset) add object-name Add new accounting object to table delete object-name Delete existing accounting object get object-name Get existing accounting object flush Flush accounting object table version Display version and disclaimer help Display this help message
Configuration
Objectives
Let’s have for objectives to get the following statistics:
- IPv6 data usage
- http on IPv6 usage
- https on IPv6 usage
- IPv4 data usage
- http on IPv4 usage
- https on IPv4 usage
Ulogd2 configuration
Let’s start by a simple output to XML. For that we will add the following stack:
stack=acct1:NFACCT,xml1:XML
and this one:
stack=acct1:NFACCT,gp1:GPRINT
nfacct setup
modprobe nfnetlink_acct
nfacct add ipv6 nfacct add http-ipv6 nfacct add https-ipv6 nfacct add ipv4 nfacct add http-ipv4 nfacct add https-ipv4
iptables setup
iptables -I INPUT -m nfacct --nfacct-name ipv4 iptables -I INPUT -p tcp --sport 80 -m nfacct --nfacct-name http-ipv4 iptables -I INPUT -p tcp --sport 443 -m nfacct --nfacct-name https-ipv4 iptables -I OUTPUT -m nfacct --nfacct-name ipv4 iptables -I OUTPUT -p tcp --dport 80 -m nfacct --nfacct-name http-ipv4 iptables -I OUTPUT -p tcp --dport 443 -m nfacct --nfacct-name https-ipv4
ip6tables setup
ip6tables -I INPUT -m nfacct --nfacct-name ipv6 ip6tables -I INPUT -p tcp --sport 80 -m nfacct --nfacct-name http-ipv6 ip6tables -I INPUT -p tcp --sport 443 -m nfacct --nfacct-name https-ipv6 ip6tables -I OUTPUT -m nfacct --nfacct-name ipv6 ip6tables -I OUTPUT -p tcp --dport 80 -m nfacct --nfacct-name http-ipv6 ip6tables -I OUTPUT -p tcp --dport 443 -m nfacct --nfacct-name https-ipv6
Starting the beast
Now we can start ulogd2:
ulogd2 -c /etc/ulogd.conf
In /var/log, we will have the following files:
- ulogd_gprint.log: display stats for each counter on one line
- ulogd-sum-14072012-224313.xml: XML dump
- ulogd.log: the daemon log file to look at in case of problem
Output examples
In the ulogd_gprint.log file, the ouput for a given timestamp is something like that:
timestamp=2012/07/14-22:48:17,sum.name=http-ipv6,sum.pkts=0,sum.bytes=0 timestamp=2012/07/14-22:48:17,sum.name=https-ipv6,sum.pkts=0,sum.bytes=0 timestamp=2012/07/14-22:48:17,sum.name=ipv4,sum.pkts=20563,sum.bytes=70 timestamp=2012/07/14-22:48:17,sum.name=http-ipv4,sum.pkts=0,sum.bytes=0 timestamp=2012/07/14-22:48:17,sum.name=https-ipv4,sum.pkts=16683,sum.bytes=44 timestamp=2012/07/14-22:48:17,sum.name=ipv6,sum.pkts=0,sum.bytes=0
The XML output is the following:
<obj><name>http-ipv6</name><pkts>00000000000000000000</pkts><bytes>00000000000000000000</bytes><hour>22</hour><min>43</min><sec>15</sec><wday>7</wday><day>14</day><month>7</month><year>2012</year></obj> <obj><name>https-ipv6</name><pkts>00000000000000000000</pkts><bytes>00000000000000000000</bytes><hour>22</hour><min>43</min><sec>15</sec><wday>7</wday><day>14</day><month>7</month><year>2012</year></obj> <obj><name>ipv4</name><pkts>00000000000000000052</pkts><bytes>00000000000000006291</bytes><hour>22</hour><min>43</min><sec>15</sec><wday>7</wday><day>14</day><month>7</month><year>2012</year></obj> <obj><name>http-ipv4</name><pkts>00000000000000000009</pkts><bytes>00000000000000000408</bytes><hour>22</hour><min>43</min><sec>15</sec><wday>7</wday><day>14</day><month>7</month><year>2012</year></obj> <obj><name>https-ipv4</name><pkts>00000000000000000031</pkts><bytes>00000000000000004041</bytes><hour>22</hour><min>43</min><sec>15</sec><wday>7</wday><day>14</day><month>7</month><year>2012</year></obj> <obj><name>ipv6</name><pkts>00000000000000000002</pkts><bytes>00000000000000000254</bytes><hour>22</hour><min>43</min><sec>15</sec><wday>7</wday><day>14</day><month>7</month><year>2012</year></obj>
Conclusion
nfacct and ulogd2 offers a easy and efficient way to gather network statistics. Some tools and glue are currently lacking to fill the data inside reporting tool but the log structure is clean and it should not be too difficult.
`automake –install-missing` and `libtoolize` are redundant, because `autoreconf -i` already takes care of that.
Thanks j.eng! I’ve fixed it in the page !
It could be interesting to feedback the protocol information from Suricata or a tool like nDPI to do the accounting.
Good idea, we could do this inside the database. Do we add an ulogd2 output to suricata ? 😉
Great blog! Could you give an example of per host accounting using nfacct, please.
Thanks. It looks it is an excellent question. I don’t see any easy way to do it but to define a counter per-host which is not really optimal in term of performance.