linux日志 audit

linux日志 audit,第1张

我们知道在Linux系统中有大量的日志文件可以用于查看应用程序的各种信息,但是对于用户的 *** 作行为(如某用户修改删除了某文件)却无法通过这些日志文件来查看,如果我们想实现监管企业员工的 *** 作行为就需要开启审计功能,也就是audit。

1、首先执行以下命令开启auditd服务

| 1 | service auditd start |

2、接着查看看auditd的服务状态,有两种方法可以实现,使用auditctl命令时主要看enabled是否为1,1为开启,0为关闭

[root@ns-master-c01 ~]``# service auditd status` |

`auditd (pid 20594) is running...

[root@ns-master-c01 ~]``# auditctl -s

| 5 | AUDIT_STATUS: enabled=1 flag=1 pid=20594 rate_limit=0 backlog_limit=320 lost=0 backlog=0 |

3、开启了autid服务后,所有的审计日志会记录在/var/log/audit/audit.log文件中,该文件记录格式是每行以type开头,其中红框处是事件发生的时间(代表从1970年1月1日到现在过了多久,可以用date命令转换格式),冒号后面的数字是事件ID,同一个事件ID是一样的。

4、audit可以自定义对指定的文件或命令进行审计(如监视rm命令被执行、/etc/passwd文件内容被改变),只要配置好对应规则即可,配置规则可以通过命令行(临时生效)或者编辑配置文件(永久生效)两种方式来实现。

命令行语法(临时生效****)****:

| 1 | auditctl -w /bin/``rm -p x -k removefile ``#-w指定所要监控的文件或命令 |

| 2 | #-p指定监控属性,如x执行、w修改 |

| 3 | #-k是设置一个关键词用于查询 |

编辑配置文件(****永久生效)****:

auditd的配置文件为/etc/audit/audit下的auditd.conf 和audit.rules,auditd.conf 主要是定义了auditd服务日志和性能等相关配置,audit.rules才是定义规则的文件,下面是一个例子,其实就是把auditctl的命令直接拿过来即可,auditctl里支持的选项都可以在这个文件里指定

修改完后重启服务

| 1 | service auditd restart |

5、如果直接使用tailf等查看工具进行日志分析会比较麻烦,好在audit已经提供了一个更好的事件查看工具—— ausea****rch, 使用auserach -h查看下该命令的用法:

这里列出几个常用的选项:

-a number #只显示事件ID为指定数字的日志信息,如只显示926事件:ausearch -a 926

-c commond #只显示和指定命令有关的事件,如只显示rm命令产生的事件:auserach -c rm

-i #显示出的信息更清晰,如事件时间、相关用户名都会直接显示出来,而不再是数字形式

-k #显示出和之前auditctl -k所定义的关键词相匹配的事件信息

通过下图可以看到每个事件被虚线分开,用户名和执行的 *** 作也都能清晰的看到了:

6、使用auditctl还可以查看和清空规则

查看源码

<embed width="16" height="16" id="highlighter_638828_clipboard" type="application/x-shockwave-flash" title="复制到剪贴板" allowscriptaccess="always" wmode="transparent" flashvars="highlighterId=highlighter_638828" menu="false" src="http://www.linuxe.cn/content/plugins/et_highlighter51/scripts/clipboard.swf" style="margin: 0pxpadding: 0pxoutline: 0pxzoom: 1max-width: 96%">

摘自 http://www.linuxe.cn/post-255.html

| 1 | auditctl -l 查看定义的规则 |

| 2 | auditctl -D 清空定义的规则 |

材料:

Linux审计系统auditd 套件

步骤:

安装 auditd

REL/centos默认已经安装了此套件,如果你使用ubuntu server,则要手工安装它:

sudo apt-get install auditd

它包括以下内容:

auditctl : 即时控制审计守护进程的行为的工具,比如如添加规则等等。

/etc/audit/audit.rules : 记录审计规则的文件。

aureport : 查看和生成审计报告的工具。

ausearch : 查找审计事件的工具

auditspd : 转发事件通知给其他应用程序,而不是写入到审计日志文件中。

autrace : 一个用于跟踪进程的命令。

/etc/audit/auditd.conf : auditd工具的配置文件。

Audit 文件和目录访问审计

首次安装 auditd 后, 审计规则是空的。可以用 sudo auditctl -l 查看规则。文件审计用于保护敏感的文件,如保存系统用户名密码的passwd文件,文件访问审计方法:

sudo auditctl -w /etc/passwd -p rwxa

-w path : 指定要监控的路径,上面的命令指定了监控的文件路径 /etc/passwd

-p : 指定触发审计的文件/目录的访问权限

rwxa : 指定的触发条件,r 读取权限,w 写入权限,x 执行权限,a 属性(attr)

目录进行审计和文件审计相似,方法如下:

$ sudo auditctl -w /production/

以上命令对/production目录进行保护。

3. 查看审计日志

添加规则后,我们可以查看 auditd 的日志。使用 ausearch 工具可以查看auditd日志。

sudo ausearch -f /etc/passwd

-f 设定ausearch 调出 /etc/passwd文件的审计内容

4. 查看审计报告

以上命令返回log如下:

time->Mon Dec 22 09:39:16 2016

type=PATH msg=audit(1419215956.471:194): item=0 name="/etc/passwd"

inode=142512 dev=08:01 mode=0100644 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL

type=CWD msg=audit(1419215956.471:194): cwd="/home/somebody"

type=SYSCALL msg=audit(1419215956.471:194): arch=40000003 syscall=5 

success=yes exit=3 a0=b779694b a1=80000 a2=1b6 a3=b8776aa8 items=1 ppid=2090 pid=2231 auid=4294967295 uid=1000 gid=1000 euid=0 suid=0 fsuid=0 egid=1000 sgid=1000 fsgid=1000 tty=pts0 ses=4294967295

comm="sudo" exe="/usr/bin/sudo" key=(null)

time : 审计时间。

name : 审计对象

cwd : 当前路径

syscall : 相关的系统调用

auid : 审计用户ID

uid 和 gid : 访问文件的用户ID和用户组ID

comm : 用户访问文件的命令

exe : 上面命令的可执行文件路径

以上审计日志显示文件未被改动。

我的答案是最正确的请采纳我的内核审计系统的接口函数在Linux内核需要输出审计信息时,它先调用函数audit_log_start创建缓冲区。接着,调用函数audit_log或audit_log_format写缓冲区写入审计信息,最后调用函数audit_log_end发送审计信息,并释放缓冲区。这三个函数分别说明如下:1.函数audit_log_start 函数audit_log_start申请审计缓冲区,如果任务当前在系统调用中,系统调用被标识为可审计的,并在系统调用退出时,产生一条审计记录。函数audit_log_start的参数ctx为审计上下文结构实例;参数gfp_mask为分配内存的类型,如:__GFP_WAIT表示可以等待和重调度;参数type为审计消息类型。如果缓存区申请成功,它返回审计缓冲区的指针,否则返回NULL表示错误。函数audit_log_start申请审计缓冲区,当审计缓冲区链表的缓冲区个数超过上限时,当前进程需要等待用户空间的后台进程将审计消息写入log文件,直到缓冲区个数小于上限值为止。函数audit_log_start在申请并初始化审计缓冲区后,给缓冲区加时间戳和审计记录序列号。函数audit_log_start列出如下(在linux26/kernel/audit.c中)://声明等待队列头,用于等待审计消息被后台进程写入log文件static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait)struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,int type){struct audit_buffer*ab= NULLstruct timespectunsigned intserialint reserveunsigned long timeout_start = jiffies //开始的时间if (!audit_initialized)//如果已初始化,就直接退出return NULLif (unlikely(audit_filter_type(type)))return NULLif (gfp_mask &__GFP_WAIT)reserve = 0elsereserve = 5/*允许调用者多出5个条目*/ //当链表中审计缓冲区数超出上限时,进程等待auditd处理链表中缓冲区while (audit_backlog_limit&&skb_queue_len(&audit_skb_queue) >audit_backlog_limit + reserve) {if (gfp_mask &__GFP_WAIT &&audit_backlog_wait_time &&time_before(jiffies, timeout_start + audit_backlog_wait_time)) {/* 等待后台进程auditd从队列中处理部分缓冲区 */DECLARE_WAITQUEUE(wait, current)set_current_state(TASK_INTERRUPTIBLE)//设置当前进程的状态为可中断等待状态add_wait_queue(&audit_backlog_wait, &wait) //将当前进程加入等待队列if (audit_backlog_limit && skb_queue_len(&audit_skb_queue) >audit_backlog_limit)schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies)//调度__set_current_state(TASK_RUNNING) //设置当前进程为运行状态remove_wait_queue(&audit_backlog_wait, &wait)continue}  //检查每秒发送的记录数不能超过上限,以防止受非法攻击if (audit_rate_check())printk(KERN_WARNING "audit: audit_backlog=%d >" "audit_backlog_limit=%d\n", skb_queue_len(&audit_skb_queue), audit_backlog_limit) audit_log_lost("backlog limit exceeded")audit_backlog_wait_time = audit_backlog_wait_overflowwake_up(&audit_backlog_wait)return NULL}ab = audit_buffer_alloc(ctx, gfp_mask, type) //申请审计缓冲区if (!ab) {audit_log_lost("out of memory in audit_log_start")return NULL}//得到当前时间存入t,计算审计记录的序列号,存入serialaudit_get_stamp(ab->ctx, &t, &serial)//将时间戳和序列号写入审计记录audit_log_format(ab, "audit(%lu.%03lu:%u): ", t.tv_sec, t.tv_nsec/1000000, serial)return ab}函数audit_buffer_alloc申请审计缓冲区,先尝试从空闲链表上取下一个缓冲区,如果空闲链表中没有,就分配一个缓冲区。然后,填充netlink消息头。该函数列出如下: static DEFINE_SPINLOCK(audit_freelist_lock)//定义自旋锁,用于锁住链表audit_freeliststatic struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,gfp_t gfp_mask, int type){unsigned long flagsstruct audit_buffer *ab = NULLstruct nlmsghdr *nlh //从空闲链表中得到一个缓冲区spin_lock_irqsave(&audit_freelist_lock, flags) //加锁if (!list_empty(&audit_freelist)) {ab = list_entry(audit_freelist.next,struct audit_buffer, list)list_del(&ab->list)--audit_freelist_count}spin_unlock_irqrestore(&audit_freelist_lock, flags) //释放锁 //如果空闲链表中没有空闲缓冲区成员,就分配一个缓冲区if (!ab) {ab = kmalloc(sizeof(*ab), gfp_mask)if (!ab)goto err}ab->skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask)//分配套接字缓冲区if (!ab->skb)goto errab->ctx = ctxab->gfp_mask = gfp_mask //扩展套接字缓冲区skb的已使用数据区,将netlink消息头数据nlmsghdr加到skbnlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0)) nlh->nlmsg_type = typenlh->nlmsg_flags = 0nlh->nlmsg_pid = 0nlh->nlmsg_seq = 0return aberr:audit_buffer_free(ab)return NULL}2.函数audit_log_format函数audit_log_format将一个审计消息按格式写入审计缓冲区,参数ab为审计缓冲区,参数fmt为格式化的字符串。其列出如下:void audit_log_format(struct audit_buffer *ab, const char *fmt, ...){va_list argsif (!ab)returnva_start(args, fmt)audit_log_vformat(ab, fmt, args)va_end(args)}函数audit_log_vformat将一个审计消息按格式写入套接字缓冲区中,如果审计缓冲区没有足够的空间,就扩展套接字缓冲区的数据域。由于printk缓冲区为1024,扩展的套接字缓冲区最小应为1024。函数audit_log_vformat列出如下: static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,  va_list args){int len, availstruct sk_buff *skbva_list args2if (!ab)returnBUG_ON(!ab->skb)skb = ab->skbavail = skb_tailroom(skb)//计算套接字缓冲区的空闲数据空间if (avail == 0) { //如果套接字缓冲区没有空闲数据空间,扩展空间avail = audit_expand(ab, AUDIT_BUFSIZ) // AUDIT_BUFSIZ为1024,if (!avail)goto out}va_copy(args2, args)len = vsnprintf(skb->tail, avail, fmt, args) //将信息写入到缓冲区if (len >= avail) { //如果实际信息长度比可用的缓冲区大,扩展空间/* 由于printk缓冲区是1024,因此,扩展空间最少为1024 */avail = audit_expand(ab,max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail))if (!avail)goto outlen = vsnprintf(skb->tail, avail, fmt, args2)  //将审计信息写入到缓冲区}if (len >0)skb_put(skb, len)//将写入信息的数据缓冲区附加到skb上out:return}

函数audit_expand扩展在审计缓冲区中的套接字缓冲区,扩展成功,返回可用的空间大小,扩展失败返回0,表示没有空间。参数ab表示审计缓冲区的指针,参数extra表示加到套接字缓冲区skb尾部的缓冲区空间大小。函数audit_expand列出如下:static inline int audit_expand(struct audit_buffer *ab, int extra){struct sk_buff *skb = ab->skbint ret = pskb_expand_head(skb, skb_headroom(skb), extra, ab->gfp_mask)if (ret <0) {audit_log_lost("out of memory in audit_expand")return 0}return skb_tailroom(skb)//返回可用的缓冲区空间大小}3.函数audit_log_end当进程完成了将审计记录写入审计缓冲区的 *** 作时,它调用函数audit_log_end将套接字缓冲区中的审计记录数据发送给用户空间后台进程,由后台进程写入到log文件。如果审计后台进程存在,使用netlink机制传输数据,由审计后台将套接字缓冲区中的审计记录数据写入审计文件audit.log中;如果审计后台不存在,使用函数printk记录数据,然后由日志后台进程将数据写入到日志文件中。当数据发送完成后,函数audit_log_end唤醒等待队列kauditd_wait。有些进程因为审计套接字缓冲区链表上的缓冲区数量超过上限而在队列kauditd_wait等待,当其他进程发送了数据时,应唤醒这些等待进程。函数audit_log_end列出如下:void audit_log_end(struct audit_buffer *ab){if (!ab)returnif (!audit_rate_check()) { //检查审计系统的传输速度,如果netlink机制传输速度超过上限,则返回错误audit_log_lost("rate limit exceeded")} else {if (audit_pid) { //如果审计后台的进程ID存在,使用netlink机制传输数据struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->datanlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0)skb_queue_tail(&audit_skb_queue, ab->skb)ab->skb = NULLwake_up_interruptible(&kauditd_wait) //发送了数据,唤醒等待队列} else { //使用printk记录数据printk(KERN_NOTICE "%s\n", ab->skb->data + NLMSG_SPACE(0))}}audit_buffer_free(ab)}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/7121409.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-01
下一篇2023-04-01

发表评论

登录后才能评论

评论列表(0条)

    保存