彻底搞懂android selinux系列一 (linux selinux)

一、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 列出自定义的,非预定义的端口项

build with Hugo, theme Stack, visits 0