发布网友 发布时间:2022-04-22 07:16
共1个回答
热心网友 时间:2022-06-17 09:16
作者:橘子-实现网
链接:https://www.hu.com/question/21637060/answer/583622
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
用户在执行系统调用时,先通过原有的内核接口依次执行功能性的错误检查,接着进行传统的DAC检查,并在即将访问内核的内部对象之前,通过LSM钩子函数调用LSM。LSM再调用具体的访问控制策略来决定访问的合法性。访问控制整体构架:<img src="https://pic2.mg.com/0bfbc70b5ad72af5cb72219bcd8fc471_b.jpg" data-rawwidth="804" data-rawheight="604" class="origin_image zh-lightbox-thumb" width="804" data-original="https://pic2.mg.com/0bfbc70b5ad72af5cb72219bcd8fc471_r.jpg">
LSM框架下访问决策模块包括selinux,smack,tomoyo,yama,apparmor.
每个决策模块都是通过各自的XXX_init函数调用register_security()函数,注册到LSM框架的模块被加载成功后,就可以进行访问控制操作。如果此时还有一个安全模块要使用register_security()函数进行加载,则会出现错误,直到使用框架注销后,下一个模块才可以载入。<img src="https://pic2.mg.com/550ae6f4ad51862159579972417dc1fd_b.jpg" data-rawwidth="420" data-rawheight="285" class="content_image" width="420">
Linux安全模块(LSM)提供了两类对安全钩子函数的调用:一类管理内核对象的安全域,另一类仲裁对这些内核对象的访问。对安全钩子函数的调用通过钩子来实现,钩子是全局表security_ops中的函数指针,这个全局表的类型是security_operations结构,这个结构定义在include/linux/security.h这个头文件中。
通过对security代码进行一番简单的分析,LSM启动过程流图:
<img src="https://pic2.mg.com/a466cf523ec473d8105855abc74621_b.jpg" data-rawwidth="1011" data-rawheight="213" class="origin_image zh-lightbox-thumb" width="1011" data-original="https://pic2.mg.com/a466cf523ec473d8105855abc74621_r.jpg">security_initcall只能调用selinux_init,smack_init ,tomoyo_init , yama_init 和apparmor_init中的一个,因为内核不允许多种安全机制同时一起工作。一旦一个安全模块被加载,就成为系统的安全策略决策中心,而不会被后面的register_security()函数覆盖,直到这个安全模块被使用unregister_security()函数向框架注销。security_initcall只能调用selinux_init,smack_init ,tomoyo_init , yama_init 和apparmor_init中的一个,因为内核不允许多种安全机制同时一起工作。一旦一个安全模块被加载,就成为系统的安全策略决策中心,而不会被后面的register_security()函数覆盖,直到这个安全模块被使用unregister_security()函数向框架注销。
因此LSM框架下只能开启一种安全机制,smack编译进Linux内核的配置和要求:
(1)要求smack和selinux不能够同时运行,不能同时存在于同一个运行中的内核;
查看内核是否开启以下的功能(如果没有则需要开启):
CONFIG_NETLABEL=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_SMACK=y
CONFIG_SECURITY_SELINUX should not be
set
步骤:
make menuconfig
<img src="https://pic1.mg.com/8a9aad542a47db3e49ad6f37aad0_b.jpg" data-rawwidth="658" data-rawheight="461" class="origin_image zh-lightbox-thumb" width="658" data-original="https://pic1.mg.com/8a9aad542a47db3e49ad6f37aad0_r.jpg"><img src="https://pic3.mg.com/b73ffa1412b241eda27952dab213e526_b.jpg" data-rawwidth="658" data-rawheight="4" class="origin_image zh-lightbox-thumb" width="658" data-original="https://pic3.mg.com/b73ffa1412b241eda27952dab213e526_r.jpg"><img src="https://pic3.mg.com/ac339d9e2ba4c219d7373663583258d6_b.jpg" data-rawwidth="658" data-rawheight="468" class="origin_image zh-lightbox-thumb" width="658" data-original="https://pic3.mg.com/ac339d9e2ba4c219d7373663583258d6_r.jpg"><img src="https://pic4.mg.com/5353927df40ad97d45aac525d0dfa3ef_b.jpg" data-rawwidth="662" data-rawheight="468" class="origin_image zh-lightbox-thumb" width="662" data-original="https://pic4.mg.com/5353927df40ad97d45aac525d0dfa3ef_r.jpg">
make moles_install
make install
查看/proc/filesystems
可以看到smackfs,说明smack已经编进内核
<img src="https://pic2.mg.com/88a3d754e3a6bdc36a3424ef3df54671_b.jpg" data-rawwidth="146" data-rawheight="187" class="content_image" width="146">
执行如下的命令:
mkdir -p /smack
在文件/etc/fstab添加下面的一行
smackfs /smack smackfs defaults 0 0
然后执行下面的命令:
mount –a
然后就体验一下它的功能了:
1. 比如在用户test的home目录下(/home/test),新建文件夹 mkdir testdir
cd testdir/
touch testfile
2. 给新建的testfile 打上TheOther标签
setfattr
--name=security.SMACK --value=TheOther testfile
查看其标签
getfattr
--only-values -n security.SMACK -e text testfile
可以看到标签TheOther
<img src="https://pic3.mg.com/4144a4e056bb4065bcbe5985c1259c4a_b.jpg" data-rawwidth="698" data-rawheight="60" class="origin_image zh-lightbox-thumb" width="698" data-original="https://pic3.mg.com/4144a4e056bb4065bcbe5985c1259c4a_r.jpg">
3. echo TheOne
2>/dev/null > /proc/self/attr/current,当前执行的进程默认都会被打为/proc/self/attr/current下的标签
4.配置策略echo -n "TheOne TheOther r---"> /sma ck/load
因为当前进程只要是没有特殊配置过的都被打为TheOne,所以当转换到普通用户test下,cat testfile是可读的
5.现在我将当前进程打为NotTheOne ,echo NotTheOne 2>/dev/null >
/proc/self/attr/current
当转换到普通用户test下,cat testfile则变成不可读的了
6.如果你想单独对某个进程打标签,而不是对当前进程打,就
attr -s security.SMACK -V TheOne /bin/cat
此时cat被标为TheOne,根据策略可以看出,当转换到普通用户test下,cat testfile是可读的
若attr -s
security.SMACK –V Not TheOne /bin/cat
根据策略可以看出,当转换到普通用户test下,cat testfile是不可读的
(需要说明的一点是,当cat本身被标上标签和/proc/self/attr/current打入标签共存时,cat本身的标签生效,而/proc/self/attr/current打入标签没有生效)