mirror of https://github.com/OISF/suricata
docs: sync up to recent redmine
parent
0e63c9ca41
commit
7806ae8f57
@ -0,0 +1,138 @@
|
||||
Hyperscan guide for Ubuntu
|
||||
==========================
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
"Hyperscan is a high-performance multiple regex matching library." https://01.org/hyperscan
|
||||
|
||||
In Suricata it can be used to perform multi pattern matching (mpm). Support was implemented by Justin Viiret and Jim Xu from Intel: https://github.com/inliniac/suricata/pull/1965, https://redmine.openinfosecfoundation.org/issues/1704
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
To use Suricata with Hyperscan support, install dependencies:
|
||||
|
||||
|
||||
::
|
||||
|
||||
|
||||
apt-get install cmake ragel
|
||||
|
||||
libboost headers
|
||||
----------------
|
||||
|
||||
Hyperscan needs the libboost headers from 1.58+.
|
||||
|
||||
On Ubuntu 15.10 or 16.04+, simply do:
|
||||
|
||||
|
||||
::
|
||||
|
||||
|
||||
apt-get install libboost-dev
|
||||
|
||||
|
||||
Trusty
|
||||
~~~~~~
|
||||
|
||||
Trusty has 1.57, so it's too old. We can grab a newer libboost version, but we *don't* install it system wide. It's only the headers we care about during compilation of Hyperscan.
|
||||
|
||||
|
||||
::
|
||||
|
||||
|
||||
sudo apt-get python-dev libbz2-dev
|
||||
wget http://downloads.sourceforge.net/project/boost/boost/1.60.0/boost_1_60_0.tar.gz
|
||||
tar xvzf boost_1_60_0.tar.gz
|
||||
cd boost_1_60_0
|
||||
./bootstrap.sh --prefix=~/tmp/boost-1.60
|
||||
./b2 install
|
||||
|
||||
Hyperscan
|
||||
---------
|
||||
|
||||
We'll install version 4.2.0.
|
||||
|
||||
|
||||
::
|
||||
|
||||
|
||||
git clone https://github.com/01org/hyperscan
|
||||
cd hyperscan
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DBUILD_STATIC_AND_SHARED=1 ../
|
||||
|
||||
If you have your own libboost headers, use this cmake line instead:
|
||||
|
||||
::
|
||||
|
||||
|
||||
cmake -DBUILD_STATIC_AND_SHARED=1 -DBOOST_ROOT=~/tmp/boost-1.60 ../
|
||||
|
||||
Finally, make and make install:
|
||||
|
||||
::
|
||||
|
||||
|
||||
make
|
||||
sudo make install
|
||||
|
||||
Compilation can take a long time, but it should in the end look something like this:
|
||||
|
||||
|
||||
::
|
||||
|
||||
|
||||
Install the project...
|
||||
-- Install configuration: "RELWITHDEBINFO"
|
||||
-- Installing: /usr/local/lib/pkgconfig/libhs.pc
|
||||
-- Up-to-date: /usr/local/include/hs/hs.h
|
||||
-- Up-to-date: /usr/local/include/hs/hs_common.h
|
||||
-- Up-to-date: /usr/local/include/hs/hs_compile.h
|
||||
-- Up-to-date: /usr/local/include/hs/hs_runtime.h
|
||||
-- Installing: /usr/local/lib/libhs_runtime.a
|
||||
-- Installing: /usr/local/lib/libhs_runtime.so.4.2.0
|
||||
-- Installing: /usr/local/lib/libhs_runtime.so.4.2
|
||||
-- Installing: /usr/local/lib/libhs_runtime.so
|
||||
-- Installing: /usr/local/lib/libhs.a
|
||||
-- Installing: /usr/local/lib/libhs.so.4.2.0
|
||||
-- Installing: /usr/local/lib/libhs.so.4.2
|
||||
-- Installing: /usr/local/lib/libhs.so
|
||||
|
||||
Note that you may have to add /usr/local/lib to your ld search path
|
||||
|
||||
|
||||
::
|
||||
|
||||
|
||||
echo "/usr/local/lib" | sudo tee --append /etc/ld.so.conf.d/usrlocal.conf
|
||||
sudo ldconfig
|
||||
|
||||
Suricata
|
||||
--------
|
||||
|
||||
Compilation
|
||||
~~~~~~~~~~~
|
||||
|
||||
Suricata's installation is now quite standard.
|
||||
|
||||
It's possible to pass --with-libhs-includes=/usr/local/include/hs/ --with-libhs-libraries=/usr/local/lib/, although by default this shouldn't be necessary. Suricata should pick up Hyperscan's pkg-config file automagically.
|
||||
|
||||
When Suricata's compilation succeeded, you should have:
|
||||
|
||||
::
|
||||
|
||||
|
||||
suricata --build-info|grep Hyperscan
|
||||
Hyperscan support: yes
|
||||
|
||||
|
||||
Using Hyperscan
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
To use the hyperscan support edit your suricata.yaml and change the mpm-algo value to 'hs'.
|
||||
|
||||
Alternatively, use this commandline option: --set mpm-algo=hs
|
@ -0,0 +1,80 @@
|
||||
Packet Capture
|
||||
==============
|
||||
|
||||
Load balancing
|
||||
--------------
|
||||
|
||||
To get the best performance, Suricata will need to run in 'workers' mode. This effectively means that there are multiple threads, each running a full packet pipeline and each receiving packets from the capture method. This means that we rely on the capture method to distribute the packets over the various threads. One critical aspect of this is that Suricata needs to get both sides of a flow in the same thread, in the correct order.
|
||||
|
||||
The AF_PACKET and PF_RING capture methods both have options to select the 'cluster-type'. These default to 'cluster_flow' which instructs the capture method to hash by flow (5 tuple). This hash is symmetric. Netmap does not have a cluster_flow mode built-in. It can be added separately by using the "'lb' tool":https://github.com/luigirizzo/netmap/tree/master/apps/lb
|
||||
|
||||
> **WARNING** Recent AF_PACKET changes have "broken":https://redmine.openinfosecfoundation.org/issues/1777 this symmetry. Work is under way to "address this":https://redmine.openinfosecfoundation.org/issues/1777#note-7, but for now stay on kernel <=4.2.
|
||||
|
||||
On multi-queue NICs, which is almost any modern NIC, RSS settings need to be considered.
|
||||
|
||||
|
||||
RSS
|
||||
---
|
||||
|
||||
Receive Side Scaling is a technique used by network cards to distribute incoming traffic over various queues on the NIC. This is meant to improve performance but it is important to realize that it was designed for normal traffic, not for the IDS packet capture scenario. RSS using a hash algorithm to distribute the incoming traffic over the various queues. This hash is normally *not* symmetrical. This means that when receiving both sides of a flow, each side may end up in a different queue. Sadly, when deploying Suricata, this is the common scenario when using span ports or taps.
|
||||
|
||||
The problem here is that by having both sides of the traffic in different queues, the order of processing of packets becomes unpredictable. Timing differences on the NIC, the driver, the kernel and in Suricata will lead to a high chance of packets coming in at a different order than on the wire. This is specifically about a mismatch between the two traffic directions. For example, Suricata tracks the TCP 3-way handshake. Due to this timing issue, the SYN/ACK may only be received by Suricata long after the client to server side has already started sending data. Suricata would see this traffic as invalid.
|
||||
|
||||
None of the supported capture methods like AF_PACKET, PF_RING or NETMAP can fix this problem for us. It would require buffering and packet reordering which is expensive.
|
||||
|
||||
To see how many queues are configured:
|
||||
|
||||
::
|
||||
|
||||
|
||||
$ ethtool -l ens2f1
|
||||
Channel parameters for ens2f1:
|
||||
Pre-set maximums:
|
||||
RX: 0
|
||||
TX: 0
|
||||
Other: 1
|
||||
Combined: 64
|
||||
Current hardware settings:
|
||||
RX: 0
|
||||
TX: 0
|
||||
Other: 1
|
||||
Combined: 8
|
||||
|
||||
Some NIC's allow you to set it into a symmetric mode. The Intel X(L)710 card can do this in theory, but the drivers aren't capable of enabling this yet (work is underway to try to address this). Another way to address is by setting a special "Random Secret Key" that will make the RSS symmetrical. See http://www.ndsl.kaist.edu/~kyoungsoo/papers/TR-symRSS.pdf (PDF).
|
||||
|
||||
In most scenario's however, the optimal solution is to reduce the number of RSS queues to 1:
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
|
||||
# Intel X710 with i40e driver:
|
||||
ethtool -L $DEV combined 1
|
||||
|
||||
Some drivers do not support setting the number of queues through ethtool. In some cases there is a module load time option. Read the driver docs for the specifics.
|
||||
|
||||
|
||||
Offloading
|
||||
----------
|
||||
|
||||
Network cards, drivers and the kernel itself have various techniques to speed up packet handling. Generally these will all have to be disabled.
|
||||
|
||||
LRO/GRO lead to merging various smaller packets into big 'super packets'. These will need to be disabled as they break the dsize keyword as well as TCP state tracking.
|
||||
|
||||
Checksum offloading can be left enabled on AF_PACKET and PF_RING, but needs to be disabled on PCAP, NETMAP and others.
|
||||
|
||||
|
||||
|
||||
Recommendations
|
||||
---------------
|
||||
|
||||
Read your drivers documentation! E.g. for i40e the ethtool change of RSS queues may lead to kernel panics if done wrong.
|
||||
|
||||
Generic: set RSS queues to 1 or make sure RSS hashing is symmetric. Disable NIC offloading.
|
||||
|
||||
AF_PACKET: 1 RSS queue and stay on kernel <=4.2 until futher notice. Exception: if RSS is symmetric cluster-type 'cluster_qm' can be used to bind Suricata to the RSS queues. Disable NIC offloading except the rx/tx csum.
|
||||
|
||||
PF_RING: 1 RSS queue and use cluster-type 'cluster_flow'. Disable NIC offloading except the rx/tx csum.
|
||||
|
||||
NETMAP: 1 RSS queue. There is no flow based load balancing built-in, but the 'lb' tool can be helpful. Another option is to use the 'autofp' runmode. Exception: if RSS is symmetric, load balancing is based on the RSS hash and multiple RSS queues can be used. Disable all NIC offloading.
|
Loading…
Reference in New Issue