首页 / 资讯中心 / 文章详情

Snort 2.9 DAQ 2.0.7 编译与 afpacket 排错

Snort 2.9 DAQ 2.0.7 编译与 afpacket 排错 ★ FEATURED ARTICLE
简介DAQData Acquisition2.0.7 源码包面向 Snort 入侵检测系统的开发者与安全运维人员用于解决数据包采集层与具体网卡、捕获机制耦合的问题。它提供独立于网络接口和抓包后端的抽象接口使 Snort 可在物理网卡、虚拟设备、libpcap 及 PCAP 文件等数据源之间灵活切换适合研究 IDS 数据采集机制、进行插件适配或二次开发的中高级读者。压缩包共 74 个文件约 508KB以 23 个头文件和 16 个 C 源文件为主体前者给出 DAQ API 与公共数据结构后者实现模块操作、基础调度及各抓包后端适配另含 m4、am、in 等构建脚本、配置模板与说明文档便于在类 Unix 环境组织编译。已有 781 人学习。读者可获得完整的 DAQ 接口定义、模块实现范例与构建配置用于理解 Snort 采集抽象层的设计思路、排查编译依赖问题或作为自定义数据源模块的参考底稿。1. 把 daq-2.0.7.tar.gz 放回 Snort 2.9 的数据路径里某实验室一台旧抓包机跑 Snort 2.9原先用 pcap 模块流量一上来就丢包换 afpacket 后启动直接报找不到 DAQ 模块才回头翻出 daq-2.0.7.tar.gz。这个包是 Snort 2.x 的数据采集抽象层源码把 pcap、afpacket、nfq、ipq、dump 这些抓包后端统一成一套 APISnort 只认 DAQ 模块不直接绑网卡。它适合还在维护 Snort 2.9.x 的运维和安全分析人员尤其是想从 pcap 切到 afpacket、又不想重编整个 Snort 的人如果你已经在用 Snort 3数据采集层不是这一套别混用。2. DAQ 在 Snort 里到底管什么模块边界与选型理由2.1 数据路径网卡到检测引擎之间的那一层Snort 2.9 收包不是直接从网卡 read 到检测引擎。数据先由 DAQ 模块从内核或 libpcap 取出来整理成 DAQ 的 packet 结构再交给 Snort 的解码器和预处理器。DAQ 这一层解决的是“不同抓包方式接口不一样”的问题pcap 用 libpcap 的pcap_loopafpacket 用AF_PACKET加 mmap 环形缓冲nfq 走 netfilter 队列ipq 是更老的队列接口。Snort 只调用 DAQ 的daq_load_modules、daq_initialize、daq_acquire这一组函数模块名通过配置或命令行传入。这样分层的好处是换抓包后端不用改 Snort 源码坏处是路径上多了一层间接调用编译期依赖和运行期模块路径必须对齐。我见过最常见的翻车不是 Snort 规则写错而是 Snort 编译时链接了 A 路径的 libdaq运行的时候daq_dir指向 B 路径的模块结果--daq-list能列出来一启动就报Failed to find DAQ module。所以后面每一步都要确认“头文件、动态库、模块目录”三件事指向同一个 prefix。选型上pcap 模块兼容性最好虚拟网卡、普通物理网卡、BPF 过滤都能用但高包量下复制次数多单核容易打满afpacket 用 mmap 环形缓冲区减少一次内核到用户态的复制适合 1Gbps 以上、规则量中等的场景nfq 用于 IPS 模式和 netfilter 队列配合能做阻断但配置复杂队列长度和nfqueue参数没调好会直接丢包ipq 是旧接口新环境不建议碰dump 模块常用于回放和测试不从真实网卡收包。一个合格的选择顺序是先确认业务是 IDS 还是 IPSIDS 优先 afpacketIPS 且需要 iptables 联动再考虑 nfq临时验证用 pcap 或 dump。2.2 2.0.7 版本支持哪些模块怎么查DAQ 2.0.7 属于 Snort 2.9.x 时代常用的版本模块是否编进去取决于 configure 时依赖找没找到。常见模块有 pcap、afpacket、nfq、ipq、dump。pcap 依赖 libpcapafpacket 依赖 Linux 的AF_PACKET不需要额外库nfq 依赖 libnetfilter_queueipq 依赖 libipq 和 libdnet 一类旧库dump 通常默认参与构建。你在机器上可以先用daq-config或直接看模块目录确认不要凭记忆判断。# 先看系统里是否已经有 daq-config以及它报告的版本和编译参数 command -v daq-config daq-config --version daq-config --cflags --libs 2/dev/null # 再看模块目录里实际有哪些 .so模块名通常和文件名对应 ls -1 /usr/local/daq/lib/daq/ 2/dev/nulldaq-config存在说明某个 prefix 下装过 DAQ--cflags --libs输出的是编译 Snort 时要用的头文件和库路径。模块目录里的daq_pcap.so、daq_afpacket.so、daq_nfq.so才是运行期真正加载的文件文件名前缀daq_后面的部分就是--daq参数要写的模块名。如果目录为空要么没装模块要么装到了别的 prefix先用find / -name daq_afpacket.so 2/dev/null定位不要直接改 Snort 配置硬猜。2.3 为什么先编译 DAQ 再编译 SnortSnort 2.9 的 configure 会检测 libdaq 的头文件和库检测不到就退回内置的 pcap 支持或者直接关闭 DAQ 相关功能。先装 DAQ 再编 Snort能让 Snort 链接到你指定的版本避免系统包管理器里旧版 libdaq 抢先命中。反过来如果先编了 Snort后面再升级 DAQSnort 的二进制不会自动换链接运行时可能加载到不兼容的libdaq.so表现是启动时符号缺失或模块加载失败。我一般会把 DAQ 装到独立 prefix比如/usr/local/daq而不是直接塞进/usr/local。这样 Snort 编译时用--with-daq-includes/usr/local/daq/include、--with-daq-libraries/usr/local/daq/lib明确指向运行期再用config daq_dir指模块目录升级和回退都干净。代价是要多配一个ld.so.conf.d文件但比事后查“到底加载了哪个 libdaq”省事得多。3. 编译 daq-2.0.7依赖、configure 参数与安装路径3.1 依赖清单别只装运行库编译 DAQ 最容易缺的是开发包不是运行包。pcap 模块要pcap.hnfq 模块要libnetfilter_queue/libnetfilter_queue.hipq 相关要 dnet 头文件。只装libpcap不装libpcap-devconfigure 阶段就会报pcap.h not found然后 pcap 模块被静默跳过最后 Snort 启动才发现没有 pcap 可用。下面这张表按模块列依赖装的时候按需取舍但 pcap 和 afpacket 建议都保留。依赖用途不装的后果gcc、make编译工具链configure 直接失败libpcap-devpcap 模块无pcap.hpcap 模块不构建libdnet-dev部分旧模块和地址转换dnet 相关模块缺失libnetfilter-queue-devnfq 模块nfq 模块不构建IPS 队列不可用bison、flex部分解析代码生成编译中途报语法文件缺失以 apt 系为例安装命令如下。这里只装编译需要的开发包不装 Snort 本身。装完用dpkg -l | grep pcap或pkg-config --modversion libpcap确认版本别在没确认头文件路径的情况下直接 configure。sudo apt update sudo apt install -y gcc make bison flex \ libpcap-dev libdnet-dev libnetfilter-queue-dev \ pkg-config pkg-config --cflags --libs libpcappkg-config --cflags --libs libpcap会输出-I/usr/include和-lpcap一类结果如果报Package libpcap was not found说明开发包没装好或者PKG_CONFIG_PATH不对。libdnet-dev和libnetfilter-queue-dev不是每个环境都必须但如果你后面打算试 nfq先装好能少一次重编。bison 和 flex 只在部分代码生成路径用到缺了会在make阶段报错不是 configure 阶段。3.2 configure 参数把 pcap 路径和 prefix 写死解包后进目录configure 的关键是--prefix和两个库路径。--with-libpcap-includes指头文件目录--with-libpcap-libraries指libpcap.so所在目录。不同发行版路径可能是/usr/lib/x86_64-linux-gnu或/usr/lib64用pkg-config和ldconfig -p | grep pcap确认后再填不要照抄。tar -xzf daq-2.0.7.tar.gz cd daq-2.0.7 ./configure \ --prefix/usr/local/daq \ --with-libpcap-includes/usr/include \ --with-libpcap-libraries/usr/lib/x86_64-linux-gnu \ --with-libdnet-includes/usr/include \ --with-libdnet-libraries/usr/lib/x86_64-linux-gnu--prefix/usr/local/daq决定安装后的include、lib、lib/daq三个目录后面 Snort 编译和运行都围绕它。--with-libpcap-includes和--with-libpcap-libraries是告诉 configure 去哪里找 pcap避免它只搜默认路径然后判定 pcap 不可用。--with-libdnet-*只在你要保留 dnet 相关模块时需要找不到 dnet 就删掉这两行不要让它阻塞 pcap 和 afpacket。configure 结束前会打印模块汇总看到pcap和afpacket是yes再继续。3.3 编译安装与动态库注册configure 通过后make和make install一般不复杂但安装完必须让动态链接器找到/usr/local/daq/lib/libdaq.so。否则 Snort 编译时能过运行时却报error while loading shared libraries: libdaq.so.2: cannot open shared object file。这一步是血泪经验里重复率最高的。make -j$(nproc) sudo make install # 把 DAQ 的 lib 目录注册给动态链接器 echo /usr/local/daq/lib | sudo tee /etc/ld.so.conf.d/daq.conf sudo ldconfig ldconfig -p | grep libdaqmake -j$(nproc)用满 CPU 核数老机器上如果内存小把-j降到 2 或 4避免编译进程被 OOM 杀掉。make install会把模块装到/usr/local/daq/lib/daq把库装到/usr/local/daq/lib。ld.so.conf.d/daq.conf是告诉系统这个目录也要参与动态库缓存ldconfig -p | grep libdaq能列出libdaq.so才算注册成功。如果这一步没做后面 Snort 的--daq-list可能直接失败看起来像模块没编出来实际是库找不到。3.4 验证安装模块目录、版本和链接安装完别急着上 Snort先单独验证 DAQ 的模块目录和链接。ls看模块文件ldd看依赖有没有缺失daq-config看版本。三件事都过再进入 Snort 配置。这个顺序能把你从“Snort 报错”拉回到“DAQ 本身是否完整”排查范围小很多。ls -1 /usr/local/daq/lib/daq/ ldd /usr/local/daq/lib/daq/daq_afpacket.so 2/dev/null /usr/local/daq/bin/daq-config --version 2/dev/null || truels至少应看到daq_pcap.so和daq_afpacket.so如果只有daq_dump.so说明 pcap 依赖没找到回看 configure 汇总。ldd输出里出现not found就是运行期缺库按缺失的库名补开发包或运行包。daq-config --version能输出 2.0.7 说明安装路径正确如果命令不存在直接用模块目录和ldconfig的结果判断不要为了一个辅助脚本重装。4. 让 Snort 用上 DAQ模块选择、配置与抓包验证4.1 运行模式决定模块IDS 用 afpacketIPS 才碰 nfqSnort 2.9 的 DAQ 模块和运行模式要匹配。IDS 模式只检测不阻断afpacket 或 pcap 都行IPS 模式要丢包通常用 afpacket inline 或 nfq。config daq_mode写readonly还是inline要和命令行-Q以及模块能力对齐。afpacket 在 readonly 下就是收包在 inline 下配合-Q可以做阻断pcap 模块一般只做 readonly别硬配 inline。模块选择建议先用snort --daq-list看 Snort 编译时链接的 DAQ 能识别哪些模块再用--daq指定。--daq-list输出的是 Snort 视角的模块列表和/usr/local/daq/lib/daq目录不完全等价目录里有模块文件但 Snort 的daq_dir指错列表就会空。先让列表出来再谈抓包。4.2 snort.conf 里的三行配置daq、daq_dir、daq_modeSnort 2.9 的配置文件里DAQ 相关配置通常放在全局配置区。最少要写config daq指定模块config daq_dir指定模块目录config daq_mode指定模式。daq_var按模块传参数afpacket 常用buffer_size_mb。下面是一段最小配置路径按你的 prefix 改。# /etc/snort/snort.conf 中的 DAQ 段 config daq: afpacket config daq_dir: /usr/local/daq/lib/daq config daq_mode: readonly config daq_var: buffer_size_mb256config daq: afpacket告诉 Snort 加载 afpacket 模块名字必须和daq_afpacket.so对应。config daq_dir是模块搜索目录不是库目录别写成/usr/local/daq/lib。config daq_mode: readonly表示只收包不阻断IPS 才改inline并配合-Q。config daq_var: buffer_size_mb256把 afpacket 的环形缓冲调到 256MB具体上限受内存和网卡队列影响先给 128 或 256压测后再调。多个daq_var可以写多行但不同模块支持的 key 不一样写错 key 有的版本会静默忽略有的会直接报错。4.3 命令行覆盖--daq、--daq-var 与 -i 的配合配置文件写好后命令行还可以覆盖模块和参数。调试阶段我一般不在配置文件里写死先用命令行跑通再落配置。--daq afpacket指定模块--daq-var传参数-i指定网卡-A console把告警打到终端-k none关闭校验和检查避免测试流量因为网卡 offload 被误判。# 先测配置语法不真正抓包 sudo snort -c /etc/snort/snort.conf -T # 用 afpacket 前台抓包输出告警到控制台 sudo snort -c /etc/snort/snort.conf \ --daq afpacket \ --daq-var buffer_size_mb256 \ -i eth0 -A console -k none-T是配置测试模式会加载规则和 DAQ 配置但不抓包适合改完配置先跑一遍。--daq afpacket覆盖配置文件里的模块名--daq-var buffer_size_mb256覆盖或追加参数。-i eth0指定接口接口名用ip link确认别用旧脚本里的eth1。-A console只适合前台调试生产用-A fast或统一日志。-k none关闭校验和校验测试环境常用生产按实际 offload 情况决定。4.4 验证抓包tcpdump 对照与丢包计数Snort 启动成功不等于抓到包。用 tcpdump 在同一网卡抓同样的流量做对照再看 Snort 是否出告警。如果 tcpdump 有包、Snort 没告警先查 BPF 过滤和规则再查 DAQ 模块。afpacket 下还可以看接口统计的丢包计数确认是不是缓冲区不够。# 另开一个终端抓 10 个包做对照 sudo tcpdump -i eth0 -nn -c 10 # 看接口收包和丢包计数 ip -s link show eth0tcpdump -c 10抓满 10 个包退出用来确认网卡上有流量。ip -s link show eth0的 RX 段有 packets 和 droppeddropped 持续增长说明内核侧或环形缓冲在丢。注意 afpacket 的丢包不一定全记在接口 dropped 上还要结合 Snort 自己的统计输出。验证顺序是网卡有包、tcpdump 能抓、Snort 能加载模块、Snort 能出告警四步缺一不可。不要一上来就调规则先把数据路径打通。5. 避坑与排查五个从编译到抓包的血泪记录5.1 现象configure 报 pcap.h not foundpcap 模块被跳过现象是./configure输出里 pcap 检测失败最后模块汇总只有 dump没有 pcap。原因通常不是 libpcap 没装而是只装了运行库没装开发包或者头文件在非默认路径configure 没搜到。解决是先确认pkg-config --cflags libpcap有输出再显式把 include 和 lib 路径传给 configure。如果pkg-config也找不到装libpcap-dev后重新解包 configure不要在旧 build 目录里反复make clean缓存会干扰判断。pkg-config --cflags --libs libpcap ./configure --prefix/usr/local/daq \ --with-libpcap-includes/usr/include \ --with-libpcap-libraries/usr/lib/x86_64-linux-gnu参数里的 include 路径要包含pcap.h的父目录libraries 路径要包含libpcap.so。如果系统是 64 位库可能在/usr/lib/x86_64-linux-gnu不要想当然写/usr/lib。configure 汇总里看到 pcap 为 yes 再往下走否则后面 Snort 配 pcap 一定失败。5.2 现象Snort 启动报 Failed to find DAQ module “afpacket”现象是snort --daq-list可能为空或者启动时直接报找不到 afpacket 模块。原因有三个常见分支daq_dir指向了/usr/local/daq/lib而不是/usr/local/daq/lib/daqlibdaq.so没进ldconfigSnort 编译时链接的 DAQ 版本和运行期模块版本不一致。解决顺序是先ldconfig -p | grep libdaq再ls /usr/local/daq/lib/daq/daq_afpacket.so最后检查snort.conf里的daq_dir。config daq_dir: /usr/local/daq/lib/daq这一行只写目录不写文件名。如果ldconfig找不到 libdaq按第 3 章的ld.so.conf.d方法注册。如果模块文件存在但 Snort 仍找不到用ldd看daq_afpacket.so是否缺依赖缺什么补什么。不要用LD_LIBRARY_PATH长期兜底生产环境容易和别的库冲突注册到 ldconfig 更稳。5.3 现象afpacket 启动成功但一条告警都没有现象是 Snort 进程在跑tcpdump能看到流量Snort 控制台没有任何告警。原因可能是接口名写错、BPF 过滤把流量滤掉、规则没加载或者daq_mode和运行参数不匹配。解决先用-T确认规则加载再用tcpdump对照同一接口最后临时去掉-k none以外的过滤参数用-A console看启动日志里收包数。排查时重点看 Snort 启动摘要里的Packet Statistics如果收包数为 0问题在 DAQ 或接口如果收包数增长但没有告警问题在规则或 BPF。afpacket 在 readonly 下不需要-Q加了-Q反而可能进入 inline 初始化失败。配置文件和命令行同时写daq_mode时以命令行和实际模块能力为准别让两边打架。5.4 现象高流量下丢包接口 dropped 持续增长现象是压测时 Snort 收包数明显少于 tcpdumpip -s link的 dropped 一直涨。原因通常是 afpacket 环形缓冲太小、单实例处理不过来、网卡多队列没利用或者规则太重导致用户态消费慢。解决先调大buffer_size_mb再把 afpacket 的 fanout 或多实例分流安排上最后才去砍规则。不要一上来就换硬件先确认瓶颈在收包还是检测。sudo snort -c /etc/snort/snort.conf \ --daq afpacket \ --daq-var buffer_size_mb512 \ -i eth0 -A fast -Dbuffer_size_mb512不是越大越好要留内存给规则和系统老机器先试 256。-D后台运行日志走-l指定目录。调大缓冲后如果 dropped 还涨看 CPU 单核是否打满afpacket 单实例通常吃一个核多队列要靠多实例或内核分流。规则侧用-T看加载耗时规则太多先关掉低优先级规则组做对照。5.5 现象升级 DAQ 后 Snort 报符号未定义或启动崩溃现象是换了 DAQ 版本后 Snort 启动报undefined symbol或直接段错误。原因是 Snort 二进制编译时链接的 libdaq 版本和运行期加载的 libdaq 不是同一个 ABI或者旧版 Snort 不认识新模块参数。解决是回到 Snort 源码重新 configure明确--with-daq-includes和--with-daq-libraries指向当前 prefix然后重编 Snort不要只换 libdaq 不重编 Snort。ldd $(command -v snort) | grep libdaqldd看 Snort 实际链接的 libdaq 路径如果指向/usr/lib而不是/usr/local/daq/lib说明编译时没指对。重新 configure Snort 时把 DAQ 路径写死编完再ldd确认。版本搭配上2.0.7 配 Snort 2.9.x 是常见组合不要拿它去配 Snort 3 的数据采集层接口不是一套。6. 进阶afpacket 调优后的验证习惯afpacket 调优不是把buffer_size_mb改大就结束。我通常做三组对照默认参数跑 10 分钟记录ip -s link的 dropped把 buffer 调到 256MB 再跑 10 分钟如果还丢再开多实例或 fanout观察每个实例的收包是否均衡。验证时不要只看 Snort 控制台控制台只反映告警不反映内核丢包。下面这段检查脚本用于压测时每 2 秒采样一次接口计数跑 5 次看 dropped 是否线性增长。#!/bin/bash # 压测期间采样接口收包/丢包计数观察 dropped 是否持续增长 for i in $(seq 1 5); do ip -s link show eth0 | awk /RX:/{getline; print rx_packets $2, rx_dropped $4} sleep 2 doneawk里取的是ip -s link输出 RX 段的第二行字段位置在不同版本可能略有差异先手动跑一次ip -s link show eth0对一下列。rx_dropped持续增长说明内核侧或环形缓冲在丢不是规则误判。对照tcpdump -c和 Snort 启动摘要里的收包数三者差距大就从 DAQ 参数查差距小但告警少就从规则查。另一个常被忽略的点是网卡多队列和 CPU 绑核。afpacket 单实例通常跟一个收包线程网卡多队列开了但 Snort 只用一个实例等于只用一个队列。常见做法是按队列数起多个 Snort 实例每个实例绑不同 CPU日志分目录再用统一规则集。部署前先用ethtool -l eth0看队列数用taskset绑核压测十分钟看每个实例的收包是否接近。参数上fanout_typehash能让同一流落到同一实例减少流重组错乱fanout_flagrollover在实例故障时把流量转到其他实例但具体支持情况以--daq-var debug的日志为准不要在不确认的情况下直接上生产。从那以后我每次把 DAQ 推到新环境都强制先跑snort --daq-list、snort -T、十分钟压测三件事再看丢包计数不再凭“进程还活着”判断抓包正常。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站