• 首发公号:Rand_cs

SELinux策略语法以及示例策略

本文来讲述 SELinux 策略常用的语法,然后解读一下 SELinux 这个项目中给出的示例策略

安全上下文

首先来看一下安全上下文的格式:

user : role : type : level

每一个主体和客体都有一个安全上下文,通常也称安全标签、标签,由 4 部分组成(最后一部分 mls 是可选的)

  • user,user 为 SELinux User,而非传统意义上的 Linux User。用户登录系统后,login 程序根据当前策略配置文件,将 Linux User 映射到相应 SELinux User。
  • role,不同 SELinux User 所能扮演的 SELinux Role 不同,而不同 SELinux Role 具有不同的能力(权限)。从而方便地给不同的 Linux User 定义不同的能力。
    • 客体的 role 都默认为 object_r,这是一个内置变量(代码里面写死的)

NOTE:上述两部分则是 SELinux 提供的 RBAC (Role Based Access Control) 安全模型,目前我们大部分示例不会用到这两个部分。但是根据 SELinux 语法规则,必须要定义至少一个 user 和 role。比如说 Android 运用的策略便没有使用 user、role,在 Android 上,所有 user 部分都是 u,所有 role 部分都是 r (客体的 role 为 object_r)

  • type,SELinux 中最重要的部分,SELinux 提供的 TE(Type Enforcement) 安全模型就是基于此来实现的)。每个主体和客体都有自己的类型,但是英文中叫法有点不一样,主体也就是进程的类型叫做 domain,客体(不止文件)的类型就叫做 type,这里看英文文档的时候需要稍微注意一下。
  • mls,此部分与文件机密性有关,这是 SELinux 对 BLP 模型的实现,具体的后面再详述

策略语法

标签各部分定义

定义类型属性

type a;        #定义一个类型 a
type a_t; #定义一个类型 a_t attribute TestFile; #定义一个属性 TestFile type b_t, TestFile; #定义一个类型 b_t,具有属性 TestFile typeattribute a_t TestFile; #使a_t也具有TestFile属性

NOTE:

  • type 和 attribute 两者位于同一个命名空间,也就是说如果定义了 type a,那就不能定义 attribute a
  • a_t,后面有个 t 是表示 "type" 类型,这是 PC 端 SELinux 策略常见写法,但是 Android 不这样用,没有后缀
  • 对于属性的理解,用上面的示例来说,可以理解为 a_t 和 b_t 都具有相同的属性 TestFile,也可以理解为 TestFile 它是一个 {a_t, b_t} 的集合

定义角色

type p_t;      # 定义了一个类型 p_t
role rand; # 定义了一个角色 rand
role rand types p_t; #rand 这个角色与 p_t 关联(具有 p_t 的能力)

对于 role 拥有能力的理解:拿上面的例子来说,加入 p_t 对 a_t 这个类型的文件有读写权限,那么因为 rand 与 p_t 关联,我们就认为 rand 这个角色拥有读写 a_t 类型文件的能力

定义用户

user Lyy roles rand;   # Lyy 这个 SELinux user 可以扮演 rand 这个角色

定义 mls

sensitivity s0;        //定义灵敏度 s0
sensitivity s1; //定义灵敏度 s1
dominance { s0 s1 } //表示 s0 的机密性 低于 s1

这里只是顺便提一下 sensitivity 如何定义,关于 mls 不只有 sensitivity 还有 category,这部分后面的文章再讲,后续的示例策略也不会包含 mls 部分。

客体类别和权限

class file   #定义名为 file 的客体类别。注意没有 ';'
class file { read, write } #针对 file 类别的客体,相关权限有 read、write。注意还是没有 ';' common file { read, write } #定义一个权限集合,此集合名为 file
class file inherits file { create } #上述 file 类别关联的权限也可以如此定义,表示 file 类别的权限有 read write create

Acess Vector Rules

有 4 个,allow、dontaudit、auditallow、neverallow

语法格式都是一样的

# a_t 类型的进程 对于 c_t类型的字符文件 有read、write权限
allow a_t c_t : chr_file { read, write }; # a_t 访问 c_t:chr_file 失败后,不做日志统计
dontaudit a_t c_t : chr_file { read, write };
# a_t 即使成功访问 c_t:chr_file,也要做日志统计
auditallow a_t c_t : chr_file { read, write };
# 绝不允许 a_t 以 {read,write} 的形式访问 c_t:chr
neverallow a_t c_t : chr_file { read, write };

赋予权限的只有 allow 语句,注意 auditallow 语句也没有赋予权限,只是说即使访问成功,也需要记录此条访问.

allow 语句使用的最为广泛

如果某些访问本就应该拒绝,拒绝是我们期望的,SELinux 默认只要拒绝就会有一条日志记录,但是我们可以使用 dontaudit 语句使其不产生日志记录

auditallow 用于某些重要数据访问,因为它们很重要,即使一些进程有权限访问它们,但也希望有日志记录

neverallow 会在策略编译期间起作用,再举个例子

type a1, A;
type a2, A;
type b1, B;
type b2, B;
neverallow A B:file {read};
allow a1 b1:file {read}; #error

编译的时候便会检查到这类错误

类型转换规则

type_transition a_t b_exec_t : process b_t;

a_t 类型的进程执行 b_exec_t 类型的可执行程序后,类型转变为 b_t。通常进程要进行类型转换都是在执行不同的 exec 之后转换的。

此语句要生效,还需要 3 条 allow 语句:

# 允许 a_t 到 b_t 的转换
# type_transition 只是指了一条路说你可以执行这个可执行文件来改变自己的类型,
# 但并没有给出实际的权限
allow a_t b_t : process transition; # a_t 类型的进程 需要对 b_exec_t 类型的可执行文件有 执行、读、获取属性 的权限
allow a_t b_exec_t : file { execute read getattr }; # b_t 需要对 b_exec_t 有 entrypoint 权限
allow b_t b_exec_t : file entrypoint;

文件系统

SELinux 对文件系统上面的文件提供了几种标记方式,标记方式就是说以何种方式决定文件系统上文件的标签

fs_use_xattr ext4 system_u:object_r:fs_t;

fs_use_xattr 针对支持扩展属性的文件系统,比如说 ext4 文件系统,其上的文件的标签由自身的 xattr 中名为 security.selinux 的扩展属性决定。

后面的 system_u:object_r:fs_t表示文件系统这个客体(具体到数据结构就是 超级块)的标签为 system_u:object_r:fs_t

fs_use_task pipefs system_u:object_r:fs_t;

fs_use_task 用于伪文件系统,比如说 pipefs。使用 fs_use_task 修饰的文件系统,其上的文件的标签都由创建它的父进程决定。同样的对于 pipefs 文件系统本身也就是超级块,其标签为 system_u:object_r:fs_t

fs_use_trans devpts system_u:object_r:devpts_t;
type_transition sysadm_t devpts_t : chr_file sysadm_devpts_t;

fs_use_trans,顾名思义,要基于 transition 规则,比如说如上定义了一条 type_transition 规则,意思是说,当 sysadm_t 类型的进程 在 devpts_t 类型的文件系统上面 创建的文件类型应为 sysadm_devpts_t

如果没有 type_transition 规则,那么其上的文件和文件系统的标签是一致的,对于此例来说就是 devpts_t

genfscon proc / system_u:object_r:proc_t
genfscon proc /kmsg system_u:object_r:proc_kmsg_t
genfscon proc /kcore system_u:object_r:proc_kcore_t
genfscon proc /mdstat system_u:object_r:proc_mdstat_t

genfscon 可以很灵活的定义某个文件系统上的文件的标签,从其上的例子应该就能看出,它能指定一个文件系统下某个目录甚至某个文件的标签。

示例策略

该示例策略来自:https://github.com/SELinuxProject/selinux-notebook/tree/main/src/notebook-examples/selinux-policy

按照文档所述将其编译,得到一个 policy.conf 文件,让我们来简单的过一遍,

# 这里是定义客体类别
class security
class process
class system
.... # 这与系统刚启动,selinux 初始化的时候有关,先跳过
sid kernel
sid security
sid unlabeled
sid fs
... # 定义一些权限集合,后面方便与 class 关联
common file {ioctl read write create getattr setattr lock relabelfrom relabelto append map unlink link rename execute quotaon mounton audit_access open execmod watch watch_mount watch_sb watch_with_perm watch_reads }
common socket {ioctl read write create getattr setattr lock relabelfrom relabelto append map bind connect listen accept getopt setopt shutdown recvfrom sendto name_bind }
... # 将 class 与 权限关联起来
class security { compute_av compute_create compute_member check_context load_policy compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot read_policy validate_trans }
class process { fork transition sigchld sigkill sigstop signull signal ptrace getsched setsched getsession getpgid setpgid getcap setcap share getattr setexec setfscreate noatsecure siginh setrlimit rlimitinh dyntransition setcurrent execmem execstack execheap setkeycreate setsockcreate getrlimit }
class system { ipc_info syslog_read syslog_mod syslog_console module_request module_load halt reboot status start stop enable disable reload } # 为了更加动态灵活的控制权限,SELinux 推出 bool,cap 等特性,先跳过
# 如果你想尝试在你的机器上应用此策略,务必务必务必加上 bool xserver_object_manager false;
# 不要问我为什么有三个 务必
policycap network_peer_controls;
bool xserver_object_manager false; # 定义一个类型 unconfined_t
type unconfined_t;
# 定义一个角色 unconfined_r
role unconfined_r;
# unconfined_r 拥有 unconfined_t 的能力
role unconfined_r types { unconfined_t }; # 接下来是一系列的 allow 语句,因为是示例策略,且只有一个类型,这里直接使用通配符 * 授予所有权限
allow unconfined_t unconfined_t:security *;
allow unconfined_t unconfined_t:process *;
.... # 定义 seuser unconfined_u,可以扮演 unconfined_r 这个角色
user unconfined_u roles { unconfined_r };
# 定义 seuser system_u,可以扮演 unconfined_r 这个角色
user system_u roles { unconfined_r }; # 系统启动时初始化相关,先跳过
sid kernel system_u:unconfined_r:unconfined_t
sid security system_u:object_r:unconfined_t
sid unlabeled system_u:object_r:unconfined_t # 定义文件系统标记方式
fs_use_xattr ext2 system_u:object_r:unconfined_t;
fs_use_xattr ext3 system_u:object_r:unconfined_t;
... fs_use_task pipefs system_u:object_r:unconfined_t;
fs_use_task sockfs system_u:object_r:unconfined_t; fs_use_trans mqueue system_u:object_r:unconfined_t;
fs_use_trans devpts system_u:object_r:unconfined_t;
... genfscon selinuxfs / system_u:object_r:unconfined_t
genfscon proc / system_u:object_r:unconfined_t
...

这么一套下来,感觉策略还是挺简单的哈,没那么复杂,像 Android sepolicy、refpolicy 这些策略也就是加了亿点点细节而已,没什么大不了的。

如果想试试这个初始策略,可以按照前文,修改 /etc/selinux/config,然后重启,,,务必记得第一次一定要设置为 permissive 模式

  • 首发公号:Rand_cs

SELinux策略语法以及示例策略的更多相关文章

  1. redis过期策略、内存淘汰策略、持久化方式、主从复制

    原文链接:https://blog.csdn.net/a745233700/article/details/85413179 一.Redis的过期策略以及内存淘汰策略:1.过期策略:定期删除+惰性删除 ...

  2. iblog语法高亮示例

    -------------------------------------------------------------------------------------- iblog 是一款 Sub ...

  3. Java正则表达式的语法与示例

    Java正则表达式的语法与示例 java 正则表达式 正则表达式语法 java正则表达式语法 java正则表达式 概要: Java正则表达式的语法与示例 | |目录 1匹配验证-验证Email是否正确 ...

  4. gzip 与 gunzip 语法与示例

    gzip 与 gunzip 语法与示例 语法: gunzip -c 被压缩的文件 > 已解压的文件示例: 将 catalina.out.gz 文件解压到 catalina.out 文件中: gu ...

  5. (转)Java正则表达式的语法与示例

    转自:http://www.cnblogs.com/lzq198754/p/5780340.html 概要: Java正则表达式的语法与示例 | |目录 1匹配验证-验证Email是否正确 2在字符串 ...

  6. windows组策略实验-本地组策略和域控组策略

    windows组策略实验-本地组策略和域控组策略 本地组策略只对本地计算机有效,域策略是计算机加入域环境后对加入域的一组计算机.用户定义的策略,便于管理 本地组策略: 一.实验环境 Windows 7 ...

  7. [转帖]编写shell脚本所需的语法和示例

    编写shell脚本所需的语法和示例 https://blog.csdn.net/CSDN___LYY/article/details/100584638 在说什么是shell脚本之前,先说说什么是sh ...

  8. java之hibernate之加载策略和抓取策略

    1.加载策略:指hibernate查询数据时,采用什么样的方式将数据写入内存.Hibernate中提供了两种方式来加载数据:懒加载和即时加载. 2.懒加载又称延迟加载,指使用hiberante API ...

  9. 策略模式(Strategy)(策略类,场景不同策略不同,环境策略分离组合,)

    (定义一组算法,将每个算法都封装起来,并且使它们之间可以互换.)   例:button 与 listener ,在使用时具体根据情况实例化listener,做不同的操作. 背景 在软件开发中常常遇到这 ...

  10. Redis详解(十一)------ 过期删除策略和内存淘汰策略

    在介绍这篇文章之前,我们先来看如下几个问题: ①.如何设置Redis键的过期时间? ②.设置完一个键的过期时间后,到了这个时间,这个键还能获取到么?假如获取不到那这个键还占据着内存吗? ③.如何设置R ...

随机推荐

  1. mysql错误ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

  2. 【Oracle】ORDER BY 2 DESC,1 ASC,同时对多个数据列进行不同的顺序排序&Oracle中的 (+)

    最初想对 travelled_distance 降序排列 ,如果有两个或者更多的用户旅行了相同的距离, 那么再以 name 升序排列 然后就写了下面的 SELECT U.NAME name, NVL( ...

  3. 力扣584(MySQL)-寻找用户推荐人(简单)

    题目: 给定表 customer ,里面保存了所有客户信息和他们的推荐人. 写一个查询语句,返回一个客户列表,列表中客户的推荐人的编号都 不是 2. 对于上面的示例数据,结果为:  解题思路: 本题最 ...

  4. 【pytorch学习】之数据操作

    1 数据操作 为了能够完成各种数据操作,我们需要某种方法来存储和操作数据.通常,我们需要做两件重要的事:(1)获取数据: (2)将数据读入计算机后对其进行处理.如果没有某种方法来存储数据,那么获取数据 ...

  5. PolarDB-X 2.1 新版本发布 让“MySQL 原生分布式”触手可及

    简介: PolarDB-X 2.1 是 PolarDB-X 非常重要的版本,也是第一次 PolarDB-X 分布式数据库的产品可以作为企业级的分布式数据库真正部署到客户的生产环境使用. PolarDB ...

  6. 同为博客,不同风格 ——Hexo另类搭建

    ​简介:通过阿里云云开发平台快速由Hexo创建赛博朋克风格的博客. 一  .通过云开发平台快速创建初始化应用 1.创建相关应用模版请参考链接:Hexo博客框架-轻量.一令部署 2.完成创建后就可以在g ...

  7. DataX在数据迁移中的应用

    简介: DataX在数据迁移中的应用 1. DataX定义 首先简单介绍下datax是什么.DataX是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL.Oracle.SqlSe ...

  8. Serverless 时代下大规模微服务应用运维的最佳实践

    简介: 原来的微服务用户需要自建非常多的组件,包括 PaaS 微服务一些技术框架,运维 IaaS.K8s,还包括可观测组件等.SAE 针对这些方面都做了整体的解决方案,使用户只需要关注自己的业务系统, ...

  9. [FE] G2Plot 更新图表的两种方式

    第一种是使用 G2Plot 对象上的 changeData 方法,如果不涉及到全局 title 等这些的更改,可以采用这种方式. 也就是说,只有纯数据方面的变动,使用 changeData 更新图表数 ...

  10. 2019-7-2-WPF-通过-ReadyToRun-提升性能

    title author date CreateTime categories WPF 通过 ReadyToRun 提升性能 lindexi 2019-07-02 10:29:55 +0800 201 ...