要深入掌握 SELinux,首先需要了解它的起源。这套强制访问控制系统由美国国家安全局(NSA)主导研发,被认为是 Linux 安全领域最具影响力的子系统之一。在 Linux 社区的协作下,NSA 构建了一种全新的访问控制机制:在这种机制下,每个进程只能访问与其任务直接相关的文件,无法越界操作。SELinux 默认集成在 Fedora 和 Red Hat Enterprise Linux 中,其他 Linux 发行版也能通过软件包轻松安装。该项目于 2000 年以 GNU GPL 许可证发布,自 Linux 内核 2.6 版本起被正式纳入内核。
传统 Linux 环境下,我们依赖的是 DAC(自主访问控制),而 SELinux 引入的是 MAC(强制访问控制)。两者最根本的区别在于:DAC 模式下进程几乎不受束缚,权限完全由用户和文件权限决定;MAC 模式下所有行为都由预设的策略规则严格定义,进程能被有效限制。策略会明确告知系统:哪些资源(例如文件、端口)是受限进程可以访问的。默认情况下,任何未被明确允许的操作都会被拒绝。这种“默认拒绝”的设计哲学,正是安全防护的关键。
SELinux 的工作类型
SELinux 共有四种工作模式,各自侧重点不同:
- strict:每个进程都受 SELinux 管控,最为严格。
- targeted:仅保护常见的网络服务,只有有限进程被 SELinux 控制,这是系统默认模式。
- minimum:在 CentOS 7 上出现,属于 targeted 的精简版,只对选定的网络服务生效。
- mls:提供多级安全(MLS)机制,达到国防级别。
SELinux 安全上下文
传统 Linux 信奉“一切皆文件”,访问控制依赖于用户、组和权限,但该模型存在诸多缺陷。在 SELinux 中,“一切皆对象(进程)”,所有访问都由存放在 inode 扩展属性域中的安全元素控制。换句话说,所有文件、端口资源和进程都带有一个安全标签,这就是安全上下文。
安全上下文由五个元素构成,以下是一个典型示例:
system_u:object_r:admin_home_t:s0
对应的格式为:user:role:type:sensitivity:category
- user:指登录系统的用户类型,例如 root、user_u、system_u。大多数本地进程属于自由进程。
- role:定义文件、进程和用户的用途。文件通常为
object_r,进程和用户为system_r。 - type:指定数据类型,规则根据 type 决定何种进程类型可以访问何种文件。targeted 策略基于 type 实现,多个服务可以共用
public_content_t类型。 - sensitivity:限制访问所需的安全级别,由组织定义的分层级别,例如 unclassified、secret、top。一个对象只有一个 sensitivity,分为 0–15 个级别,s0 最低。targeted 策略默认使用 s0。
- category:针对特定组织划分的非分层分类,如 FBI secret、NSA secret。一个对象可以包含多个 category,范围 c0–c1023,共 1024 个分类。targeted 策略不使用 category。
查看安全上下文可使用命令:ls -Z 和 ps -Z。而期望(默认)上下文存储在二进制的 SELinux 策略库中,通过 semanage fcontext -l 可以查看系统中的默认安全上下文。

SELinux 策略
在 SELinux 中,对象(object)指所有可被读取的目标,包括文件、目录、进程、端口等。而进程则被称为主体(subject)。SELinux 对每个文件都赋予一个 type 标签,对每个进程也赋予一个 domain 标签。domain 标签能够执行哪些操作,由安全策略定义。
当一个 subject 试图访问一个 object 时,内核中的策略执行服务器会检查 A VC(访问向量缓存)。在 A VC 中,subject 和 object 的权限被缓存起来,系统会依次查找应用和文件的安全环境,然后根据查询结果决定允许或拒绝访问。安全策略本质上是一个规则数据库,定义了哪种类型的主体可以用哪种方法读取哪个对象是被允许还是拒绝,同时也定义了哪些行为是被允许的。
设置 SELinux
配置 SELinux 主要涉及以下几个方面:是否启用 SELinux、为文件重新打安全标签、为端口设置安全标签、设定某些操作的布尔型开关,以及管理 SELinux 的日志。
SELinux 的状态
- enforcing:强制模式,每个受限进程都必须遵守策略。
- permissive:允许模式,受限进程违规操作不会被阻止,但会被记录到审计日志。
- disabled:禁用模式,允许所有操作。
常用命令:getenforce 获取当前状态,sestatus 查看详细状态,setenforce 0|1 设置模式(0 为 permissive,1 为 enforcing)。
配置文件为 /etc/sysconfig/selinux,它实际上是 /etc/selinux/config 的链接文件。配置文件关键内容示例:
SELINUX=enforcing
SELINUXTYPE=targeted
也可通过内核引导参数设置:在 /boot/grub/grub.conf 内核那一行后追加 selinux=0|1。只要配置文件或内核设定为禁用,最终 SELinux 状态即为禁用。
注意事项:从 disabled 状态切换至 enforcing 或 permissive 状态需要重启系统,此时系统会对每个文件重新打标签,耗时较长。
修改 SELinux 的安全标签
为文件重新打安全标签使用 chcon 命令:
chcon [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE..
chcon [OPTION]... --reference=RFILE FILE..
常用选项:-R 递归打标(针对目录)。例如,若要把自定义的 Web 文档根目录 /htdocs 设置为正确标签:
chcon -R httpd_sys_content_t /htdocs
恢复目录或文件的默认安全上下文使用 restorecon:
restorecon [-R] /path/to/somewhere
例如,若将 Web 文档根目录改回原目录,需还原自定义目录的标签:
restorecon -R /htdocs
恢复操作依据策略库中的策略进行。
默认安全上下文查询与修改
semanage 命令来自 policycoreutils-python 包,部分系统默认未安装,安装后方可使用。查看默认安全上下文:
semanage fcontext -l

添加安全上下文:
semanage fcontext -a -t httpd_sys_content_t '/home/hadoop(/.*)?'
restorecon -Rv /home/hadoop # 此步骤不可省略,从策略库还原才能生效
删除安全上下文:
semanage fcontext -d -t httpd_sys_content_t '/home/hadoop(/.*)?'
SELinux 端口标签
查看端口标签:
semanage port -l

添加端口:
semanage port -a -t port_label -p tcp|udp port
semanage port -a -t http_port_t -p tcp 8080
删除端口:
semanage port -d -t port_label -p tcp|udp port
semanage port -d -t http_port_t -p tcp 8080
修改现有端口为新标签:
semanage port -m -t port_label -p tcp|udp port
semanage port -m -t ssh_port_t -p tcp 8080 # 将 SSH 服务的端口改为 8080
SELinux 布尔值
查看布尔值命令:
getsebool [-a] [boolean]
semanage boolean -l -C # 查看修改过的布尔值
设置布尔值:
setsebool [-P] boolean value (on|off|1|0)
setsebool httpd_enable_homedirs on|1 # 开启 httpd 家目录访问,但不写入策略库
setsebool -P httpd_enable_homedirs on|1 # 永久修改
也可使用 = 写法:setsebool httpd_enable_homedirs=on。
SELinux 的日志管理
需安装 setroubleshoot* 包,安装后需重启系统才能生效。错误日志会记录到 /var/log/message 中:
grep setroubleshoot /var/log/message
sealert -l UUID # 查看安全事件日志说明
sealert -a /var/log/audit/audit.log # 扫描并分析日志

如需查看特定服务的 SELinux 帮助文档,可安装 selinux-policy-devel(CentOS 7)或 selinux-policy-doc(CentOS 6),然后更新 man 数据库:
mandb | makewhatis
man -k _selinux
man httpd_selinux

总结:SELinux 在安全防护方面发挥着实质性作用——它在内核层面工作,能够抵御许多利用漏洞的攻击。但另一方面,其配置繁琐且对稳定性要求较高,导致很多企业不愿在生产环境中启用 SELinux,转而采用硬件安全防护设备。因此,我们通常只需了解它是什么,知道如何开启、关闭以及一些基本操作即可。遇到问题时能快速定位并解决,比死记硬背所有细节更为实用。
