type_transition

发布于

上一篇 SELinux 在管什么 把地图铺开:域、AVC、初始化、四段标签、TE allow。本文只挖一块地形——type_transition:进程(以及新建文件)的 Type 何时被改写、规则存在哪、和 allow 怎么配合。

仍默认 Fedora Targeted。若域 / 初始化 / TE 还不熟,先读概念文再回来。

适用读者

需要概念文里的底子,再加上一点「想看清服务域从哪来」的动机。

  1. 已读懂 SELinux 概念 中的域、初始化、TE、AVC。
  2. 知道 fork / execve:新程序映像是在 exec 时换上的。
  3. 不要求会写 .te;文末有只读查询命令即可跟上。

它解决什么问题

TE 的 allow 回答:当前 Type 能不能对另一 Type 做某操作。
默认创建/启动时,新对象的 Type 往往靠继承(子进程继承父域;新文件常继承父目录类型)。

type_transition 回答另一件事:在特定条件下,不要用继承默认,而强制落成策略指定的 Type。
服务要进 httpd_t、日志文件要落成某类 Type,靠的就是它(外加配套 allow)。

规则长什么样

策略语言里的基本形态:

type_transition 源类型  相关类型 : class  结果类型;

两类最常见。

进程域转换

type_transition 源域  可执行文件类型 : process  目标域;

概念例:

type_transition init_t httpd_exec_t:process httpd_t;

处在 init_t 的进程去 exec 类型为 httpd_exec_t 的文件时,新进程域默认为 httpd_t。

文件类型转换

type_transition 源域  父目录类型 : file  新文件类型;

某域在某类目录里创建文件时,新 inode 的默认 Type 由规则指定,而不是傻继承。dir、lnk_file 等 class 同理。

命名上常见 *_exec_t → *_t,这是惯例,不是内核写死的万能公式。叫什么 Type、从谁转到谁,都由策略决定。

表从哪里来

type_transition「表」不是另维护的 Excel,而是已加载 SELinux 策略里所有 type_transition 规则的集合。

定义路径:

  1. 策略源码(多为 .te)里写语句,或用宏(如 domain_auto_trans)一次生成 transition + 一批 allow。
  2. 配 .fc:路径 → 默认文件标签(如 /usr/sbin/httpd → httpd_exec_t)。
  3. 打成 .pp,经 semodule -i 或开机加载进内核。

发行版上这些在 selinux-policy-targeted 的各个策略模块里(semodule -l 可见 httpd、sshd、init 等)。
内核执行时查的是当前已加载策略;sesearch -T 查的也是这份。

和 allow 的关系:同属 TE(Type Enforcement) 机制,但是两类规则——transition 管「默认变成谁」,allow 管「允不允许这样及之后的操作」。

exec 换域逐步

以「systemd / init 相关域启动 httpd」为叙事(真实源域名因版本可能是 init_t 的变体,思想相同)。

父进程域: init_t(示意)
文件标签: /usr/sbin/httpd → httpd_exec_t
希望结果: 子进程 → httpd_t

收集键

execve 时内核拿到:

查 transition

找是否存在 type_transition 旧域 文件type : process 新域。

再过 allow(TE)

transition 只回答「默认想变成谁」。还要有配套 allow,否则转换失败或 exec 被拒。常见相关包括:

方向 大致含义
旧域 → 文件 type:execute 等 能不能执行这个文件
旧域 → 新域:process 上的 transition 允不允许从旧域转到新域
文件 type 作为新域的 entrypoint 这个文件能不能当进入该域的入口
Role 约束 当前 Role 是否允许关联目标域

成功换域 ≈ transition 命中 AND 相关 allow 通过 AND Role 等约束通过。

写入新进程

成功则新进程第三段变成目标域,例如 system_u:system_r:httpd_t:s0。之后一切 TE 检查按新域,不再按父域。

失败时 AVC 里常见 execute / transition / entrypoint 被拒——读法见概念文「名词解释 · AVC」。

Entrypoint 与 exec 类型

安全上不希望「任意 bin_t 被 exec 都能进 httpd_t」。

常见拆法:

策略规定:只有特定入口类型配合 transition,才能进入对应域。
所以可执行文件的 Type 是 transition 的输入键,不是装饰性后缀。

和初始化的关系

概念文里的 SELinux 初始化与本文的关系:

会话初始化 exec type_transition
时机 用户登录映射 某次 execve
结果 会话初始域(如 unconfined_t) 从旧域换到新域(如 httpd_t)
典型谁 交互式 shell / 桌面会话 systemd 拉起的 confined 服务

服务进程的「初始域」在实践中往往就是:父域 exec 入口文件 → type_transition → 服务域。
之后若再 exec 并命中其它规则,叫继续换域,不是又登录一次。

你在 unconfined_t 的 shell 里跑普通命令:很多没有指向其它域的 transition,于是一直停在原域——这是预期,不是 transition「坏了」。

文件 transition

创建文件时同构:键变成(进程域 × 父目录 Type × file/dir…),查 transition 得到新 inode 默认 Type,同样要配套 allow。

注意和运维命令的分工:

策略模块里怎么写

人写策略时常见三件套(发行版已写好,此处仅帮助读懂):

# .te(概念)
type httpd_t;
type httpd_exec_t;
domain_auto_trans(init_t, httpd_exec_t, httpd_t);  # 宏 ≈ transition + allow

# .fc
/usr/sbin/httpd  --  system_u:object_r:httpd_exec_t:s0

加载进内核后,transition 表与 allow 表都来自这些模块。整套 SELinux 还可粗分为:内核裁决、用户态工具(semodule / restorecon / sesearch)、策略内容(targeted + 大量 .pp)——细节不必一次记完,知道「规则在策略模块里」即可。

本机怎么查

# 需要 setools-console(包名因发行版可能略异)
sudo dnf install setools-console

# 谁会 transition 到 httpd_t
sesearch -T -t httpd_t

# 某源域在 process 上的 transition
sesearch -T -s init_t -c process

# 某域作为主体的 allow(TE 权限表;结果很多,建议加 -c / -t)
sesearch -A -s httpd_t -c file

# 对照:文件类型 vs 进程域
ls -Z /usr/sbin/httpd
ps -eZ | grep httpd

读 AVC、真实拒绝案例见 Cursor Remote SSH 与 SELinux。

小结

地图在 SELinux 在管什么;本文是换域这块地形。

评论

可对整篇留言,或划选正文中的句子后评论该段。

登录后即可发表评论。

  • 还没有公开评论。
↑