想实现一个linux内核安全功能模块的技术思路是怎样的

想实现一个linux内核安全功能模块的技术思路是怎样的,第1张

作者:橘子-实现网

链接:https://www.zhihu.com/question/21637060/answer/58362892

来源:知乎

著作权归作者所有,转载请联系作者获得授权。

用户在执行系统调用时,先通过原有的内核接口依次执行功能性的错误检查,接着进行传统的DAC检查,并在即将访问内核的内部对象之前,通过LSM钩子函数调用LSM。LSM再调用具体的访问控制策略来决定访问的合法性。访问控制整体构架:<img src="https://pic2.zhimg.com/0bfbc70b5ad72af5cb72219bcd8fc471_b.jpg" data-rawwidth="804" data-rawheight="604" class="origin_image zh-lightbox-thumb" width="804" data-original="https://pic2.zhimg.com/0bfbc70b5ad72af5cb72219bcd8fc471_r.jpg">

LSM框架下访问决策模块包括selinux,smack,tomoyo,yama,apparmor.

每个决策模块都是通过各自的XXX_init函数调用register_security()函数,注册到LSM框架的模块被加载成功后,就可以进行访问控制 *** 作。如果此时还有一个安全模块要使用register_security()函数进行加载,则会出现错误,直到使用框架注销后,下一个模块才可以载入。<img src="https://pic2.zhimg.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.zhimg.com/a46689cf523ec473d8105855abc74621_b.jpg" data-rawwidth="1011" data-rawheight="213" class="origin_image zh-lightbox-thumb" width="1011" data-original="https://pic2.zhimg.com/a46689cf523ec473d8105855abc74621_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.zhimg.com/898a9aad542a8947db3e49ad6f37aad0_b.jpg" data-rawwidth="658" data-rawheight="461" class="origin_image zh-lightbox-thumb" width="658" data-original="https://pic1.zhimg.com/898a9aad542a8947db3e49ad6f37aad0_r.jpg"><img src="https://pic3.zhimg.com/b73ffa1412b241eda27952dab213e526_b.jpg" data-rawwidth="658" data-rawheight="464" class="origin_image zh-lightbox-thumb" width="658" data-original="https://pic3.zhimg.com/b73ffa1412b241eda27952dab213e526_r.jpg"><img src="https://pic3.zhimg.com/ac339d9e2ba4c219d7373663583258d6_b.jpg" data-rawwidth="658" data-rawheight="468" class="origin_image zh-lightbox-thumb" width="658" data-original="https://pic3.zhimg.com/ac339d9e2ba4c219d7373663583258d6_r.jpg"><img src="https://pic4.zhimg.com/5353927df40ad97d45aac525d0dfa3ef_b.jpg" data-rawwidth="662" data-rawheight="468" class="origin_image zh-lightbox-thumb" width="662" data-original="https://pic4.zhimg.com/5353927df40ad97d45aac525d0dfa3ef_r.jpg">

make modules_install

make install

查看/proc/filesystems

可以看到smackfs,说明smack已经编进内核

<img src="https://pic2.zhimg.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.SMACK64 --value=TheOther testfile

查看其标签

getfattr

--only-values -n security.SMACK64 -e text testfile

可以看到标签TheOther

<img src="https://pic3.zhimg.com/4144a4e056bb4065bcbe5985c1259c4a_b.jpg" data-rawwidth="698" data-rawheight="60" class="origin_image zh-lightbox-thumb" width="698" data-original="https://pic3.zhimg.com/4144a4e056bb4065bcbe5985c1259c4a_r.jpg">

3. echo TheOne

2>/dev/null >/proc/self/attr/current,当前执行的进程默认都会被打为/proc/self/attr/current下的标签

4.配置策略echo -n "TheOne TheOtherr---">/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.SMACK64 -V TheOne /bin/cat

此时cat被标为TheOne,根据策略可以看出,当转换到普通用户test下,cat testfile是可读的

若attr -s

security.SMACK64 –V Not TheOne /bin/cat

根据策略可以看出,当转换到普通用户test下,cat testfile是不可读的

(需要说明的一点是,当cat本身被标上标签和/proc/self/attr/current打入标签共存时,cat本身的标签生效,而/proc/self/attr/current打入标签没有生效)

我感觉首先应该明确需求,

如果是实现连接池功能,是不用做查询,插入等 *** 作的。

只需要提供接口,给调用程序返回connection,并且把用完的

connection再回收,以供下次调用。所以,概括说就是一次建立大量连

接(比如500个),并且管理这些连接,使它们能反复使用,这样就避

免了不断新建和销毁connection浪费时间。

关于实现:连接池的算法是通用的,这个可以C语音实现。但是具体的

取得数据库连接(get

connection),需要不同的数据库驱动,这个不

可能实现通用。

lz现在做的怎么样了?给个参考,mod_mysql_pool

是一个mySQl的连接池。

--有道启新嵌入式培训


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

原文地址: http://outofmemory.cn/yw/7185621.html

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

发表评论

登录后才能评论

评论列表(0条)

保存