selinux策略修改后不生效是因为需先编译(checkmodule)再打包(semodule_package)并加载(semodule -i),且必须指定模块名(-n)、正确设置文件上下文并执行restorecon,否则规则无法触发。

SELinux 策略为什么改了还不生效?
因为策略编译和加载是两步,且内核只认 policy.kern 这个二进制格式——直接改 te 文件或 if 文件不会触发任何变化。
- 必须用
checkmodule -M -m -o policy.mod policy.te编译模块源码 - 再用
semodule_package -o policy.pp policy.mod打包成可加载包 - 最后用
semodule -i policy.pp加载(注意:不是load_policy,那是重启时用的) - 常见错误:
semodule -i报Permission denied?检查当前 shell 是否在sysadm_r或unconfined_r下,普通用户即使 sudo 也受限于角色域
如何让自定义策略不被 semodule -r 清掉?
默认 semodule 安装的是“命名模块”,卸载时按名匹配;但如果你用 -i 装了未命名包(比如没指定 -n myapp),它会被归为“无名模块”,semodule -l 看不见,semodule -r 也删不掉,只能靠 semodule -b /etc/selinux/targeted/modules/active/base.pp 强制回滚整个基础策略——非常危险。
- 安装时务必加
-n myapp:例如semodule -i -n myapp policy.pp - 升级策略时用
-u替换而非-i,否则同名模块会叠加而非覆盖 -
semodule -l | grep myapp能查到才算真正注册成功 - 模块名不能含下划线或点号,只支持小写字母、数字、短横线
audit2why 显示 allowed 但实际被拒绝?
说明 AVC 拒绝日志里混着多个原因,audit2why 只挑了一个路径解释,而真实拦截点可能在另一条策略链上,比如 file_contexts 不匹配导致类型标注失败,后续所有规则都失效。
- 先跑
ausearch -m avc -ts recent | audit2why看完整拒绝链 - 重点检查
ls -Z输出的目标文件上下文是否真为你期望的 type(比如你写了allow httpd_t myapp_log_t:file { read write };,但日志文件其实是var_log_t) - 用
semanage fcontext -a -t myapp_log_t "/var/log/myapp(/.*)?"注册上下文,再执行restorecon -Rv /var/log/myapp - 别跳过
restorecon:SELinux 不自动重标已存在文件,只对新建文件生效
为什么 setsebool -P 不持久?
因为 -P 只把布尔值写进 /etc/selinux/targeted/modules/active/booleans.local,但某些发行版(如 RHEL 8+)默认启用 selinux-policy-devel 包,它会在每次策略更新时清空这个文件并重建 booleans 数据库。
- 确认布尔值是否真写入:
semanage boolean -l | grep your_bool,看default和current列是否一致 - 若不一致,手动运行
semanage boolean -m --on your_bool(这会走数据库接口,比setsebool更底层) - 检查
/etc/selinux/config中SELINUXTYPE是否与当前加载策略名完全一致(大小写敏感),否则semanage会静默失败 - 容器环境里
setsebool基本无效——宿主机策略不传递到容器进程域,得用podman run --security-opt label=type:your_type










