内容来源:《Linux内核安全模块深入剖析》———李志
Linux内核安全模块
安全模型:BLP模型——解决私密行——禁止上读,禁止下写
BIBA模型——解决完整性——禁止上写,禁止下读
分时复用时代:角色的访问控制
PC时代:类型增强(TE)——控制进程
信任的度量:完整性校验值、数字签名
第一部分 自主访问控制
自主:使用计算机的人决定访问策略-------->应用
访问控制:标记——主、客体 策略——允许主体对客体i做什么
优缺点:优:设计简单 缺:安全性相对较差
一.主体标记与进程凭证
(include/linux/sched.h)
1.1uid和gid
uid——标记运行进程的用户——real_cred
gid——标记用户组——cred
1.uid和gid
英文名称——中文名称——作用
(r)uid——资源统计和资源分配
euid——有效id——内核做特权判断、IPC通信和密钥
suid——特权有关,暂存euid的值
fuid——文件系统id——文件系统访问相关的访问控制中判断操作许可
gid类似uid
补充组id——访问控制权限检查
group id——与特权无关
二.客体标记与文件属性
2.1文件属性
文件:包含文件的内容(数据),元数据
元数据
内容:存取访问方式、创建日期、所在设备、属主和属组以及允许位等。
存储位置:文件系统的inode中
2.2系统调用
文件——内核修改——调用相关函数(chown/stat)
三.操作与操作许可
1.基本操作:
读、写
额外操作:
1.文件:执行——本质:进程替换自身的内存——将文件内内容置入进程的代码空间和数据空间
2.目录:读——列出目录的内容 写——自目录中增/删 文件/子目录
3.管道——pipefs文件系统上的匿名文件 命名管道/设备——特殊类型的文件,执行无意义
4.IPC——不是作为特殊文件实现的,故只有读写操作。
5.socket——无定义操作许可。
6.key(密钥)——可类比文件 key——文件 keyring——目录
操作:1.读 2.写 3.搜索 4.链接 5.查看 6.设置属性(setattr)
2.允许位
同主,同组,其他组的读、写、执行
1.文件——9bit IPC——6bit 密钥——18bit
3.设置位
1.文件
增加3个允许位:setuid setgid sticky id
setuid:
当一个文件setuid=1——进程的euid、fsuid修改为文件属主id——进程读取内容+文件属性部分数据
setuid:
类似setuid,不同:进程的euid、fsuid修改为文件的属组id。与特权无关。
sticky id
Linux系统中无作用
2.目录
setuid:无任何作用
setuid:在此目录下创建的文件和子目录的属组自动初始化为目录的属组
sticky id:在其下的文件/子目录只能被该文件/子目录的属主删除
四.访问控制列表
1.作用范围
只作用文件和目录。
2.实现方式:
扩展属性被实现为一个数组,数组项又分为属性名和属性值。
属性名:字符串 属性值——任意类型
和访问控制列表相关的扩展属性有两个
属性名分别是system.posix_acl_access和system.posix_acl_default。
结构:tag id permission-bits(3bit)
id:用户的id或组id
permission-bits:分别表示读、写、执行
3.操作许可
1.进程fsuid=文件属组————判断进程申请的操作是否在ACL_USER_OBJ项的permission-bits中,若是,返回允许,否则返回拒绝
2.进程fsuid=文件的某一项ACL_USER中规定的id——————判断进程申请的操作是否在该项的permission-bits和ACL_MASK项的permission-bits的交集中,若是,返回允许,否则返回拒绝
3.进程fsuid 或 补充组中的任何一个gid = 文件的属组或某一项ACL_GROUP中规定的id
(1):无ACL_MASK项,判断进程申请的操作是否在该项的permission-bits中,若是,返回允许,否则返回拒绝
(2):有ACL_MASK项,则判断进程申请的操作是否在该项的permission-bits和ACL_MASK项的permission-bits的交集中,若是,返回允许,否则返回拒绝
4.如果进程申请的操作出现在ACL_OTHER项的permission-bits中,返回允许,否则返回拒绝
4.类型
(1)ACCESS —— system.posix_acl_access ————判断进程对文件或目录的操作许可
(2)DEFAULT —— system.posix_acl_default————参与确定目录中新文件或新目录的初始ACCESS型ACL
五.能力
1.分类
1.超越允许位控制和属主控制
2.无法纳入允许位操作
2.列举
1.文件
序号名称功能1chmod改变文件的属主或属组2dac_override不顾允许位限制对文件进行读、写、执行操作,对目录进行读、写、通过操作3dac_read_search不顾允许位限制读文件、读目录、通过目录4fowner拥有此能力的进程被视为fsuid等于文件的属主id5fsetid能力和文件的set-group-id有关6linux_immutable修改文件的immutable标志,拥有此标志的文件无法被删除7setfcap设置文件能力8lease进程可以通过系统调用fcntl对文件建立读lease或写lease
2.进程
序号名称功能1kill进程可以通过系统调用kill向另一个进程发送信号2setgid修改进程凭证中的各种gid3setuid修改进程凭证中的各种uid4setpcap修改进程的能力集5sys_chroot改变进程的根目录6sys_ptrace无视内核对跟踪进程有两个限制7sys_nice无视内核限制进程只能将自己的nice值增加,还可以修改进程的调度算法
3.网络
序号名称功能1net_bind_service可以绑定系统特权端口(端口号小于1024)2net_broadcast此能力未被使用3net_admin配置网络参数4net_raw使用RAW型socket
4.ipc
序号名称功能1ipc_lock主要用于锁定内存2ipc_owner进程在内核操作许可检查中被视为euid等于IPC客体的属主id
5.系统
序号名称功能1block_suspend可以实施阻止系统挂起的操作2syslog系统调用syslog的有些参数的要求调用者拥有此能力,另一个是当/proc/sys/kernel/kptr_restrict文件内容为“1”时,拥有此能力的进程可以查看到内核通过/proc伪文件系统暴露的地址3sys_admin一个缩小的“root”4sys_boot启动系统5sys_module加载内核模块6sys_pacct以打开或关闭系统对进程进行统计的功能7sys_resource涉及文件系统、IPC、进程等领域。包括调整文件系统的保留空间、设置文件系统的日志参数、设置进程内存布局等8sys_time系统时间和硬件时间9sys_tty_config调用系统调用vhangup需要此能力10wake_alarm设置系统闹钟
6.设备
序号名称功能1sys_rawio操作I/O端口和读伪文件/proc/kcore需要此能力2mknod创建设备文件需要此能力
7.审计
序号名称功能1audit_write用于向内核写入或修改审计规则2audit_control配置内核审计子系统的参数
8.强制访问控制(MAC)
序号名称功能1mac_override有的MAC机制拥有mac_override能力的进程可以不受MAC机制控制2mac_admin配置MAC机制参数
第二部分 强制访问控制
1.概述
LSM(inux Security Module)—— 体现为一组安全相关的函数
目的:对用户态进程进行强制访问控制
2。工作原理
SELinux安全机制:
基于角色的访问控制、类型增强、多级安全
1.SELLinux多级安全
小于等于大于包含不相关支配支配被包含被支配被支配不相关相等被支配相等支配不相关不相关不相关相关
2.BLP模型
读写支配✔✘相等✔✔被支配✘✔不相关✘✘
3.机制
1.安全上下文
定义:SELinux中对主体和客体的标记
访问三要素:主体、操作、客体
主体——进程
进程的安全上下文被记录在内核中进程的task_struct之中。具体来说,就是进程的task_struct有一个成员叫cred,cred中有一个指针成员叫security,security是一个“void *”指针,SELinux会申请内存,将安全上下文相关的数据记录在这里
客体——常见为文件
2.构成
四元组:SELinux User、Role、Type、MLS
MLS包含敏感度和组别
3.安全上下文的初始值
1.进程的安全上下文
(1)创建进程时,子进程的安全上下文是父进程的安全上下文的副本
(2)Linux系统中第一个进程的安全上下文是SECINITSID_KERNEL所对应的安全上下文
sid:为提高效率,SELinux代码用数组项的序号来代表安全上下文
2.安全上下文的改变
(1)进程调用execve系统调用
(2)通过写/proc/self/attr/current文件
第三部分 完整性保护
一.概述
1.1基本概念
目的:防止数据被篡改
IMA:完整性度量体系架构 EVM:扩展验证模块
可信计算架构:
应用:PTS(Platform Trust Services)
库:TSS(Trusted Software Stack)
内核:IMA、EVM、TPM驱动
启动:GRUB-IMA TBOOT
硬件:TPM
TPM的运用:管理密钥、执行加解密运算、数字签名、安全存储数据。
1.IMA
功能:
(1)收集——度量文件,计算文件的哈希值。
(2)存储——将度量值放入内核维护的一个列表中
(3)证明——如果TPM硬件存在,使用TPM对TPM分配给IMA的PCR的值签名
(4)评估——判断文件是否被篡改
2.EVM
功能:保护——保护文件的安全相关的扩展属性
注:IMA和EVM针对的是离线攻击的威胁
二.架构
2.1钩子
IMA钩子函数
● ima_file_mmap
● ima_bprm_check
● ima_file_check
● ima_module_check
● ima_inode_post_setattr
● ima_inode_set_xattr
● ima_inode_removexattr
EVM钩子函数
● evm_inode_setattr
● evm_inode_post_setattr
● evm_inode_init_security
● evm_inode_setxattr
● evm_inode_post_setxattr
● evm_inode_removexattr
● evm_inode_post_removexattr
2.2策略
2.2.1IMA策略:
rule format: action [condition ...]
action: measure | dont_measure | appraise | dont_appraise | audit
|
| measure即度量———将文件的完整性度量值存储在内核的一个链表中
| appraise即评估———将现度量值与扩展属性“security.ima”的值比较,返回一个结果
| audit即审计————生成一条审计日志,传给内核审计子系统
|
condition:= [ base | lsm ] [option]
base: [[func=] [mask=] [fsmagic=] [fsuuid=] [uid=] [fowner=]]
lsm: [[subj_user=] [subj_role=] [subj_type=] [obj_user=] [obj_role=] [obj_type=]]
option: [[appraise_type=]]
|
| IMA对文件做选择度量:base/lsm
|
func:= BPRM_CHECK | MMAP_CHECK | FILE_CHECK | MODULE_CHECK
mask:= MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC
fsmagic:= hex value fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6)
uid:= decimal value fowner:=decimal value
|
| func:对应相应的钩子函数
| fsmagic:内核文件系统super_check结构体中s_magic的值
| lsm:SELinux
| option:appraise_type————>imasig
|
2.2.2扩展属性
EVM的完整性保证———加密算法
2.2.3密钥
作用:保护完整性度量值
密钥:evm-key _evm _ima
evm-key
类型:encrypted
密钥(evm-key)+消息输入(安全相关的扩展属性的值)-----消息摘要(HMAC值)
_evm 数字签名(公钥和私钥)
EVM子系统在内核钥匙链(keyring)“_evm”中寻找用于验证签名的公钥
_ima
IMA扩展————ecurity.ima中直接存储一个和文件完整性校验值相关的数字签名
公钥存储在内核钥匙链(keyring)“_ima”
2.2.4用户态工具
签名的生成:
IMA —— security.ima
1.非加密哈希——内核启动时有参数“ima_appraise=fix,由内核在进程访问文件时填入当时的哈希值
2.数字签名——用户态工具写入
EVM——security.evm
1.HMAC——内核启动时有参数“evm=fix”,由内核在进程访问文件时填入当时计算的结果
2.数字签名——用户态工具写入
密钥的生成
1.evm-key
TPM硬件存在:
keyctl add trusted kmk "new 32" @u
让内核借助TPM产生一个类型为“trusted”,描述为“kmk”,长度为32B的密钥
keyctl add encrypted evm-key "new trusted:kmk 32" @u
让内核借助刚才产生的“kmk”密钥,产生一个类型为“encrypted”,描述为“evm-key”,长度为32B的密钥
无TPM硬件:
keyctl add user kmk "`dd if=/dev/urandom bs=1 count=32 2>/dev/null`" @u
让内核产生一个类型为“user”,描述为“kmk”,长度为32B,内容为自/dev/urandom读出的随机数的密钥
keyctl add encrypted evm-key "new user:kmk 32" @u
让内核借助刚才产生的“kmk”密钥,产生一个类型为“encrypted”,描述为“evm-key”,长度为32B的密钥
2._ima和_evm
用openssl生成公私钥对
ima_id=$(keyctl newring _ima @u)
evmctl import /etc/keys/pubkey_ima.pem $ima_id
evm_id=$(keyctl newring _evm @u)
evmctl import /etc/keys/pubkey_evm.pem $evm_id
加载流程:
系统启动的早期被加载入内核
1.有TPM硬件 假设密钥相关的数据被存入/etc/keys/目录下
keyctl add trusted kmk "load `cat /etc/keys/kmk`" @u
keyctl add encrypted evm-key "load `cat /etc/keys/evm-key`" @u
无TPM硬件
cat /etc/keys/kmk | keyctl padd user kmk @u
keyctl add encrypted evm-key "load `cat /etc/keys/evm-key`" @u
2.通知内核
echo "1"> /sys/kernel/security/evm
3.公钥的加载
# search for EVM keyring
evm_id=`keyctl search @u keyring _evm 2>/dev/null`
if [ -z "$evm_id" ]; then
evm_id=`keyctl newring _evm @u`
fi
# import EVM X509 certificate
evmctl import /etc/keys/x509_evm.der $evm_id
三.伪文件系统
四命令行参数
五.dm-verity
Mapped Device
|
|
Target Devidce(dm-verity)
|
|
Data Device Hash Device
Data Device:存储数据————保证数据完整性
Hash Device:存储哈希值
哈希设备中的数据建立:用户态工具“格式化”相应设备——在内核建立dm-verity设备
第四部分 审计和日志
4.1概述
目的:记录系统关键行为
审计:在内核中根据设定的规则生成审计消息
日志:自觉行为。多个守护进程(daemon)在执行过程中发送日志消息给日志服务进程,后者将消息记录到日志文件中
接口:netlink套接字
4.2架构
4.2.1审计消息来源
1.内核:内核中的一些子系统会使用audit子系统提供的函数产生audit日志消息
2.用户态守护进程:通过netlink套接字发送消息给内核,内核转发给用户态的auditd
3. auditd:自身产生的audit消息直接发送给audispd
4.系统调用————————审计
内核作为独立的个体做正式的检查,它检查的对象是用户态进程,检查点设置在系统调用的实现里面
4.2.2规则列表
User、Task、Entry、Watch、Exit和Type ———— udit_filter_list数组的第0~第5个元素
4.2.3对文件的审计
(1):使用文件Inode号
(2):文件的路径名——依赖关键数据结构audit_watch
(3):目录的文件路径名
4.3接口
netlink套接字
4.4规则
(1):队列——五个规则队列:User、Task、Entry、Exit与Type
(2):动作
never——不审计 always——审计
(3)系统调用
表示哪个或哪些系统调用下做审计
版权归原作者 小蟹不忙 所有, 如有侵权,请联系我们删除。