一、selinux是什么
selinux是linux内核的一个安全策略模块,本质就是一个控制进程对资源(文件)访问的系统,它由内核加载,运行在内核空间中。
selinux系统由编译器(编译策略代码)、执行程序(selinux引擎)、用户态管理程序(如id、semanage等)、 策略规则代码(由用户指定.te、.fc、.if、.cil)构成。
--------------------------
# 传统编译方式
#.te 文件是描述策略规则文件
#.fc 文件是指定资源(文件)的上下文标签
#.if 文件是宏定义和接口
#.pp 单个最终策略文件
# policy.31整合的策略文件,被放入/etc/selinux/targeted/policy/,由selinux加载
# 1. 将 .te 文件编译为 .mod 文件
checkmodule -M -m -o my_app.mod my_app.te
# 2. 将 .mod 和 .fc 文件打包成 .pp 策略包
semodule_package -o my_app.pp -m my_app.mod -f my_app.fc
--------------------------
#现代方式
#.cil 新的策略文件
#.te可以编译成.cil
#.cil也可以最终编译成.pp
sudo semodule -i my_app.cil
二、selinux 规则有哪些组成部分
组成
是否允许(role) 主体subject 对某个客体 object 做 某个动作 action
主体 subject、动作action、对象 object
一般一条或一组规则被写入后缀名为.te的文件中,等待selinux编译系统编译
role:
访问控制规则:默认(拒绝一切)、allow(允许)
编译策略规则: neverallow(绝对不允许出现允许A干B的规则)
审计日志规则: dontaudit(不记录拒绝的日志)、auditallow(允许的日志也记录)
role + subject(主体,通常是进程(在selinux中也称域)) + object(客体)+object类别(可以是文件、目录、端口、套接字等任何系统资源)+ action(做什么,读写创建、设置读取属性、执行)
object类别:
- file、dir、lnk_file、sock_file、tcp_socket、udp_socket、port
action:
- 针对file ----read, write, create, getattr, setattr, execute, append, unlink 等
- 针对tcp_socket-----name_bind, connectto, send_msg, recv_msg
- 针对port------name_bind
三、一些完整的selinux规则示例
//-----访问规则-------
//允许httpd_t进程对于httpd_log_t这个文件进行读写、追加内容、获取文件属性
allow httpd_t httpd_log_t : file { read write append getattr };
//允许httpd_t进程对http_port_t这个tcp_socket进行端口绑定
allow httpd_t http_port_t : tcp_socket name_bind;
//-----编译策略规则-----
//绝对不允许出现user_t进程对lib_t、user_t这些文件进行写入的规则
neverallow user_t {lib_t user_t}: file write;
//-----日志规则-------
//审计日志保存在/var/log/audit/audit.log中
//系统日志保存在/var/log/messages中
//1. 首先,允许某个域(如sysadmin_t)写shadow文件
allow sysadmin_t shadow_t : file { write };
// 2. 强制记录任何成功的写操作
auditallow sysadmin_t shadow_t : file write;
//一条拒绝记录日志如下,大量的拒绝记录
AVC denied: read access by bad_app_t to shadow_t
// 告诉SELinux:拒绝bad_app_t读shadow_t是正常的,别记日志了
dontaudit bad_app_t shadow_t : file read;
四、selinux高级特性-属性和宏
实际编写selinux策略中,为了简化和模块化,很少直接编写上面那种最基础的规则,而是大量使用属性和宏
domain 所有进程都有这个属性,宏是对客体和action的封装
//这一条意味着所有进程域都可以读取 httpd_log_t文件。
allow domain httpd_log_t : file read;
//下面是一个宏,它封装客体http_port_t和action(name_bind)
corenet_tcp_bind_http_port(httpd_t)
等同于
allow httpd_t http_port_t : tcp_socket name_bind;
五、linux中selinux安全模块执行逻辑
系统启动会挂载一个selinuxfs伪文件系统到/sys/fs/selinux中,伪文件系统保存着策略
avc模块:Access Vector Cache 访问策略缓存
用户空间的se管理工具:semanage seinfo sesearch sediff等
六、selinux 标签
selinux标签可以理解为是主体(subject)和客体(object)的属性,有了策略规则,但是你不能识别主体和客体也是没有用的,所以主体和客体就必须有标签。
标签的组成:
用户:角色:类型:级别
用户:selinux user,以_u结尾
角色:selinux role,以_r结尾
类型:selinux type,类型标识符,以_t结尾
级别:sensitivity level, ,MLS(多级别安全),MCS(多类别安全)
User和Role
这里的用户角色是selinux不是linux系统中的用户和角色,它们属于两套系统
预定义的 SELinux 用户:
user_u: 用于普通登录用户。
staff_u: 用于有部分特权(如可以使用 sudo)的用户。
sysadm_u: 用于系统管理员。
system_u: 用于系统进程和系统对象(文件)。
root: 用于 root 用户。
unconfined_u: 用于不受限制的进程(几乎禁用 SELinux 保护)。
xguest_u: 用于极受限制的来宾用户(例如,只能使用浏览器)。
预定义的 SELinux 角色:
object_r: 几乎所有客体(文件、端口等)都使用的角色。
system_r: 用于系统进程。
user_r: 用于普通用户进程。
staff_r: 用于 staff_u 用户的角色。
sysadm_r: 用于 sysadm_u 用户的角色。
unconfined_r: 用于 unconfined_u 用户的角色。
这些预定义的用户和角色及其基本关系是策略的一部分,是相对“固定”的。
semanage user -l 可以查看用户
Type类别
selinux预定义的标识符,比如上面进程的标识http_t,客体的标识符httpd_log_t
MLS(多级别安全)
层次化等级 sensitivity:category(灵敏度:类别)
例如 s0, s0:c0.c1023 ,s0代表灵敏度,c0.c1023代表类别
这是一个层次化的等级,例如 s0(无分类)、s1(秘密)、s2(机密)、s3(绝密)。
核心规则: 一个主体(进程)只能读取同级或更低级别的客体(文件),但只能写入同级或更高级别的客体。这被称为 “不读向上,不写向下”(No read up, no write down)。
linux系统中默认都使用s0级别,所以级别这个概念可以忽略
####### MCS:多类别安全
通常表示为 c0, c1, c2, ... 或一个范围 c0.c1023。
核心规则: 主体必须拥有客体所要求的所有类别,才能访问它。
示例上下文:
一个运行在容器中的进程可能具有这样的上下文:
system_u:system_r:container_t:s0:c1,c2
这意味着它属于类别 c1 和 c2。它只能访问那些也被标记为 s0:c1,c2(或其子集,取决于策略)的文件。
标签的存储
- 普通文件存储在文件系统中该文件的扩展属性中。
- 进程,内核动态管理(fork 继承父进程的安全上下文标签, exec 会进程转换,存放在内核的进程结构体中)
- 端口,静态指定,策略中规定
- 网络接口,和端口一样
- 网络节点,同样是策略中规定
- 内核对象,内核维护在对应内核对象中
七、selinux bool值
在selinux中什么是bool值?它其实是一组策略规则的总开关。
在编写.te文件的时候,往往一个进程需要一组规则,下面httpd_use_nfs 就是一个bool值
selinux通过setsebool getsebool semanage boolean来控制这个值,对应/sys/fs/selinux/booleans 目录
allow httpd_t nfs_t : file { read write };
# 这是一个条件规则:如果 'httpd_use_nfs' 为真,则启用内部的规则
if (httpd_use_nfs) {
allow httpd_t nfs_t : file { read write };
allow httpd_t mount_t : process { sigchld };
# ... 可能还有另外 5-10 条让 Apache 能正常使用 NFS 所必需的规则
}
八、selinux 上下文标签修正
1、文件上下文修改
对任何文件的操作都可能会影响文件的上下文。
#查看selinux上下文标签
#文件的创建和复制会继承父文件的上下文,移动保留原来上下文
ls -Z 文件名
#修改上下文,下面这种方式修改后,restorecon会还原成原来的上下文。
chcon -u -r -t 文件名
-u 指定用户
-r 指定角色名
-t 指定类型
-v 打印输出
-R 递归操作
-h 修改软链接,不加则直接修改链接的文件
--reference=文件名 参考该文件的上下文来修改
# 默认上下文,预定义的 /etc/selinux/targeted/contexts/files/file_contexts
# 恢复上下文
restorecon -F 文件名
-F 不加F则只恢复type,加-F可恢复所有
#这条命令可以管理上下文
semanage fcontext -a -t -e 文件目录正则
-a 添加
-t 类型
-e 参考某个目录
#正确修改上下文的方式是先用semanage fcontext为某个目录添加上下文,然后再restorecon某个文件或目录。
2、进程和端口上下文修改
#查看进程上下文
ps -eZ | grep 名称
#查看所有端口的策略规则
semanage port -l
#添加删除端口规则
semanage port -a -t -p 协议(tcp|udp) 端口
-a 添加
-t 类型
-p 指定端口
-d 删除
-m 修改
-l 列表
-C 列出自定义的,非预定义的端口项