需求:针对某个设备文件,阻止除特定进程以外的进程写入。
拿 /dev/tty20
做试验。实验环境:Fedora 38,x64 虚拟机。
给设备打标签,阻止普通写
-
创建
.te
策略文件之最最基础版:1policy_module(tty20, 1.0.0) 2 3type tty20_t;
-
构建并加载策略模块:
1make -f /usr/share/selinux/devel/Makefile 2semodule -i tty20.pp
这里参考了这篇问答 。
-
尝试变更
/dev/tty20
的标签:1chcon -t tty20_t /dev/tty20
大概率会因为缺少必要的权限而报错。
-
查看最近 AVC 类型的审计日志:
1ausearch -m AVC -ts recent
可尝试直接转换为新规则:
1ausearch -m AVC -ts recent | audit2allow -R
-
将新规则加入
.te
策略文件。不断重复步骤 2 至 5,直到chcon
成功。 -
最后恢复
/dev/tty20
的标签:1restorecon -v /dev/tty20
经过几轮迭代后的 .te
策略文件:
1policy_module(tty20, 1.0.0)
2
3type tty20_t;
4
5require {
6 type unconfined_t;
7}
8
9# 允许处于 `unconfined_t` 域的一般进程: 读取 打上标签 摘除标签
10# vvvvvvvvvvvvvvvvv vvvvvvvvv vvvvvvvvvvv
11allow unconfined_t tty20_t:chr_file { open read getattr relabelto relabelfrom };
12# 允许将此类型作为 /dev 文件系统的标签,i.e. associate
13dev_associate(tty20_t)
最终实现的效果:unconfined_t
进程对 /dev/tty20
可读可重打标签,但不可写。
走过的弯路:
- 参考该 Red Hat 的文档
操作,最后一步运行
.sh
总是失败。后来才发现是里面包含了生成文档的动作,而该动作又把新标签当做 domain…… - 在尝试解决上一个问题时,有尝试通过
files_type(tty20_t)
将新标签加入file_type
属性。这样做不能解决问题,也会导致后续unconfined_t
对tty20_t
有全部权限。
注意:配置策略途中若遇到看不懂的“类函数语句”,应直接进入 /usr/share/selinux/devel
进行搜索。
创建特殊域进程,允许写设备
参考了这篇 Gentoo 的 Wiki 。这个系列 Wiki 写得不错。
总体思路:为可执行文件和进程分别创建标签和域,并设立相应的类型转移(type transition)规则。
-
可执行文件标签:
1type tty20_writer_exec_t; # 按惯例以 `_exec_t` 结尾 2 3# 允许被(处于 `unconfined_t` 域的)Bash 进程: 打上标签 摘除标签 执行 读取 4# vvvvvvvvv vvvvvvvvvvv vvvvvvv vvvvvvvvvvvvvvvvv 5allow unconfined_t tty20_writer_exec_t:file { relabelto relabelfrom execute getattr read open }; 6 7# 允许将此类型作为文件系统的标签,i.e. associate 8fs_associate(tty20_writer_exec_t)
-
进程域:
1type tty20_writer_t; 2# 将新类型(域)与 role 相关联,不然会出现 SELINUX_ERR 类型的审计日志 3role unconfined_r types tty20_writer_t; 4 5# 类型转换规则及权限 6type_transition unconfined_t tty20_writer_exec_t : process tty20_writer_t; 7allow unconfined_t tty20_writer_t:process transition; 8 9# 允许该域进程对拥有 tty20_t 标签的设备文件进行:读、写、打/摘标签 10allow tty20_writer_t tty20_t:chr_file { open read getattr relabelto relabelfrom write }; 11 12permissive tty20_writer_t;
.te
策略文件总览:
1policy_module(tty20, 1.0.0)
2
3require {
4 type unconfined_t;
5 role unconfined_r;
6}
7
8type tty20_t;
9
10allow unconfined_t tty20_t:chr_file { open read getattr relabelto relabelfrom };
11dev_associate(tty20_t)
12
13############################################################################################
14
15type tty20_writer_exec_t;
16
17allow unconfined_t tty20_writer_exec_t:file { relabelto relabelfrom execute getattr read open };
18fs_associate(tty20_writer_exec_t)
19
20############################################################################################
21
22type tty20_writer_t;
23role unconfined_r types tty20_writer_t;
24
25type_transition unconfined_t tty20_writer_exec_t : process tty20_writer_t;
26allow unconfined_t tty20_writer_t:process transition;
27
28allow tty20_writer_t tty20_t:chr_file { open read getattr relabelto relabelfrom write };
29
30permissive tty20_writer_t;
参考资料
- Chapter 8.2. Creating and enforcing an SELinux policy for a custom application , Using SELinux, RHEL 8
- How does a process get into a certain context , SELinux Tutorials, Gentoo Wiki
- What to do about “invalid context” , Fedora SELinux mailing list (selinux@lists.fedoraproject.org )
- SELinux: How do you create a custom label for files , Unix & Linux Stack Exchange
- The SELinux Notebook