Filtering Netflow/IPFix
AC-Hunter’s Active-Flow module knows how to process Netflow V9 packets, but not the IPFix or deprecated Netflow V5 formats. To keep these out of the Active-Flow module entirely, we can filter them with four firewall rules. The first handles incoming Netflow V5, the second handles incoming IPFix (and the 3rd and 4th filter the equivalent FORWARDED packets). While they wrap in this document, from the first “sudo” to the first “DROP” should be on one line, and similarly for the other commands.
sudo iptables -I INPUT -p udp --dport 2055 \! -f -m u32 --u32 "0>>22&0x3C@6&0xFFFF=0x0005" -j DROP sudo iptables -I INPUT -p udp --dport 2055 \! -f -m u32 --u32 "0>>22&0x3C@6&0xFFFF=0x000a" -j DROP sudo iptables -I FORWARD -p udp --dport 2055 \! -f -m u32 --u32 "0>>22&0x3C@6&0xFFFF=0x0005" -j DROP sudo iptables -I FORWARD -p udp --dport 2055 \! -f -m u32 --u32 "0>>22&0x3C@6&0xFFFF=0x000a" -j DROP
Here’s a breakdown of the first Netflow V5 command. You’re welcome to skip both breakdowns and go right to testing, below.
sudo iptables
Work with the internal Linux firewall:
-I INPUT
Put in a new rule at the top of the list that inspects incoming traffic to this system. Note that we put in both INPUT and FORWARD versions of the 2 base commands – this drops both packets headed directly to this system and packets being forwarded through this system.
-p udp --dport 2055
If this packet is a UDP packet with destination port 2055,
\! -f
and is not fragmented at all,
-m u32 --u32 "0>>22&0x3C@6&0xFFFF=0x0005"
and the first two bytes of the UDP payload are 00 and 05 (see below for more details):
-j DROP
If all of the above tests come back true, drop the packet (discard it, but don’t send back any error about it).
That u32 bit is cryptic, to put it charitably. 🙂 Here’s a breakdown of that part:
-m u32
Load the “u32” module, which allows us to create firewall rules that inspect specific locations in a packet without any programming.
--u32
Everything inside the following double-quotes is a series of steps to follow to first find, then compare, bytes in the packet to some value and only return “True” if those bytes match the value.
"0>>22&0x3C
Pull out the first 4 bytes of the IP header and turn it into a “Number of bytes in the IP header” value (by right shifting it 22 bits and throwing away all bits except 00111100).
@
Skip over that many bytes (20 for an IP header with no options, more if IP options included). This gets us over the IP header and into the UDP header.
6
Now that we’re in the UDP portion, grab bytes 6 and 7 (the last two bytes of the UDP header) and bytes 8 and 9 (the first 2 bytes of the payload). We grab 4 bytes because u32 wants to start with a block of 4 bytes.
&0xFFFF
Discard the top two bytes (from the UDP header) leaving just the first 2 bytes of the payload,
=0x0005"
and see if bytes 8 and 9 (the first two bytes in the UDP payload) equal 5 (meaning Netflow V5).
The second firewall rule is identical, except its final test is to see if the first two bytes of the UDP payload equal 10 (0x000a, meaning IPFix).
Testing
As soon as you press enter, the firewall will start looking for these packets and silently discarding them. To see how many packets have exactly matched both of these rules, run:
sudo iptables -L -nxv | egrep '(:2055|^Chain|^ *pkts)'
The output should include lines like:
0 0 DROP udp !f * * 0.0.0.0/0 0.0.0.0/0 udp dpt:2055 u32 "0x0>>0x16&0x3c@0x6&0xffff=0xa"
The numbers in the two left hand columns are the number of packets matched by this rule and the number of bytes matched by this rule, respectively. If you have incoming Netflow V5 and/or IPFix packets, the numbers on one or both rules should rise above 0.
1 131 DROP udp !f * * 0.0.0.0/0 0.0.0.0/0 udp dpt:2055 u32 "0x0>>0x16&0x3c@0x6&0xffff=0xa"
If you want to generate a few test packets to make sure the firewall rules are matching while you’re waiting for the switches/routers to be configured for Netflow V9, you can try the following shell commands. If you have ncat installed (part of the nmap package):
echo -e '\x00\x05' | ncat -u active.flow.ip.address 2055 echo -e '\x00\x0a' | ncat -u active.flow.ip.address 2055
The first simulates a Netflow V5 packet and the second simulates IPFix.
If you have standard netcat (nc) installed, you can use the following, but be aware that you may have to stop each one by hand with Ctrl-c:
echo -e '\x00\x05' | nc -u active.flow.ip.address 2055 echo -e '\x00\x0a' | nc -u active.flow.ip.address 2055
Reference
For more information on u32, please see the u32 blog:
http://www.stearns.org/doc/iptables-u32.current.html
Bill has authored numerous articles and tools for client use. He also serves as a content author and faculty member at the SANS Institute, teaching the Linux System Administration, Perimeter Protection, Securing Linux and Unix, and Intrusion Detection tracks. Bill’s background is in network and operating system security; he was the chief architect of one commercial and two open source firewalls and is an active contributor to multiple projects in the Linux development effort. Bill’s articles and tools can be found in online journals and at http://github.com/activecm/ and http://www.stearns.org.