MLS不能仅靠修改/etc/selinux/config启用,必须确保策略编译、内核模块、安全上下文及用户映射全部对齐;验证需执行getenforce和sestatus -b | grep mls,未输出mls即未生效。

MLS策略不是开个开关就能用的
直接在/etc/selinux/config里把SELINUXTYPE=mls一改,系统大概率启动失败或连ls都报错。MLS不是“启用策略类型”那么简单,它要求整个策略编译、内核模块、安全上下文、用户映射全部对齐。默认发行版(RHEL/CentOS 8+、Fedora)的预编译策略包几乎都不带完整MLS支持——你看到的seinfo -x输出里有mls字样,不代表当前加载的策略实际启用了MLS逻辑。
验证当前系统是否真支持MLS运行时
别跳过这步。很多文档教你在sestatus里看Policy from config file:字段,但那只是配置项,不是运行态。必须执行:
getenforce sestatus -b | grep mls
如果sestatus -b没输出mls,或getenforce返回Disabled,说明MLS根本没加载。常见原因包括:
-
selinux-policy-mls软件包未安装(RHEL系需单独装,非默认) - 内核启动参数缺
selinux=1 security=selinux,或显式禁用了mls -
/boot/grub2/grub.cfg里linux行没加enforcing=0临时调试,导致启动卡死
chcon和runcon不能直接设MLS级别
chcon -l s0:c0,c1 file这类命令看似能设级别,但实际生效前提是:当前策略已启用MLS且该级别被策略明确定义。否则会报错Invalid argument或静默失败。正确流程是:
- 先确认策略中已声明敏感度(
sensitivity)和类别(category),例如s0、c0、c1 - 用
seinfo -s查是否存在s0,用seinfo -c查c0是否在策略中注册 - 只有这两者都存在,
chcon -l s0:c0 file才可能成功;否则得先用semanage sensitivity和semanage category添加(需重启策略)
更关键的是:runcon -l s0:c0 myapp启动的进程,其domain必须被策略允许在s0:c0级别运行——否则即使启动了,访问任何资源都会被拒绝。
MLS策略定制远超普通semanage操作
给Web服务加个httpd_sys_content_t标签用semanage fcontext就行,但MLS下要让进程读写某类文件,得同时满足三重约束:
- 进程domain的MLS范围(如
myapp_t:s0-s15:c0.c255)必须包含目标文件level(如s0:c0,c1) - 策略中必须有
allow myapp_t myfile_t:file {read write}规则 - 还得有
mlsconstrain语句明确允许该level组合下的读写,例如:mlsconstrain file { read write } (l1, l2) and l1 domby l2;
这些规则不在semanage命令覆盖范围内,必须手写.te模块,用checkmodule -M(注意-M开关!缺它就不生成MLS逻辑),再semodule_package打包加载。漏掉-M,所有mlsconstrain都会被忽略。
真正难的不是语法,而是level设计本身:一旦设错dominance关系(比如s1没声明高于s0),整个MLS就形同虚设。生产环境极少用纯MLS,大多只用MCS(Multi-Category Security)做轻量隔离——它复用MLS框架但去掉敏感度分级,只靠c0,c1做标签隔离,兼容性好得多。











