频 道 直 达 - 新闻 - 培训 - 软件 - 教程 - 前沿 - 组网 - 系统应用 - 安全 - 编程 - 存储 - 操作系统 - 数据库 - 服务器 - 专题 - 产品 - 案例库 - 读书 - 博客 - BBS
51CTO.COM_中国最大的网络技术网站
找资料:

2.4.4 文件系统变化的审计

作者: 倪继利 著 出处:电子工业出版社博文视点  2007-12-22 16:40    砖    好    评论   进入论坛
阅读提示:《Linux安全体系分析与编程》第二章分析了日志系统的记录机制,阐述了审计系统的原理,并说明了文件系统变化监视机制。本文主要介绍的是文件系统变化的审计。

2.4.4  文件系统变化的审计

审计系统使用inotify机制监视文件系统的变化,并将监视的结果通过审计系统记录到log文件中。

内核审计系统调用函数audit_init进行初始化时,函数audit_init会调用函数inotify_init创建并初始化一个监视处理实例audit_ih。程序可以在指定节点的watch链表中查找监视处理实例audit_ih的watch,如果找到watch,就可以调用在监视处理实例audit_ih中的函数处理审计事件。

1.审计监视的数据结构

审计监视结构audit_watch用来存放用于监视文件系统变化规则的相关信息。审计规则链表audit_filter_list[AUDIT_FILTER_WATCH]用来存储审计监视的规则。每条审计规则结构audit_krule含有审计监视结构指针watch,审计规则结构audit_krule与审计监视结构指针相关的部分列出如下:

struct audit_krule {
......
struct audit_watch*watch;
......
};

审计监视结构audit_watch列出如下(在linux26/include/linux/audit.h中):

struct audit_watch {
atomic_tcount;  /*引用数 */
char*path;   /* 加watch的路径*/
dev_tdev;    /* 与超级块设置被关的指针*/
unsigned longino;   /*相关的节点号*/
struct audit_parent*parent;  /* associated parent */
struct list_headwlist;      /* 用于挂接到parent->watches 链表上 */
struct list_headrules;         /* 相关的规则*/
};

结构audit_parent用来封装watch,它还含有审计监视的链表和状态标识等,它对应规则描述路径的父目录节点,因此,文件系统变化时,inotify机制的hook函数通过父目录节点的watch触发监视处理实例的函数。

父目录中每个文件路径可能对应一个审计监视规则,因此,结构audit_parent提供了链表指针watches存放父目录下文件的审计监视结构audit_watch实例。

程序可以通过审计规则链表找到watch,还可以在节点的watch链表中找到需要的watch。

结构audit_parent列出如下:

struct audit_parent {
struct list_headilist;/*用于挂接在inotify注册链表上*/
struct list_headwatches;  /*用于挂接结构audit_watch实例的链表头*/
struct inotify_watchwdata;/*inotify机制的watch数据*/
unsignedflags;/*状态标识*/
};

2.添加审计监视规则

审计应用程序auditctl可使用-w或-W选项添加或删除文件系统监视规则,这两个选项说明如下:

-w 为文件系统对象插入一个watch(监视)。不支持匹配符
-W 移去文件系统对象

添加与删除审计监视规则的过程是相反的过程,下面只分析添加审计监视规则的机制。

当审计应用程序auditctl添加审计监视规则时,内核审计系统针对所有规则统一调用函数audit_receive_filter将审计规则加到审计规则链表上。对于审计监视规则,函数audit_receive_filter的调用层次图如图2-7所示。
错误!

图2-7 函数audit_receive_filter添加审计监视规则的调用层次图

图2-7中,内核审计系统函数audit_receive_filter分析应用程序auditctl设置的审计监视规则,调用函数audit_init_watch将规则初始化为结构audit_watch实例,放入规则链表中。

函数audit_add_watch在节点和规则实例krule中加入watch。它调用函数inotify_find_watch在节点的watch链表中查找匹配监视处理实例audit_ih的watch,如果没找到,就调用函数audit_init_parent初始化watch,并将其加入到节点和监视处理实例audit_ih的watch链表中,再将watch加入到审计监视规则链表中。

watch加入节点后,监视文件系统变化的hook函数就可以调用watch中的监视处理函数,hook函数通过watch的成员指针找到监视处理实例audit_ih,audit_ih含有审计文件系统变化的记录函数,记录函数将文件系统变化信息通过审计系统写入到log文件中。

函数audit_add_watch列出如下(在linux26/kernel/auditfilter.c中):

/*参数ndw是文件的结构nameidata 实例,ndp为文件所在目录的结构实例*/
static int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
   struct nameidata *ndw)
{
 //得到审计监视规则实例,前面运行的函数audit_init_watch根据规则已初始化了这个实例
struct audit_watch *watch = krule->watch;
struct inotify_watch *i_watch;
struct audit_parent *parent;
int ret = 0;

if (ndw) {
watch->dev = ndw->dentry->d_inode->i_sb->s_dev; //得到文件所在的设备
watch->ino = ndw->dentry->d_inode->i_ino;//得到文件的节点号
}

mutex_unlock(&audit_filter_mutex);
     //在目录节点上查找符合audit_ih的watch,找到后,放在i_watch中
if (inotify_find_watch(audit_ih, ndp->dentry->d_inode, &i_watch) < 0) {
               /*如果在目录节点上没有找到watch,初始化watch,创建结构audit_parent实例并放在parent中
parent = audit_init_parent(ndp);
if (IS_ERR(parent)) { //如果初始化出错,返回错误
/* 调用者期望互斥锁处于锁住状态*/
mutex_lock(&audit_filter_mutex);
return PTR_ERR(parent);
}
} else
 //找到watch,得到它的结构audit_parent实例,并放在parent中
parent = container_of(i_watch, struct audit_parent, wdata);

mutex_lock(&audit_filter_mutex);

/* parent在取得audit_filter_mutex之前被移走,则返回错误*/
if (parent->flags & AUDIT_PARENT_INVALID)
ret = -ENOENT;
else
audit_add_to_parent(krule, parent); //将parent加入到krule中,krule代表一条审计规则

/*引用计数减1,如果引用计数为0,删除watch */
put_inotify_watch(&parent->wdata);
return ret;
}

函数audit_add_to_parent将给定的规则与父目录的结构inotify_watch实例联系起来,调用者必须持有互斥锁audit_filter_mutex,其列出如下:

static void audit_add_to_parent(struct audit_krule *krule,
struct audit_parent *parent)
{
  //得到审计监视规则实例,前面运行的函数audit_init_watch根据规则已初始化这个实例
struct audit_watch *w, *watch = krule->watch;
int watch_found = 0;
      //遍历链表watches,watches存放着目录下所有文件的结构audit_watch实例
list_for_each_entry(w, &parent->watches, wlist) {
   // parent->watches为目录的结构audit_watch实例,w为文件的结构audit_watch实例
if (strcmp(watch->path, w->path))
continue;

watch_found = 1;

audit_put_watch(watch); //引用计数减1
audit_put_watch(watch);

audit_get_watch(w); //引用计数加1
krule->watch = watch = w;  //将文件的结构audit_watch实例放到内核规则实例krule上
break;
}

if (!watch_found) { //在链表watches没有找到文件的结构audit_watch实例,将
get_inotify_watch(&parent->wdata); //引用计数加1
watch->parent = parent; 

list_add(&watch->wlist, &parent->watches); //将&watch加入到parent->watches 链表上
}
list_add(&krule->rlist, &watch->rules);
}

3.监视处理实例audit_ih

文件系统变化的审计消息是通过监视处理实例audit_ih进行处理的,它的操作函数集为audit_ inotify_ops,操作函数集中的函数audit_handle_ievent处理inotify事件。当文件系统发生变化时,inotify机制hook函数会通过watch调用函数audit_handle_ievent将文件系统变化的审计消息通过审计系统写入到log文件中。

内核审计系统初始化时,初始化函数audit_init会调用函数inotify_init创建并初始化监视处理实例audit_ih。函数audit_init与创建监视处理实例相关的代码列出如下(在linux26/kernel/audit.c中):

struct inotify_handle *audit_ih;
static int __init audit_init(void)
{
......
 #ifdef CONFIG_AUDITSYSCALL
audit_ih = inotify_init(&audit_inotify_ops);
if (IS_ERR(audit_ih))
audit_panic("cannot initialize inotify handle");
#endif
    ......
}

操作函数集audit_inotify_ops列出如下:

#ifdef CONFIG_AUDITSYSCALL
static const struct inotify_operations audit_inotify_ops = {
.handle_event= audit_handle_ievent,
.destroy_watch= audit_free_parent,
};
#endif

函数audit_handle_ievent根据inotify事件更新审计规则结构实例上的审计监视数据,调用审计系统接口函数将文件系统变化信息写入到log文件中,其函数列出如下(在linux26/kernel/auditfilter.c中):

void audit_handle_ievent(struct inotify_watch *i_watch, u32 wd, u32 mask,
u32 cookie, const char *dname, struct inode *inode)
{
struct audit_parent *parent;
//通过节点的i_watch找到结构audit_parent实例
parent = container_of(i_watch, struct audit_parent, wdata);

if (mask & (IN_CREATE|IN_MOVED_TO) && inode)
//更新规则结构实例中的审计监视,并调用审计系统接口函数记录文件系统变化的信息
audit_update_watch(parent, dname, inode->i_sb->s_dev,
inode->i_ino, 0);
else if (mask & (IN_DELETE|IN_MOVED_FROM))
audit_update_watch(parent, dname, (dev_t)-1, (unsigned long)-1, 1);
/* inotify自动删除watch 并发送IN_IGNORED */
else if (mask & (IN_DELETE_SELF|IN_UNMOUNT))
audit_remove_parent_watches(parent);
/* inotify不删除watch,因此需要手动删除它 */
else if(mask & IN_MOVE_SELF) {
audit_remove_parent_watches(parent);
inotify_remove_watch_locked(audit_ih, i_watch);
} else if (mask & IN_IGNORED)
put_inotify_watch(i_watch); //删除watch
}

【责任编辑:董书 TEL:(010)68476606】

回书目   上一节   下一节
专题
Sun以10亿美元并购开源数据库厂商MySQL
系统应用日志分析管理
Linux——从菜鸟到高手
网络管理系统如何支撑ITSM
企业Web安全威胁在线评估系统
我也说两句

匿名发表

(如果看不清请点击图片进行更换)


中 国 最 大 的 网 络 技 术 网 站 ·
技 术 成 就 梦 想
订阅技术快讯
电子杂志下载
名称:SQL Server数据库管理精品黄皮书
简介:书中文章经过精挑细选,便于用户能根据自己的实际工作和学习,快速在本书寻找到相关资料。内容涵盖了SQL Server的安装与升级、语句查询、数据备份和恢复、自动化任务、数据同步、数据字典、安全和预防、性能和优化、集群等各方面应用信息,以及DBA管理人员在数据库管理工作中
名称:2007路由技术大全
简介:《2007路由技术大全》由51CTO.com网站特别策划制作,该书包括路由器技术、路由器产品、路由器配置、安全设置、路由器故障处理、路由器密码恢复,以及广大网友在实践使用中的心得经验和技巧文章,内容注重实用性,适用于初学者入门,也适合多年从业者提高,是一本实践和理论完
名称:网络安全精品应用黄皮书
简介:《2007精品网络安全黄皮书》包括了9个大类24个小类, 800余篇文章,内容包含了熊猫烧香病毒、DDOS攻击、ARP病等热点问题的介绍及解决方案。从病毒查杀、防范、系统、数据等各方面的安全设置到黑客技术的了解、防范,涉及到了安全应用的全部领域, 由浅至深内容全面。
浏览器的战国时代
浏览器的战国时代
ARP攻击防范与解决方案
ARP攻击防范与解决方案
NAC安全访问控制
NAC安全访问控制
· NAC安全访问控制
· 网络布线测试仪器
· Windows Server 2008专..
· Windows远程桌面应用
· 网络故障排除宝典
· 运营商封堵ADSL共享 中..
· 解析35岁技术人的价值..
· 世纪枭雄比尔盖茨的王..
· 主流品牌防火墙配置
· ASP.NET开发教程
· 超级计算机TOP500专题
· Vista SP1对决XP SP3
· SQL Server 2008/2005..
· 程序员如何成长?
· C#技术开发指南
· 虚拟化技术还有点“虚”
ARP攻击防范与解决方案
ARP攻击防范与解决方案
SQL Server 2008/2005全解
SQL Server 2008/2005全解
SOA 面向服务架构
SOA 面向服务架构
· SOA 面向服务架构
· SQL Server 2008/2005..
· Apache技术专题
· 三层交换技术专题
· SQL Server入门到精通
· Windows远程桌面应用
· C#技术开发指南
· Apache技术专题
· Windows集群服务应用
· C#技术开发指南
· 国际文档格式标准开战
· 路由器设置与口令恢复
· Linux 集群技术专题
· PHP开发应用手册
· SOA 面向服务架构
· 企业数据恢复指南
ARP攻击防范与解决方案
ARP攻击防范与解决方案
SQL Server 2008/2005全解
SQL Server 2008/2005全解
SQL Server入门到精通
SQL Server入门到精通
· SQL Server入门到精通
· SQL Server 2008/2005..
· SOA 面向服务架构
· Apache技术专题
· C#技术开发指南
· 三层交换技术专题
· Apache技术专题
· C#技术开发指南
· Windows远程桌面应用
· 企业数据恢复指南
· Windows集群服务应用
· 路由器设置与口令恢复
· Linux 集群技术专题
· SOA 面向服务架构
· 了解统一威胁管理(UTM)..
· 反垃圾邮件技术应用