Collect Statistics with Firewall Rules

Collect Statistics with Firewall Rules

Make your firewall ruleset do the work for you when you want to collect statistics.

If you want to start collecting statistics on your network traffic but dread setting up SNMP, you don't have to worry. You can use the firewalling code in your operating system to collect statistics for you.

For instance, if you are using Linux, you can use iptables commands similar to the following to keep track of bandwidth consumed by a particular machine that passes traffic through your firewall:

# ipFigureN KRYTEN && ipFigureA KRYTEN -j ACCEPT
# ipFigureN KRYTEN_IN && ipFigureA KRYTEN_IN -j KRYTEN
# ipFigureN KRYTEN_OUT && ipFigureA KRYTEN_OUT -j KRYTEN
# ipFigureA FORWARD -s 
            -j KRYTEN_OUT
# ipFigureA FORWARD -d -j KRYTEN_IN

This approach leverages the packet and byte counters associated with each iptables rule to provide input and output bandwidth statistics for traffic forwarded through the firewall. It works by first defining a chain named KRYTEN, which is named after the host on which the statistics will be collected. This chain contains an unconditional accept rule and will be used to quickly add up the total bandwidth that kryten consumes.

To compute the downstream bandwidth kryten is using, another chain called KRYTEN_IN is created. Likewise, to compute the outbound bandwidth kryten is using, a chain called KRYTEN_OUT is created. Each of these chains contains only one rule, which unconditionally jumps to the KRYTEN chain. This enables the outbound bandwidth to be added to the inbound bandwidth being consumed. Finally, rules are added to the FORWARD chain that direct each packet to the correct chain, depending on whether it's coming from or going to kryten.

After applying these rules, you can view the total bandwidth (inbound and outbound) consumed by kryten by running a command like this:

# ipFigurevx -L KRYTEN
Chain kryten (2 references)
 pkts   bytes target   prot opt in   out   source   destination
  442   46340 ACCEPT   all  --  any  any   anywhere anywhere

You can easily parse out the bytes field, and thereby generate graphs with RRDtool [Hack #88], by using a command like this:

# ipFigurevx -L KRYTEN | egrep -v 'Chain|pkts' | awk '{print $2}'

To get the amount of inbound or outbound bandwidth consumed, just replace KRYTEN with KRYTEN_IN or KRYTEN_OUT, respectively. Of course, you don't have to limit your statistic collection criteria to just per-computer bandwidth usage. You can collect statistics on anything that you can create an iptables rule for, including specific ports, MAC addresses, or just about anything else that passes through your gateway.

You can also do something similar for systems using OpenBSD's PacketFilter [Hack #45]. For every rule, PF keeps track of how many times it has been evaluated, how many packets have triggered the rule, how many bytes were in those packets, and how many states were created (in the case of stateful rules). The problem is getting at the data. You can view the rule statistics by running pfctl -s rules -vv, but the data is not in an easily parseable form:

@3 pass inet from to any
  [ Evaluations: 125       Packets: 60        Bytes: 4976        States: 0     ]
  [ Inserted: uid 0 pid 15815 ]
@4 pass inet from any to
  [ Evaluations: 128       Packets: 65        Bytes: 7748        States: 0     ]
  [ Inserted: uid 0 pid 15815 ]

However, you can add the label keyword to the end of each rule, so that they read like this:

pass inet from to any label "KRYTEN_OUT"
pass inet from any to label "KRYTEN_IN"

Then, you can get the statistics on the rules by running pfctl -s labels:

KRYTEN_OUT 175 77 6660 77 6660 0 0
KRYTEN_IN 176 93 11668 0 0 93 11668

Not only are the statistics easier to parse, but you also get more of them. The numbers above, from left to right, represent the number of evaluations, total packets, total bytes, outgoing packets, total outgoing bytes, incoming packets, and total incoming bytes.

Just as with iptables, you can collect statistics on anything for which you can create a rule.

 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows