PF_RING Snort multiprocessing (Inline/Passive)

Tested on CentOS 6

We have modified PF_RING to work with inline Snort (while still supporting the current passive multiprocessing functionality). PF_RING load balances the traffic to analyze by hashing the IP headers in multiple buckets. This allows it to spawn multiple instances of Snort, each processing a single bucket and achieve higher throughput through multiprocessing. In order to take full advantage of this, you need a multicore processor (like an I7 with 8 processing threads). This should also work well with dual or quad processor boards to increase parallelism even further.

The big deal is that now you can build low-cost IDPS systems using standard off-the-shelf hardware.
Here is the system we have ported PF_RING inline to:

Intel(R) Core(TM) i7 CPU 950 @ 3.07GHz, Dual Intel e1000e, 4 Gig RAM
PF_RING e1000e driver, transparent_mode=1
Snort 2.9.0.x using the 6765 Emerging Threats Pro Rules

etpro perf 1Gbps PF Ring Inline

Snort 2.9.0.x using the 5267 VRT Rules

vrt perf 1Gbps PF Ring Inline

As the graph illustrates, inline with 1 core can only sustain 100 Mbit/s or less (that’s what people get today). With Pfring inline we parallelize the inline processing on up to 8 cores thus achieving almost 700 Mbit/s sustained. Performance numbers are greatly affected by the type and number of Snort rules used and the type of traffic being sent through. However, it appears that no matter what your setup is, pfring inline with 8 cores should achieve 700-800Mbps sustained throughput with an approximately 200 microsecond latency. That is impressive performance!

  1. Install the following packages with yum install –package–

kernel-devel
libtool
subversion
automake
make
autoconf
pcre-devel
libpcap-devel
flex
bison
byacc
gcc
zlib-devel
gcc-c++

2. Download and install libdnet. You can download it here

#Build the PF_RING inline libraries and kernel module:

#download our modified PF_RING source here

tar xvfz PF_RING.tgz
cd  PF_RING; make clean
cd kernel;
make clean; make; make install
cd ../userland/lib;
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib;
export LIBS='-L/usr/local/lib';
./configure;
make clean; make; make install
cd ../libpcap;
export LIBS='-L/usr/local/lib -lpfring -lpthread';
./configure;
make clean; make; make install;
make clean; make; make install-shared
ln -s /usr/local/lib/libpfring.so /usr/lib/libpfring.so

#Build the daq-0.6.2 libraries:
#download daq-0.6.2 here

tar xvfz daq-0.6.2.tgz
cd daq-0.6.2;
chmod 755 configure;
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib;
export LIBS="-L/usr/local/lib -lpcap -lpthread"
./configure --disable-nfq-module --disable-ipq-module \
--with-libpcap-includes=/usr/local/include \
--with-libpcap-libraries=/usr/local/lib \
--with-libpfring-includes=/usr/local/include/ \
--with-libpfring-libraries=/usr/local/lib
make clean; make; make install

#Go back to the PF_RING directory and build the daq interface module

cd  PF_RING/userland/snort/pfring-daq-module;
autoreconf -ivf;
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
export LIBS='-L/usr/local/lib -lpcap -lpfring -lpthread';
./configure; make; make install

# Build Snort 2.9.x #

cd snort-2.9.x;
make clean ;
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib;
export LIBS='-L/usr/local/lib -lpfring -lpthread'
./configure --with-libpcap-includes=/usr/local/includes \
--with-libpcap-libraries=/usr/local/lib \
--with-libpfring-includes=/usr/local/include/ \
--with-libpfring-libraries=/usr/local/lib \
--enable-zlib --enable-perfprofiling
make
make install

# Load PF_RING MODULE
####### ATTENTION #########
#The OS will try to load the pfring kernel module with default
#parameters anytime any application with pfring runs. The default parameters
#are wrong when running inline!!
#never run inline with tx_capture!!!!
#Therefore is always a good idea to remove pf_ring.ko and reload it with
the correct variable before running inline.

rmmod pf_ring.ko
insmod pf_ring.ko enable_tx_capture=0

# Run Snort
# Run as many instances as your system can handle limited only to value of \
CLUSTER_LEN in PF_RING/kernel/linux/pf_ring.h at compile time (and your memory).
#Remember to replace the interfaces with ones for your instance.

ifconfig eth0 up
ifconfig eth1 up
snort -c snort.serv.conf -A console -y -i eth0:eth1 \
--daq-dir /usr/local/lib/daq --daq pfring --daq-var clusterid=10 \
--daq-mode inline -Q

If you want even faster performance (about 20% more) and you have one of the Ethernet interfaces in PF_RING/drivers, you can run in transparent mode 1. We have only extensively tested the e1000e driver and we know it is very reliable.
To use transparent mode 1 with an e1000e interface:

cd PF_RING/drivers/PF_RING_aware/intel/e1000e/e1000e-1.3.10a/src;
make clean;
make;
make install

#Now you need to replace the e1000e module by either
#rebooting or removing the old one and reloading the new driver in
#/lib/modules/`uname -r`/kernel/drivers/net/e1000e/
#You also need to reload the pf_ring.ko module to enable transparent mode 1
#also increasing the buffer size for extra humf:

rmmod pf_ring.ko
insmod pf_ring.ko enable_tx_capture=0 transparent_mode=1 min_num_slots=16384

If you have any issues go to the metaflows google group for support.
————————————————————————————————————————————————————

FILES:
PF_RING.tgz
README
INFO.txt