This topic is about NIC hardware filtration which is too rarely covered in spite of its usefulness.
Well, for this challenge you should buy modern 10GE NIC (for example, you could use Intel 520, Intel 540, Intel XL710 or any NIC on chipset Intel 82599). I will use NIC with Intel 82599 chipset with ixgbe driver.
First of all, you should use the Intel drivers from SourceForge instead of drivers related to your Linux distribution. Because these drivers are not so functional.
We will use the ethtool for management of the NIC capabilities, please install it.
Let’s go!
We have to tune the NIC driver and enable the hardware filtration capability.
Open driver configuration file:
vim /etc/modprobe.d/ixgbe.conf
And type in the following text here:
FdirPballoc=3,3,3,3
After the reconfiguration, please, unload and upload the driver again:
rmmod ixgbe
modprobe ixgbe
ifconfig 11.22.33.44. eth4
Why do we set FdirPballoc to 3? That’s why we can select number of hardware filtering rules and we select the option with maximum number of rules:
1 = 8k hash filters or 2k perfect filters
2 = 16k hash filters or 4k perfect filters
3 = 32k hash filters or 8k perfect filters (array of int)
Look at dmesg and check the number of rules in the debug messages:
dmesg|grep 'Flow Director'
[45847.024851] ixgbe: Flow Director packet buffer allocation set to 3
[45847.024874] ixgbe: 0000:0a:00.0: ixgbe_check_options: Flow Director will be allocated 256kB of packet buffer
Enable the NIC hardware filtration support in runtime:
ethtool -K eth4 ntuple on
Due to the fact that many distros has outdated ethtool main pages I show the most important part for traffic filtration here:
ethtool --help:
ethtool -N|-U|--config-nfc|--config-ntuple DEVNAME Configure Rx network flow classification options or rules
rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r... |
flow-type ether|ip4|tcp4|udp4|sctp4|ah4|esp4
[ src %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]
[ dst %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]
[ proto %d [m %x] ]
[ src-ip %d.%d.%d.%d [m %d.%d.%d.%d] ]
[ dst-ip %d.%d.%d.%d [m %d.%d.%d.%d] ]
[ tos %d [m %x] ]
[ l4proto %d [m %x] ]
[ src-port %d [m %x] ]
[ dst-port %d [m %x] ]
[ spi %d [m %x] ]
[ vlan-etype %x [m %x] ]
[ vlan %x [m %x] ]
[ user-def %x [m %x] ]
[ action %d ]
[ loc %d]] |
delete %d
For purpose of testing I started DDoS attack with trafgen tool with the power of 8 Million packets per second (but this approach can mitigate attacks up to 14MPPS):
12:45:19.050037 IP 10.10.10.100.41356 > 10.10.10.200.61598: UDP, length 18
12:45:19.050045 IP 10.10.10.100.9967 > 10.10.10.200.24210: UDP, length 18
12:45:19.050052 IP 10.10.10.100.17254 > 10.10.10.200.44345: UDP, length 18
12:45:19.050061 IP 10.10.10.100.17516 > 10.10.10.200.41543: UDP, length 18
12:45:19.050069 IP 10.10.10.100.29307 > 10.10.10.200.60769: UDP, length 18
12:45:19.050078 IP 10.10.10.100.56313 > 10.10.10.200.49897: UDP, length 18
12:45:19.050085 IP 10.10.10.100.17761 > 10.10.10.200.6767: UDP, length 18
12:45:19.050093 IP 10.10.10.100.24303 > 10.10.10.200.12295: UDP, length 18
12:45:19.050101 IP 10.10.10.100.27105 > 10.10.10.200.52313: UDP, length 18
12:45:19.050109 IP 10.10.10.100.32141 > 10.10.10.200.55003: UDP, length 18
12:45:19.050119 IP 10.10.10.100.10274 > 10.10.10.200.11494: UDP, length 18
Look at the server loading. It’s very sad picture:( Our server is completely overloaded.
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 25.0 id, 0.0 wa, 0.0 hi, 75.0 si, 0.0 st
Let’s try to create a traffic filter against this attack (action “-1” means traffic drop):
ethtool --config-ntuple eth4 flow-type udp4 src-ip 10.10.10.100 m 255.255.255.0 action -1
Check rules list:
ethtool --show-ntuple eth4
4 RX rings are available
Total: 1 rule
Filter: 8189
Rule Type: UDP over IPv4
Src IP addr: 0.0.0.100 mask: 255.255.255.0
Dest IP addr: 0.0.0.0 mask: 255.255.255.255
TOS: 0x0 mask: 0xff
Src port: 0 mask: 0xffff
Dest port: 0 mask: 0xffff
VLAN EtherType: 0x0 mask: 0xffff
VLAN: 0x0 mask: 0xffff
User-defined: 0x0 mask: 0xffffffffffffffff
Action: Drop
How to remove hardware filtering rule in case of mistake?
ethtool --config-ntuple eth4 delete 8189
Look at top and check server loading:
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
It looks very nice, doesn’t it?
How we can check the number of packets rejected by this filter rule:
ethtool -S eth4 |grep fdir
fdir_match: 916143392
fdir_miss: 139427055
fdir_overflow: 0
As you can see, it’s very fast and straightforward way to mitigate attacks directed to channel overflow.
You can block DNS/SNMP/CHARGEN traffic amplification attacks with this approach. But you should keep in mind the restriction related to this approach. We can filter traffic only with protocols, ports and specific IP’s. If you need filtration by TCP flags or by packet length you should implement the complete firewall. For example, you could try: netmap-ipfw