selinux模块安装失败主因是未编译源码:须用checkmodule编译.te为.mod,再用semodule_package打包为.pp;卸载后需手动清理布尔值、端口、文件上下文等残留配置。

semodule -i 安装模块时为什么提示 “Invalid module”
常见错误是模块文件没编译,直接拿 .te 源文件去安装。SELinux 模块必须是二进制格式(.pp),semodule -i 不接受源码。
- 正确流程:用
checkmodule编译.te→ 用semodule_package打包成.pp→ 再用semodule -i -
checkmodule -M -m -o policy.mod mypolicy.te生成中间模块对象,-M启用 MLS(若策略启用 MLS,漏掉会编译失败) - 打包时路径不能含空格或特殊字符,
semodule_package -o mypolicy.pp -m policy.mod,注意-m后必须是checkmodule输出的.mod文件,不是.te - 如果系统启用了 MLS 但模块未声明
require { type my_t; };或缺少mlsconstrain相关语句,checkmodule可能静默失败,建议加-v查看详细报错
semodule -r 卸载后策略没生效或残留规则
semodule -r 只移除模块本身,不回滚该模块曾插入的布尔值、端口类型、文件上下文等配置——这些是独立于模块生命周期的运行时状态。
- 卸载前先查模块是否带布尔开关:
semanage boolean -l | grep mymodule,若有,需手动重置:setsebool mymodule_enable off - 检查是否注册了端口:
semanage port -l | grep myport,卸载模块后端口映射仍存在,得用semanage port -d -p tcp 8080显式删除 - 文件上下文规则(
semanage fcontext)同样不会随模块卸载自动清理,遗漏会导致后续 restorecon 误标文件 - 执行
semodule -r后,务必运行restorecon -Rv /path或重启相关服务,否则旧上下文可能继续生效
自定义模块打包时 require 块里该写什么
require 块不是“导入依赖”,而是向编译器声明当前模块将引用哪些已有类型、属性、角色——漏写会导致 checkmodule 报 undefined type/attribute 错误;多写无害但可能掩盖权限设计问题。
- 必须声明所有在
allow、type_transition等规则中出现的自定义类型(如myapp_t)和基础类型(如bin_t、etc_t) - 若规则中用了
sysadm_r角色,就得在require里写role sysadm_r types myapp_t;;只写type myapp_t;不够 - 不要把标准策略里的宏(如
corenet_tcp_connect_http_port)塞进require——那是接口,不是类型,应通过interface调用 - 用
seinfo -t或sesearch -A -s unconfined_t辅助确认目标类型是否存在、是否拼写一致(SELinux 类型名区分大小写)
模块加载后 AVC 拒绝仍在发生,但 semodule -l 显示已启用
模块加载成功 ≠ 策略立即覆盖所有进程,尤其当进程已在运行且其域未重启时,旧域仍按旧策略执行。
- 检查模块是否真被激活:
semodule -l | grep mymodule输出应含版本号,如mymodule 1.0;若只有名字没版本,说明加载失败但没报错(常见于 SELinux 处于permissive模式下静默跳过) - 确认当前进程是否运行在新域:用
ps -eZ | grep myapp,看输出中上下文第三段是否为mymodule_t;不是的话,需要kill进程再由 init 重启,或手动runcon -t mymodule_t -- myapp测试 - AVC 日志里
comm="myapp"和scontext=unconfined_u:unconfined_r:unconfined_t:s0表明进程根本没进入你的域,模块规则压根没触发 -
ausearch -m avc -ts recent | audit2why是比audit2allow更准的诊断方式——它告诉你“为什么这条拒绝合理”,而不是直接建议加规则
最常被忽略的一点:模块编译时用了 -M 参数,但目标系统 SELinux 策略实际是 non-MLS 模式(sestatus -v 查 Policy MLS Status),此时模块无法加载,且错误提示极不明确。










