问题场景
我们使用suricata来做流量分析,suricata部署在一台多网卡的48核心的物理机上,由于业务需要,suricata监听流量的网卡从5块提升为了6块,新加了网卡enp176s0f1,然后发现suricata的日志中有多条类似报错:
<Error> - [ERRCODE: SC_ERR_PF_RING_OPEN(34)] - Failed to open enp176s0f1: pfring_open error. Check if enp176s0f1 exists and pf_ring module is loaded.
分析
从日志看是由于pfring监听新网卡失败了,要不就是pfring的问题要不就是新网卡的问题。所以,为了缩小目标,需要先定位下是谁的问题。
排查
1,定位是pfring问题的方法: suricata监听配置中保留新加的网卡enp176s0f1,把suricata监听的6块网卡改成小于等于5块,suricata运行正常。 2,查看系统日志是否有异常,发现有pfring的提示信息
# dmesg -T
[Tue May 26 11:29:09 2020] [PF_RING] Exceeded the maximum number of list items
3,利用强大的搜索引擎开始搜索报错,发现和MAX_NUM_RING_SOCKETS变量有关系,于是就下载源码开始查这个变量和报错的相关代码。发现是监听ring的socket超过了256导致了报错。
# grep -n MAX_NUM_RING_SOCKETS * -r
kernel/linux/pf_ring.h:34:#define MAX_NUM_RING_SOCKETS 256
kernel/linux/pf_ring.h:344:#define MAX_NUM_LIST_ELEMENTS MAX_NUM_RING_SOCKETS /* sizeof(bits_set) [see below] */
kernel/linux/pf_ring.h:998:#define MAX_NUM_ZC_BOUND_SOCKETS MAX_NUM_RING_SOCKETS
# grep -n 'Exceeded the maximum number of list items' * -r
kernel/pf_ring.c:606: printk("[PF_RING] Exceeded the maximum number of list items\n");
# vim kernel/pf_ring.c +606
605 if(l->num_elements >= MAX_NUM_LIST_ELEMENTS) {
606 printk("[PF_RING] Exceeded the maximum number of list items\n");
607 return(-1); /* Too many */
608 }
4,我们suricata使用workers模式运行,所以每个线程处理所有逻辑(包含使用pfring抓包)。结合suricata的pfring监听网卡的相关配置,我们发现每块网卡的threads数是auto,默认auto就是使用cpu的核心数48作为线程数。所以,6块网卡suricata启动的线程数就是6*48=288,超过了256的限制,所以最后一块网卡pfring open失败了。
pfring:
- interface: enp175s0f0
threads: auto
cluster-id: 81
cluster-type: cluster_flow
- interface: enp175s0f1
threads: auto
cluster-id: 82
cluster-type: cluster_flow
- interface: enp24s0f1
threads: auto
cluster-id: 83
cluster-type: cluster_flow
- interface: enp24s0f0
threads: auto
cluster-id: 84
cluster-type: cluster_flow
- interface: enp176s0f1
threads: auto
cluster-id: 85
cluster-type: cluster_flow
- interface: enp134s0f1
threads: auto
cluster-id: 86
cluster-type: cluster_flow
解决
1,增大源码中MAX_NUM_RING_SOCKETS的value,然后重新制作rpm包 2,根据每块网卡流量大小,合理调整threads数。对应流向小的网卡,threads调整为8,流量大的网卡调整大点,所有网卡的threads数量不超过256即可。(建议)
参考
https://groups.google.com/forum/#!topic/security-onion/uiR9zSmu9Zc https://github.com/ntop/PF_RING