背景
学习本文前你可能需要了解的背景知识:
Suricata 是一个高性能的开源网络入侵检测/防御系统(IDPS)和网络安全监控(NSM)引擎。它由社区驱动开发,支持实时入侵检测、入侵防御、网络安全监控和离线pcap处理等功能。Suricata 能够依靠其强大的可扩展性规则和特征语言来过滤网络流量,
DPDK(Data Plane Development Kit)是一个开源项目,由Linux基金会支持,旨在为数据平面应用提供快速的数据包处理架构。它通过创建环境抽象层(EAL)来为不同的工作环境提供函数库集,使得开发者可以将自己的应用与这些函数库进行链接。DPDK设计用于加速在各种CPU架构上运行的数据包处理工作负载。
DPDK适用于需要高性能网络数据包处理的场景,如网络功能虚拟化(NFV)、软件定义网络(SDN)和其他高性能网络应用。通过DPDK,开发者可以构建高效的网络应用,减少系统调用和上下文切换,实现接近硬件性能的数据包处理速度。
我们使用suricata时为什么要使用dpdk?
首先,如果运行suricata的机器在接入流量后,能够正常处理数据的情况下,可以不使用dpdk。但是如果你观察suricata的stats.log日志,发现其中的capture.kernel_drops参数不停上涨的话,就需要考虑是否使用dpdk了。
capture.kernel_drops不断增加,说明在处理数据时发生丢包,这个参数值作为分子,capture.kernel_packets参数作为分母,可以计算出当前的丢包率,如果丢包率高于10%,那我们无法保证IDPS的检测效果。
了解这些之后,你需要降低丢包率,这时引入高性能数据包处理工具dpdk就变得十分重要。这篇文章以我本地的环境为例,我的服务器网卡厂家是Mellanox(后被NVIDIA收购)
为什么这里专门要以Mellanox网卡为案例呢?因为使用Mellanox网卡有个好处是不需要折腾dpdk相关联的驱动,只需要把官方提供的驱动编译安装好就行了。(NVIDIA看到没有,快打钱!!)
首先查看网卡信息,第一列(如:3b:00.0)为设备的PCI地址,需要记下来后面会用到。这里可以看到网卡是Mellanox ConnectX-5系列,型号MT27800
# lspci | grep -i eth
3b:00.0 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5]
3b:00.1 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5]
5e:00.0 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5]
5e:00.1 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5]
得到上面的信息后,我们到dpdk官网上查看网卡是否支持dpdk。访问:https://core.dpdk.org/supported/nics/,可以看到dpdk支持mlx5即Mellanox ConnectX-5系列。(什么?你问我如果网卡不支持dpdk怎么办?那换块支持的网卡呗)
确定网卡支持dpdk后,我们到NVIDIA官方下载驱动程序,这是dpdk编译运行的必要依赖。链接:https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/?_gl=1*1ac15mp*_gcl_au*MzU5NjAwNjcyLjE3MTA4NTk0NTA.
推荐大家根据操作系统和运行环境,选择LTS版本,这里我选择ISO文件格式,例如:
文件下载并上传至服务器后,可以用mount命令挂载,安装
mkdir /media/cdrom0
mount xxx.iso /media/cdrom0
cd /media/cdrom0/
./mlnxofedinstall --upstream-libs --dpdk
/etc/init.d/openibd restart
安装完成后,我们下载20.11版本的dpdk,链接:https://fast.dpdk.org/rel/dpdk-20.11.10.tar.xz
下载完成后开始安装,这里开始重点就来了,我踩过的坑各位都有幸可以避免。
1、与官方文档快速指南不同,mlx5网卡不需要解绑、重绑网卡驱动即可直接使用dpdk
2、dpdk在编译时,旧版本需要修改配置文件以启用针对mlx5网卡的驱动模块编译支持,而在20.11版本的dpdk,已经不再使用make进行构建编译,取而代之的是meson和ninja,而且官方文档并没有说meson编译时如何修改配置以支持mlx5网卡。
整个编译过程如下:
sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
sed -i s@/security.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
apt-get update && apt-get install -y \
openssh-client \
autoconf \
automake \
build-essential \
git \
libpcre3 \
libpcre3-dbg \
libpcre3-dev \
libtool \
libpcap-dev \
libnet1-dev \
libyaml-0-2 \
libyaml-dev \
libmagic-dev \
libcap-ng-dev \
libjansson-dev \
pkg-config \
python3 \
python3-pip \
zlib1g \
zlib1g-dev \
libpcre2-dev \
rustc \
cargo \
liblz4-dev \
libnuma-dev \
libunwind-dev \
wget \
ca-certificates \
curl \
gnutls-bin \
linux-headers-$(uname -r)
python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ meson ninja pyelftools
tar xvf dpdk-20.11.10.tar.xz
cd dpdk-stable-20.11.10/
meson -Denable_kmods=true -Dexamples=all build
ninja -C build install
静静等待编译安装完成后,我们开始配置dpdk的运行环境。dpdk运行时需要系统分配大页内存。这里会用到dpdk的内置工具dpdk-hugepages.py
mkdir -p /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
/usr/bin/python3 /var/lib/suricata/dpdk-hugepages.py -p 1G --setup 2G
echo "vm.nr_hugepages=2048" >> /etc/sysctl.conf
sysctl -p
dpdk的部分告一段落,我们开始编译和部署suuricata
git clone https://github.com/OISF/suricata.git /opt/suricata-git
cd /opt/suricata-git
git clone https://github.com/OISF/libhtp
cargo install -f cbindgen --root /usr/
./autogen.sh && \
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-dpdk && \
make && \
make install-full && \
ldconfig
suricata编译完成后,我们修改suricata的配置文件,将网卡的pci地址写入配置文件中,例如:
dpdk:
eal-params:
proc-type: primary
interfaces:
- interface: 0000:5e:00.0
threads: auto
promisc: true
multicast: true
checksum-checks: false
checksum-checks-offload: false
mtu: 1500
mempool-size: 65535
mempool-cache-size: 257
rx-descriptors: 1024
tx-descriptors: 1024
copy-mode: none
copy-iface: none
interfaces:
- interface: 0000:5e:00.1
threads: auto
promisc: true
multicast: true
checksum-checks: false
checksum-checks-offload: false
mtu: 1500
mempool-size: 65535
mempool-cache-size: 257
rx-descriptors: 1024
tx-descriptors: 1024
copy-mode: none
copy-iface: none
最后启动suricata进行测试,无ERROR日志,证明一切配置顺利!
[13 - Suricata-Main] 2024-05-21 22:45:31 Notice: suricata: This is Suricata version 8.0.0-dev (856056465 2024-05-16) running in SYSTEM mode
[13 - Suricata-Main] 2024-05-21 22:45:31 Info: cpu: CPUs/cores online: 40
[13 - Suricata-Main] 2024-05-21 22:45:31 Info: suricata: Setting engine mode to IDS mode by default
[13 - Suricata-Main] 2024-05-21 22:45:31 Info: exception-policy: master exception-policy set to: auto
[13 - Suricata-Main] 2024-05-21 22:45:31 Info: suricata: Use pid file /var/lib/suricata/suricata.pid from config file.
[14 - Suricata-Main] 2024-05-21 22:45:31 Info: suricata: Preparing unexpected signal handling
[14 - Suricata-Main] 2024-05-21 22:45:31 Info: conf: Running in live mode, activating unix socket
[14 - Suricata-Main] 2024-05-21 22:45:31 Info: logopenfile: eve-log output device (regular) initialized: alert.json
[14 - Suricata-Main] 2024-05-21 22:45:31 Info: logopenfile: eve-log output device (regular) initialized: flow.json
[14 - Suricata-Main] 2024-05-21 22:45:31 Info: logopenfile: eve-log output device (regular) initialized: eve.json
[14 - Suricata-Main] 2024-05-21 22:45:31 Info: logopenfile: stats output device (regular) initialized: stats.log
[14 - Suricata-Main] 2024-05-21 22:45:31 Info: detect: 1 rule files processed. 24 rules successfully loaded, 0 rules failed, 0 rules skipped
[14 - Suricata-Main] 2024-05-21 22:45:31 Info: threshold-config: Threshold config parsed: 0 rule(s) found
[14 - Suricata-Main] 2024-05-21 22:45:31 Info: detect: 24 signatures processed. 0 are IP-only rules, 23 are inspecting packet payload, 1 inspect application layer, 0 are decoder event only
[14 - Suricata-Main] 2024-05-21 22:45:32 Notice: conf: unable to find interface default in DPDK config
[14 - Suricata-Main] 2024-05-21 22:45:32 Info: runmodes: 0000:5e:00.1: creating 30 threads
[93 - W#30-5e:00.1] 2024-05-21 22:45:36 Warning: dpdk: 0000:5e:00.1: NIC is on NUMA 0, 30 threads on different NUMA node(s)
[14 - Suricata-Main] 2024-05-21 22:45:36 Info: unix-manager: unix socket '/var/run/suricata/suricata-command.socket'
[14 - Suricata-Main] 2024-05-21 22:45:36 Info: unix-manager: created socket directory /var/run/suricata/
[14 - Suricata-Main] 2024-05-21 22:45:36 Notice: threads: Threads created -> W: 30 FM: 1 FR: 1 Engine started.
https://docs.suricata.io/en/latest/capture-hardware/dpdk.html
https://dperf.org/doc/html/compile-dpdk-19.11
https://dperf.org/doc/html/compile-dpdk-mellanox