SELinux概述.docx
- 文档编号:4406140
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:83
- 大小:86.33KB
SELinux概述.docx
《SELinux概述.docx》由会员分享,可在线阅读,更多相关《SELinux概述.docx(83页珍藏版)》请在冰豆网上搜索。
SELinux概述
SELinux使用了分级的强制访问控制,是Linux核的重要安全措施。
SELinux的安全策略工具可从oss.tresys./projects下载。
本章分析了SELinux的安全机制,介绍了安全策略配置语言、核策略库的结构,简述了SELinux核模块的实现,还分析了用户空间的客体管理器。
3.1 SELinux概述
SELinux是安全增强了的Linux,是Security-enhancedLinux的简写,SELinux改进了对核对象和服务的访问控制,改进了对进程初始化、继承和程序执行的访问控制,改进了对文件系统、目录、文件和打开文件描述的访问控制,还改进了对端口、信息和网络接口的访问控制。
早期的Linux核只提供了经典的UNIX自主访问控制(root用户,用户ID,模式位安全机制),以及部分地支持了POSIX.1e标准草案中的capabilities安全机制,这对于Linux系统的安全性是不够的,NSA(theNationalSecurityAgency)和SCC(SecureComputingCorporation)共同开发了强大的基于类型加强(TypeEnforcement)的强制访问控制(mandatoryaccesscontrol,简称MAC)机制,提供了动态的安全策略机制。
Linux核增加了一个通用的安全访问控制框架,它通过hook函数来控制程序的执行,这个框架就是Linux安全模块(LSM),在LSM上可使用各种安全控制机制(如:
Flask机制)来实现对程序的控制。
SELinux应用了类型加强(TypeEnforcement,TE)和基于角色访问控制(role-basedaccesscontrol,RBAC)技术。
TE给每个主体(进程)和系统中的客体定义了一个类型,这些类型定义在SELinux的安全策略文件中,以安全标签形式存放在文件本身的扩展属性(extendedattributes,简称xattrs)里。
当一个类型与一个进程相关时,这个类型称为域(domain),例如:
后台进程httpd的域为httpd_t。
主体(subject)对客体(object)的操作在SELinux中默认下是不允许的,而由策略定义允许的操作。
TE使用主体的域和客体类型从策略文件中查找操作许可。
例如:
策略中的一条规则如下:
allowhttpd_tnet_conf_t:
file{readgetattrlockioctl};
这条规则表示httpd_t域对net_conf_t类型客体的文件有“{}”中所表示的操作权限。
SELinux的访问控制规则存放在安全策略文件中,策略文件分为二进制和源代码文件,源代码以策略配置语言的形式描述,由编程者创建和维护。
源代码经策略配置工具编译后生成二进制文件。
二进制策略被装载到核空间,形成在存中的策略库及缓存,核就可以使用访问控制规则了。
SELinux可以实现非常小颗粒的访问控制,这些细小颗粒的访问控制也造成了安全策略的复杂性。
Linux核的SELinux安全体系由Flask和LSM框架共同组成,LSM是由hook函数组成的安全控制框架,Flask框架将SElinux的策略规则转换成访问控制许可。
在安全策略配置语言中经常用到的名称术语说明如下。
subject主体,常指一个进程
object客体,常指一个文件
objectclass客体的类
permission许可
context上下文
user 用户
role 角色
type类型
TypeAttributes类型属性
TypeEnforcement类型增强
dormain域,它是一个进程的类型
sourcetype 源类型
targettype 目标类型
labeling 标识
accessvectorcache(AVC)访问向量缓存
accessdecision访问决策
3.1.1 Linux与SELinux在安全管理上的区别
在传统的Linux自由访问控制(DiscretionaryAccessControls,DAC)之后,SELinux在核中使用强制访问控制机制(MAC)检查允许的操作。
在DAC下,文件客体的所有者提供了客体上的潜在风险控制。
用户可以通过错误配置的chmod命令和一个非期望的访问权限传递,暴露一个文件或目录给一个恶意信任者。
这个用户启动的进程,如:
CGI脚本,可在这个用户拥有的文件做任何的操作。
DAC实际上仅有两个主要的用户分类:
管理者和非管理者。
为了解决权限分级,它使用了访问控制列表(accesscontrollists,简称ACL),给非管理者用户提供不同的权限。
而root用户对文件系统有完全自由的控制权。
MAC访问控制框架可以定义所有的进程(称为主体)对系统的其他部分(如:
文件、设备、socket、端口和其他进程,它们被称为客体或目标对象)进行操作的权限或许可。
这些许可由进程和客体的安全策略来定义,通过核实现控制。
这种方式可给一个进程仅授予操作所需要的权限,这遵循了最小权限原则。
在MAC下,即使用户用chmod暴露了他们的数据,但进程还是无法修改在策略中没有许可的文件。
DAC和MAC分别使用自己的访问控制属性,两者独立,但都必须通过权限检查。
它们的区别有以下二个:
1.在主体的访问控制上:
DAC:
真实有效的用户和组ID
MAC:
安全上下文(user:
role:
type)
DAC和MAC的UID是独立的。
2.在客体的访问控制上:
DAC:
(文件)访问模式(rwxr-xr-x)和用户及组ID
MAC:
安全上下文(user:
role:
type)
3.1.2 Flask安全框架概述
1.Flask框架对操作许可的判定过程
图3-1描述了Flask框架,图中,一个主体进程对系统中的客体(如:
设备文件)进行操作,如:
读写文件。
这个操作通过DAC权限检查之后,再进行SELinux的权限检查。
在DAC检查中,主体通过基于ACL常规文件权限获得了对客体的操作许可。
SELinux权限检查的过程如下:
策略强制服务器(policyenforcementserver)从主体和客体收集安全上下文,并发送安全上下文标签对给安全服务器(securityserver),安全服务器负责产生策略的决策。
策略强制服务器首先检查AVC,如果AVC有高速缓存的策略决策,它返回决策给策略强制服务器。
如果没有,它转向到安全服务器,安全服务器使用系统初始化期间装载到核的二进制策略作出决策,将决策放到AVC的cache中进行缓存,并将决策返回给策略强制服务器。
如果决策为允许操作,则主体对客体进行操作,否则,操作被禁止,禁止操作信息被记录到log文件,log文件一般为/var/log/messages。
图3-1 Flask框架
安全服务器产生策略决策的同时,强制服务器处理任务的其他部分。
从这个角度来看,强制服务器部分可以看作客体管理器,客体管理包括用安全上下文件标识客体、管理存中的标签、管理客户端和服务器的标识行为。
2.Flask框架组成说明
Flask安全体系结构由客体管理器和安全服务器组成。
客体管理器实施安全策略的判定结果,安全服务器作出安全策略的判定。
Flask安全体系结构提供从安全服务器检索访问、标记和多例化判定的接口。
访问判定指主体对客体操作的一个权限是否得到批准。
标记指分配给一个客体的安全属性标签。
多例化判定指一个特定的请求应该从多例化资源中选取哪一个。
Flask安全体系结构还提供一个访问向量缓存(AVC)模块,该模块允许从客体管理器缓存中直接取出缓存的判定结果,以提高执行速度。
Flask框架的安全服务器的安全策略由四个子策略组成:
多级安全(MLS)策略、类型加强(TE)策略、基于标识的访问控制(IBAC)策略和基于角色的访问控制(RBAC)策略。
安全服务器提供的访问判定必须满足每个子策略的要求。
安全服务器定义了一个由类型加强(TE)策略、基于角色的访问控制(RBAC)策略和多级安全(MLS)策略组合成的策略决策系统。
其中,TE和RBAC策略是安全策略的必要部分,MLS策略是可选的,当核配置选项CONFIG_FLASK_MLS打开时,系统提供MLS策略支持。
Flask体系结构为安全标记定义了两个独立于策略的数据类型:
安全上下文(context)和安全标识符(SID)。
安全上下文是由可变长字符串表示的安全标记,存在于文件的扩展属性中。
SID是被安全服务器映射到对应安全上下文的整数。
Flask客体管理器负责将安全标签绑定到客体上、绑定SID到核对象上。
一个安全上下文(或称为标签)由用户ID、角色、类型和可选的MLS分级属性或分类属性组成。
角色仅与进程相关,因而文件安全上下文有一个通用的object_r的角色。
安全服务器仅为安全上下文提供SID。
SELinux系统提供一个与安全服务器相配套的安全策略配置语言,该语言用于对安全服务器中安全策略的配置进行描述。
策略配置语言描述的规则策略存于策略文件中,策略文件源代码由工具编译成二进制策略文件,安全服务器在引导时读取二进制形式策略文件,形成策略库。
3.MLS分级机制
MLS(Multi-LevelSecurity)机制给用户提供了可以用不同等级的安全水平来访问系统。
例如:
MLS安全分级从低到高为Confidential、Secret、TopSecret和Individuals,不同级别可查看不同的分类信息。
低级别不可查看高级别的文档。
SELinux支持分级保护数据,它使用BLP(Bell-LaPadulaModel:
BLP)模型,这个模型定义了系统的信息是如何基于粘附在每个主体和客体的标签来进行流动的。
如:
在Secret级别的用户可与其他同级别用户共享数据,并能提取来自Confidential级(比Secret级低)的信息。
但在Secret级别的进程不能查看TopSecret级别(比Secret级高)的数据。
它还阻止高级别进程随便给低级别的数据写入信息。
即“不能读较高级别的数据,不能写较低级别的数据”模型。
在多级别系统中,高级别用户不自动获得管理者权限,但它们对计算机上的所有信息可以有访问权。
安全上下文中,主体和客体用安全级别(SecurityLevels,SL)标识,SL由敏感属性和分类属性组成。
Sensitivity(敏感属性)是安全体系的属性,它将数据等分成不同安全级别,如:
“Secret”或“TopSecret”。
Categories(分类属性)是一套非体系的属性,如:
“USOnly”或“UFO”,表示仅US使用。
分类属性将数据分隔成几个独立的小组,每个小组可归属于不同的用户等。
一个SL必须有一个敏感属性和0个或多个分类属性。
例如:
SL是{Secret/UFO,Crypto}、{TopSecret/UFO,Crypto,Stargate}或{Unclassified}。
体系的敏感属性跟踪着0个或多个分类属性,因为敏感属性还可以分隔成彼此独立的分类属性。
客体上的安全级别称为分级(Classifications),主体上的安全级别称为Clearances。
3.1.3 安全模块(LSM)框架
为了加入安全机制,Linux核从以下五个方面进行了修改:
1.在核的构件描述数据结构中加入了安全域。
2.在核不同的构件中加入了对安全钩子函数的调用。
3.提供了通用安全模块。
4.将capabilities逻辑的大部分移植为一个可选的安全模块。
5.加入了安全系统调用。
安全域是一个void*类型的指针,它指向安全模块操作函数,从而将安全信息和核对象联系起来。
下面列出加入了安全域的核数据结构:
task_struct 进程结构
linux_binprm 二进制程序运行结构
super_block 文件系统超级块结构
inode 文件系统节点结构,表示文件、目录、管道、设备文件或socket套接字
file 打开的文件结构
sk_buff 网络包缓冲区结构
net_device 网络设备结构
kern_ipc_perm IPC(进程间通信)权限结构
msg_msg:
消息结构
Linux安全模块(LSM)提供了各种安全钩子(hook)函数,都在全局类型security_operations结构中,这些函数管理核对象的安全域,仲裁对这些核对象的访问。
Linux安全模块提供了一个通用的安全系统调用,允许安全模块为安全相关的应用编写新的系统调用。
在核引导的过程中,Linux初始化了一系列的虚拟钩子函数,当加载一个安全模块时,使用register_security()函数注册安全模块:
这个函数将设置全局表security_ops,使其指向安全模块的钩子函数指针,从而核可向这个安全模块询问访问控制决策。
Linux安全模块将capabilities能力机制移植到安全模块中,保留了对原有使用capabilities的应用程序的支持。
Linux安全模块的钩子函数包括任务钩子、程序装载钩子、进程间通信IPC钩子、文件系统钩子、网络钩子及模块钩子和顶层的系统钩子。
3.1.4 核SELinux的组织结构
SELinux模块由安全服务器、AVC(AccessVectorCache)、网络接口表、netlink事件通知代码、selinuxfs伪文件系统和hook函数应用六个部分组成。
安全服务器为获得安全策略决定提供通用接口,使模块的其余部分保持独立的安全策略。
这些接口定义在include/security.h中,安全服务器的特定应用能在不改变模块其他部分的情况下被改变。
安全服务器的应用有RBAC(基于角色的访问控制Role-BasedAccessControl)、TE(类型加强TypeEnforcement)的生成和可选的MLS(多级安全Multi-LevelSecurity)。
其中,RBAC和TE策略是高度可配置的,能用于许多不同的安全对象。
安全服务器的源代码在security/selinux/ss目录下载。
AVC提供了从安全服务器获得的访问策略的缓冲区(cache),提高了安全机制的运行性能。
它提供了hook函数高效检查授权的接口,提供了安全服务器管理cache的接口。
与hook函数的接口定义在include/avc.h中,与服务器的接口定义在include/avc_ss.h中,AVC代码在avc.c中。
网络接口表将网络设备映射到安全上下文中。
维护一个独立的表是必要的,因为LSM网络设备没有安全成员。
当网络设备被hook函数第一次查找到时该网络设备就被加入到这个表中,当设备被设置取消或策略重载时移出这个表。
网络接口表提供了查找hook函数以及获得网络设备条目引用或释放引用的接口函数。
该接口定义在include/netif.h中,回调函数在设备配置变化或策略重载时注册。
网络接口表的代码在netif.c中。
netlink事件通知让SELinux模块在策略重载以及强制状态改变时通知进程。
这些通知被用户空间的AVC(libselinux的一部分)用来保持与核一致的状态。
用户空间AVC被用户空间策略强制器(enforces)使用,代码在netlink.c中。
Selinux伪文件系统给进程提供安全服务器的策略API。
selinux提供基于策略API的调用,它包括进程属性、文件属性和策略API三个部分,并被高层的libselinuxAPI封装起来,代码在selinuxfs.c中。
hook函数应用管理与核对象相关的安全信息以及执行核每个操作的访问控制。
hook函数调用安全服务器和AVC得到安全策略并运用这些策略来标识和控制核对象。
hook函数还调用文件系统扩展属性代码获得和设备文件上面的安全上下文。
hook函数在hooks.c中,与核对象相关的安全信息的数据结构定义在include/objsec.h中。
SELinux安全模块及接口如图3-2所示。
图3-2 SELinux安全模块及接口
linux核对于程序的运行、文件系统的超级块和节点以及文件操作、任务操作、网络连接、socket、SystemV进程间通信等提供了对应安全操作函数,这些函数指针都放在安全操作函数结构中,由于结构很大,这里只列出了程序运行的操作函数指针,这些操作函数指针的前缀bprm是binprogram的缩写,其他的操作函数具有类似结构。
security_operations安全操作函数结构在include/linux/security.h中,分析如下:
structsecurity_operations{
int(*ptrace)(structtask_struct*parent,structtask_struct*child);
int(*capget)(structtask_struct*target,
kernel_cap_t*effective,
kernel_cap_t*inheritable,kernel_cap_t*permitted);
int(*capset_check)(structtask_struct*target,
kernel_cap_t*effective,
kernel_cap_t*inheritable,
kernel_cap_t*permitted);
void(*capset_set)(structtask_struct*target,
kernel_cap_t*effective,
kernel_cap_t*inheritable,
kernel_cap_t*permitted);
int(*acct)(structfile*file);
int(*sysctl)(ctl_table*table,intop);
int(*capable)(structtask_struct*tsk,intcap);
int(*quotactl)(intcmds,inttype,intid,structsuper_block*sb);
int(*quota_on)(structfile*f);
int(*syslog)(inttype);
int(*vm_enough_memory)(longpages);
int(*bprm_alloc_security)(structlinux_binprm*bprm);
void(*bprm_free_security)(structlinux_binprm*bprm);
void(*bprm_apply_creds)(structlinux_binprm*bprm,intunsafe);
int(*bprm_set_security)(structlinux_binprm*bprm);
int(*bprm_check_security)(structlinux_binprm*bprm);
int(*bprm_secureexec)(structlinux_binprm*bprm);
……
}
security_operations的结构很大,这里只列出了很少的一部分,下面就一些成员函数说明如下:
bprm_alloc_security:
分配或附加上一个security结构到bprm->security成员上,操作成功时返回0。
bprm_free_security:
释放或删除bprm->securityfield成员上的security结构。
bprm_apply_creds:
计算或设置进程的安全属性,这个进程是由execve操作生成的,这个操作是基于旧属性(当前进程的安全属性current->security)和被set_security函数设置存在bprm->security里的信息。
由于set_security函数是void类型,这个函数不能返回错误,如果属性设置失败,则安全属性值不会被改变。
bprm_apply_creds:
函数在任务锁住的情况下被调用,参数unsafe表示可能不安全地转换安全状态的各种原因。
bprm_set_security:
将安全信息存放到bprm->security成员中。
bprm_check_security:
检查set_security调用时设置的值是否设置到bprm->security中,返回0表示已授予设置的权限。
bprm_secureexec:
返回值是1或0,表示是否是安全运行,这个标识传进ELF解释器的初始堆栈上的补充表里,用来表示libc是否能使用安全模式。
3.2 SELinux策略配置语言
策略是一套指导SELinux安全引擎计算安全决策的规则,它定义了文件客体的类型、进程的域、使用限制进入域的角色及访问许可的规则表达式等。
策略的源代码用SELinux配置语言进行描述。
3.2.1 基本概念
1.主体和客体
主体(subject)和客体(object)是指系统中的元素,主体是访问客体的进程,客体是系统中的一类实体,在系统中定义好了30种不同的客体类别(class),每个class有定义好的许可。
在/etc/security/selinux/src/policy/flask/security_classes中有class的定义,SELinux定义了30个class,列出如下:
securityprocesssystemcapabilityfilesystem
filedirfdlnk_filechr_fileblk_filesock_file
fifo_filesockettcp_socketudp_socketmsgqsemmsg
shmipcnodenetifnetlink_socketpacket_socket
key_socketrawip_socketunix_stream_socket
unix_dgram_socketpasswd
每个class都定义了操作许可,如:
客体file有19个操作许可,列出如下:
ioctlreadwritecreategetattrsetattrlockrelabelfrom
relabelto appendunlinklink renameexecuteswapon
quotaonmountonexecute_no_transentrypoint
2.安全上下文与安全标识符
SELinux给每个主体和客体定义了一个安全上
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- SELinux 概述