当前位置: 首页 > news >正文

【安全】audispd调研

audispd调研

1 问题背景

在Linux中,当某个进程调用audit_set_pid将自己的pid保存到内核的audit模块后,如果有日志生成,kaudit内核线程就会通过netlink通信机制将审计日志发送给audit_pid,因此,只能有一个进程占用audit并接收audit日志,那如果有另一个进程已经占用audit呢?例如,auditd或者其他组件。

一种方式是可以将选择权交给用户,用户可以看到当前占用audit的进程,然后再决定是否将已经占用audit的进程杀死,然后进行占用。另一种方式是,如果用户已经在使用auditd接收日志,是否有一种方式可以让auditd在运行的同时我们也能够接收和处理日志呢?这种场景下就可以使用audispd。

2 audispd

audispd是作为auditd的子进程运行,而audispd会开启一些插件用于接收审计日志,例如,syslog或者sedispatch等,也就是说,日志转发路径变成了:

kauditd -> auditd -> audispd -> af_unix/syslog/sedispatch

下面逐个看下配置文件。

auditd.conf:

local_events = yes
write_logs = yes // 将日志写入磁盘
log_file = /var/log/audit/audit.log
log_group = root
log_format = RAW
flush = INCREMENTAL_ASYNC // 刷新模式,当前为异步增量刷新模式
freq = 50 // 接收到多少条日志后就写入磁盘
max_log_file = 8 // 日志文件大小,8MB
num_logs = 5 // 最大文件个数
priority_boost = 4 //
disp_qos = lossy
dispatcher = /sbin/audispd // 将审计日志转发的目的进程的文件名

以上是auditd.conf中的部分配置项,除了控制auditd写入日志文件的配置项,还有与日志转发相关的两个配置项:dispatcher,disp_qos,其中,dispatcher是负责日志转发的组件,auditd在启动后会拉起该程序,然后将收到的日志转发给该程序,该程序可以从标准输入读取审计日志,disp_qos则是控制当审计日志太多时auditd和dispatcher之间的行为,auditd和dispatcher之间有一个128K的队列,当队列满时,日志会被丢弃(lossy)或者auditd会等待队列有空间可以放入(lossless)。

audispd.conf:

q_depth = 250 // 队列深度
overflow_action = SYSLOG // 当内部队列满时的行为,当前值表示会写入一条syslog的日志
priority_boost = 4 //
max_restarts = 10 // 重启插件的最大次数
name_format = HOSTNAME // 节点信息如何插入日志中,当前值表示会将HOSTNAME写入到日志中
plugin_dir = /etc/audisp/plugins.d/ // 插件的路径

在plugin_dir目录下存放的就是插件的配置,每个配置项告诉audispd应该如何转发日志,例如,af_unix.conf:

active = no // 是否启用,yes/no
direction = out //
path = builtin_af_unix // 插件二进制的绝对路径,对于内部插件,就是插件的名称,内部插件有af_unix和syslog
type = builtin // 类型,builtin/always
args = 0640 /var/run/audispd_events // 参数
format = string // 格式,binary/string

从插件类型看,总共有三种类型:

内部插件的af_unix:audispd将审计日志发送给unix套接字
内部插件的syslog:audispd将审计日志发送给syslog
外部插件:audispd将审计日志发送给某个程序的标准输入

从上面对几个配置文件进行分析可以发现,auditd和audispd只是作为审计日志转发的中间组件,并且使用队列作为中间缓冲,而对于内核的日志发送者来说,日志的接收者只有auditd。

从几个组件的启动方来看,auditd负责拉起audispd,audispd负责拉起always类型的插件。

因此,如果在某些场景下希望与auditd同时运行,且获取审计日志,可以使用audispd的af_unix插件,但是可能存在其他问题:

  • 规则是全局的,多个程序都只设置自己的规则,每个程序都会收到所有的数据
  • 对于新增af_unix插件的操作,如果插件的目录是默认的,当然没有问题,如果是其他路径,可能无法获取到插件目录
  • audispd增加新的af_unix插件后,需要重启auditd才能生效,如果agent启动一段时间后出现问题退出就会导致频繁kill auditd,会造成启动失败
  • 如果其他非auditd程序正在使用audit,那就无法使用audispd
  • 如果audispd没有启动,可能是由于启动异常,也可能是由于没有需要启动的插件,如何区分

3 高版本中的audispd

如何查看auditd的版本号?auditd自身没有提供查看版本号的选项,只能通过日志或者包管理工具查看auditd的版本号。

CentOS中,在/var/log/messages中会打印auditd的版本号,也可以通过rpm -qi audit查看版本号。对于ubuntu类,在/var/log/kern.log中没看到auditd的版本号,但是可以通过dpkg -l | grep auditd查看版本号。

audit-userspace仓库的标签最早只有2.7.4,这个版本已经有audispd,而从3.0.0开始audispd作为auditd的一个线程工作,因此,auditd就包含了audispd原有的能力。

4 audispd引入的性能问题

由于使用audispd进行日志中转,在中转过程中引入了两个队列:

  • auditd和audispd之间有一个128K的缓存队列,disp_qos用于控制缓存队列满的行为
  • audispd内部会维护一个队列,q_depth用于控制队列的长度

测试环境:

  • CentOS 7.5(3.10.0-1160.102.1.el7.x86_64)
  • 4C8G
  • audit: backlog_limit=8192

只启动auditd,audispd没有配置插件:

是否丢弃日志可以通过查看auditctl -s中的lost或者/var/log/messages日志文件。

事件量级(eps)是否丢弃日志系统CPU
1000NO1.3%
5000NO5%
6000NO6%
7000NO7%
8000YES8%
9000YES10%
10000YES10%

启动auditd,audispd开启af_unix插件并使用socat命令接收审计日志:

使用socat - UNIX-CONNECT:/var/run/audispd_events命令接收审计日志,是否丢弃日志可以查看/var/log/messages中的dispatch err (pipe full) event lost日志。

事件量级(eps)q_depth是否丢弃日志系统CPU备注
50080NO2%
500250NO2%
5005000NO2%
100080YES4%
1000250YES4%
10005000YES4%用例执行3分钟开始丢弃日志

不启动auditd,使用其他程序占用并接收审计日志:

#include <stdio.h>
#include <libaudit.h>
#include <errno.h>int main() {pid_t pid = getpid();printf("current pid=%d\n", pid);int fd = audit_open();int ret = 0;ret = audit_set_pid(fd, pid, WAIT_YES);if(ret<0) {perror("audit set_pid failed: ");}ret = audit_set_backlog_limit(fd, 8192);if(ret<0) {perror("audit_set_backlog_limit failed: ");}struct audit_reply audit_rep;struct sockaddr_nl local_addr;memset(&local_addr, 0, sizeof(local_addr));local_addr.nl_family = AF_NETLINK;do {fd_set read_mask;FD_ZERO(&read_mask);FD_SET(fd, &read_mask);ret = select(fd + 1, &read_mask, NULL, NULL, NULL);if(ret < 0 ) {break;}ret = audit_get_reply(fd, &audit_rep,GET_REPLY_NONBLOCKING, 0);audit_rep.msg.data[audit_rep.len] = '\0';printf("recv audit msg: %s\n", audit_rep.msg.data);} while(1);audit_close(fd);
}

如果保留上面的代码中的printf语句,事件量级只能到1000eps,2000eps就开始丢弃日志;如果将printf语句注释,事件量级则可以到9000eps。

从上面的测试结果可以得出以下结论:

  • auditd和audispd之间的队列对目标程序接收审计日志的影响很大,完全限制了处理的审计日志量级
  • audispd内部的q_depth参数对审计日志量级影响不大,测试时可以忽略
  • 性能排序:直接读取审计日志并快速处理 > 启动auditd但不启动audispd > 启动audispd转发日志

5 audispd源码解析

auditd中与audispd相关的逻辑有两个地方:

  • audispd的拉起
  • auditd接收审计日志并将审计日志发送给audispd

在auditd的main函数中,会调用init_dispatcher()拉起dispatcher,也就是audispd。

init_dispatcher()会干下面三件事:

  • 使用socketpair创建两个socket保存到disp_pipe
  • 根据qos选项设置socket的O_NONBLOCK:如果qos设置为lossy,则将disp_pipe中的socket设置为O_NONBLOCK,否则就不设置
  • 使用fork和execl在子进程启动dispatcher,并且在执行execl之前将disp_pipe[0]设置到stdin上,这样dispatcher的stdin就是disp_pipe[0]

拉起audispd后,会执行audit_set_pid占用audit,然后设置audit fd的事件处理函数netlink_handler。在netlink_handler中会调用audit_get_reply读取数据,在收到审计日志后调用distribute_event进行事件的分发。distribute_event调用dispatch_event发送审计日志,并且调用handle_event将日志写入到本地磁盘。

dispatch_event()调用writev将数据写入到dispatcher,由于disp_pipe[0]对应的是dispatcher的stdin,因此,调用writev将数据写入disp_pipe[1]时,dispatcher就可以收到数据,在多次尝试后失败就会进行错误处理,此处有三种情况:

  • 如果错误码是EAGAIN并且是第一次调用dispatch_event,则直接返回,因此,可以在第二次再次调用
  • 如果失败数量少于REPORT_LIMIT,则打印dispatch err () event lost的错误信息
  • 如果失败数量到达REPORT_LIMIT,则打印dispatch error reporting limit reached - ending report notification.

打印错误信息后,如果失败数量继续增加则不会继续打印,除非某次发送数据成功,错误计数器清0,重新开始计算。

在audispd中,会调用audit_fd=dup(0)得到用于接收数据的文件描述符,再读取plugins.d目录下的插件,然后启动各个插件,接下来就是注册事件回调和事件处理:

  • add_event()注册audit_fd的POLLIN事件,以及事件的回调函数process_inbound_event
  • 创建子线程inbound_thread_main,在子线程中调用poll()判断是否有fd可读,然后调用对应的fd的回调函数,对于audit_fd来说,就会调用process_inbound_event
  • process_inbound_event()调用readv读取数据,然后将数据放到队列中
  • main()中的event_loop()从队列中读取数据,然后遍历所有的插件,根据插件类型调用不同的发送函数:如果是syslog,则调用send_syslog发送;如果是af_unix,则调用send_af_unix发送;如果是always,则调用wirte_to_plugin发送

从代码中只看到audispd中队列的处理,先将事件放到队列中,然后再从队列中读,对于auditd和audispd之间的缓冲应该是依赖socketpair创建的socket的缓冲区,但是,socket的缓冲区大小是由系统配置决定的,而且auditd的代码中也没看到调用setsockopt设置缓冲区大小的代码。

6 结论

audispd能够将auditd收到的日志转发出来供多个程序使用,也让其他程序能够得以与auditd同时运行,但是,使用该方式需要解决auditd的启停问题以及audispd带来的性能损耗问题,因此,如果直接使用audit接收日志不会引起其他的问题,建议还是直接使用占用audit的方式。

相关文章:

【安全】audispd调研

audispd调研 1 问题背景 在Linux中&#xff0c;当某个进程调用audit_set_pid将自己的pid保存到内核的audit模块后&#xff0c;如果有日志生成&#xff0c;kaudit内核线程就会通过netlink通信机制将审计日志发送给audit_pid&#xff0c;因此&#xff0c;只能有一个进程占用aud…...

WINDOWS(WIN11)通过IP添加网络打印机

点击添加设备 点击手动添加 使用IP地址或主机名添加打印机 选择TCP/IP设备&#xff0c;输入打印机地址 如果有正确驱动就安装&#xff0c;没有就取消。 通过手动设置添加本地打印机或网络打印机 使用现有的端口 根据打印机IP&#xff0c;选择标准端口。 成功&#xff01; 到…...

华为数通试题

选择题 华为数通推出的面向企业的云计算平台是&#xff1f; A) FusionSphere B) CloudEngine C) Agile Controller D) eSight 下面哪个不是华为数通的核心交换机系列&#xff1f; A) S12700 B) S5700 C) S9300 D) CloudEngine 华为数通的企业级路由器系列包括哪个&#xff1f…...

Labview Vision 机器视觉使用,从下载程序安装应用,到实战找硬币并输出值

1.前言 大家好,今天我要和机器人一起配合来打算 做机器视觉 用Labview 和 Vision 联动实现机器的视觉 2.下载软件-软件的安装 我们除了基础款的labview软件 还要安装视觉四件套 1.Labview 编程平台&#xff08;我是 2023 q3&#xff09; 2. NI - IMAQdx &#xff08;驱动软…...

【delphi11】delphi基础探索【三、基础组件和事件】

目录 基础组件 1. TButton&#xff08;按钮&#xff09; 2. TLabel&#xff08;标签&#xff09; 3. TEdit&#xff08;编辑框&#xff09; 4. TMemo&#xff08;多行编辑框&#xff09; 5. TComboBox&#xff08;组合框&#xff09; 6. TCheckBox&#xff08;复选框&…...

react hooks浅谈

一.useEffect useEffect是hooks中的生命周期函数 1.只要页面更新就触发回调&#xff1a; useEffect(() > { // 执行逻辑 }) 2.只运行一次&#xff08;组件挂载和卸载时执行&#xff09;&#xff0c;第二个参数传空数组[]&#xff1a; useEffect(() > { // },[]) 3. 条件…...

stable diffusion webui之lora调用

1.触发词底模lora效果最好&#xff08;分数不一定要取到1&#xff0c;0.8也行&#xff09;&#xff1b; 2.引用时一定要使用<lora:>&#xff0c;例如<lora:C4D_geometry_bg_v2.5:0.8>&#xff1b; "prompt": "(masterpiece:1.3), (best quality:1.…...

FormData文件上传多文件上传

一、简介 ​ 通常情况下&#xff0c;前端在使用post请求提交数据的时候&#xff0c;请求都是采用application/json 或 application/x-www-form-urlencoded编码类型&#xff0c;分别是借助JSON字符串来传递参数或者keyvalue格式字符串&#xff08;多参数通过&进行连接&#…...

八股文打卡day4——计算机网络(4)

TCP和UDP的概念、特点、区别和对应的使用场景&#xff1f; 我的回答&#xff1a; 概念&#xff1a; TCP是传输控制协议&#xff0c;是面向连接、可靠的、基于字节流的传输层通信协议。 UDP是用户数据报协议&#xff0c;是无连接、不可靠的&#xff0c;基于数据报的传输层通信…...

TensorFlow(2):Windows安装TensorFlow

1 安装python环境 这一步请自行安装&#xff0c;这边不做介绍。 2 安装anaconda 下载路径&#xff1a;Index of /&#xff0c;用户自行选择自己的需要的版本。 3 环境配置 3.1 anaconda环境配置 找到设置&#xff0c;点击系统->系统信息->高级系统设置->环境变量…...

一文解决idea导入源码控制台爆红问题

文章目录 唠嗑部分背景说明idea查看maven配置 言归正传安装mavenidea配置maven 结语及资料获取 唠嗑部分 背景说明 很多新手伙伴们在导入项目源码时&#xff0c;都会遇到大片依赖爆红&#xff0c;项目跑不起来&#xff0c;小白也是把自己电脑重新配置了一番&#xff0c;复现了…...

排序算法——快排

快速排序算法最早是由图灵奖获得者Tony Hoare设计出来的,他在形式化方法理论以 及ALGOL.60编程语言的发明中都有卓越的贡献,是20世纪最伟大的计算机科学家之—。 而这快速排序算法只是他众多贡献中的—个小发明而已。 快速排序&#xff08;Quick Sort&#xff09;的基本算法思…...

第二节TypeScript 基础语法

1、typescript程序由以下几个部分组成&#xff1a; 模块函数变量语句和表达式注释 2、开始第一个typescript程序 创建一个typescript程序&#xff0c;使之输出“hello typescript”&#xff1a; 代码&#xff1a; var message:string "hello typescript" cons…...

Go、Python、Java、JavaScript等语言的求余(取模)计算

余数符号规则&#xff1a; Go&#xff08;%&#xff09;&#xff1a; 余数与被除数符号一致 Java&#xff08;%&#xff09;&#xff1a; 余数与被除数符号一致 JavaScript&#xff08;%&#xff09;&#xff1a; 余数与被除数符号一致 Python&#xff08;%&#xff09;…...

scrapy快加构造并发送请求

scrapy数据建模与请求 学习目标&#xff1a; 应用 在scrapy项目中进行建模应用 构造Request对象&#xff0c;并发送请求应用 利用meta参数在不同的解析函数中传递数据 1. 数据建模 通常在做项目的过程中&#xff0c;在items.py中进行数据建模 1.1 为什么建模 定义item即提前…...

【C++】谈谈深拷贝与浅拷贝

目录 一、浅拷贝 1.定义 2.示例 3.问题 二、深拷贝 1.定义 2.示例 3.优点 三、考虑场景 浅拷贝的考虑 1.性能要求 2.简单地数据结构 3.资源管理 深拷贝的考虑 1.动态内存分配 2.复杂数据结构 3.资源管理 总结 一、浅拷贝 1.定义 浅拷贝是指对对象进行复制时…...

电商API接口如何驱动业务:代码演示与解析

随着电子商务的飞速发展&#xff0c;电商平台的业务逻辑日益复杂&#xff0c;涉及的模块和功能也越来越多。在这个过程中&#xff0c;电商API接口扮演着至关重要的角色。通过API接口&#xff0c;不同的业务模块可以相互通信&#xff0c;实现数据和服务的共享&#xff0c;提高业…...

秋招总结_就业

2020秋招总结 【前言】 以下内容是写给研二学弟学妹们的秋招总结&#xff0c;研一的师弟师妹们如有需要&#xff0c;也可看看。先说一下我为什么要写这个总结&#xff1a; 1、时代在变化&#xff0c;社会在发展&#xff0c;一届有必要给下一届讲一些经验。 2、我平时和你们…...

基于查表法的水流量算法设计与实现

写在前面 本文分享的是一种基于查表法的水流量的算法方案设计与实现&#xff0c;算法简单易懂&#xff0c;主要面向初学者&#xff0c;有两个目的&#xff1a;一是给初学者一些算法设计的思路引导&#xff1b;二是引导初学者学习怎样用C语言编程实现。 一、设计需求 基于“19…...

Python:复制、移动文件到指定文件夹

需要考虑的问题&#xff1a; 指定文件夹是否存在&#xff0c;不存在则创建在指定文件夹中是否存在同名文件&#xff0c;是覆盖还是另存为 import os import shutil import tracebackdef copyfile(srcfile, dstpath, replaceFalse):"""复制文件到指定文件夹par…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...