1. 核心概念与原理
-
定义:SELinux (Security-Enhanced Linux)是美国国家安全局在 Linux 开源社区的帮助下开发的一个强制访问控制(MAC,Mandatory Access Control)的安全子系统,用于各个服务进程都受到约束,使其仅获取到本应获取的资源。
-
作用:
-
SELinux 域限制:对服务程序的功能进行限制,以确保服务程序做不了出格的事情。
-
SELinux 安全上下文:对文件资源的访问限制,确保文件资源只能被其所属的服务程序访问。
-
-
与传统权限的区别:
-
传统 DAC (自主访问控制):靠权限控制的主体是用户。当某个进程想要对文件进行访问时,系统就会根据该进程的所有者/用户组,并比较文件的权限,若通过权限检查,就可以访问该文件。注意:各种权限设置对 root 用户是无效的。
-
SELinux MAC (强制访问控制):靠策略规则控制的主体则是进程。可以针对特定的进程与特定的文件资源来进行权限的控制,即使你是 root 在使用不同的进程时,你所能取得的权限并不一定是 root。
-
| 对比项 | 传统权限(DAC) | SELinux(MAC) |
|---|---|---|
| 控制主体 | 用户 | 进程 |
| 控制依据 | 所有者 / 用户组 + 文件 rwx 权限 | 策略规则 + 安全上下文匹配 |
| root 权限 | 不受任何权限约束 | 受进程策略限制,不一定是完全 root 权限 |
| 控制粒度 | 粗粒度,用户对文件 | 细粒度,进程对文件 |
| 风险 | 程序越权、提权风险高 | 大幅降低越权风险 |
2. SELinux 的启动、关闭与查看
-
三种配置模式:
-
enforcing:强制模式,启用 SELinux,将拦截服务的不合法请求。
-
permissive:宽容模式,启用 SELinux,遇到服务越权访问时,只发出警告而不强制拦截。
-
disabled:关闭模式,SELinux 没有运行。
-
| 模式 | 说明 |
|---|---|
| enforcing | 强制模式,启用 SELinux,拦截非法请求 |
| permissive | 宽容模式,仅警告不拦截,用于排错 |
| disabled | 关闭模式,SELinux 不运行 |
- 原理图

- 模式管理命令:
| 命令 | 作用 | 备注 |
|---|---|---|
getenforce |
查看当前模式 | - |
setenforce 0 |
临时关闭 selinux | 转为宽容模式,重启系统失效 |
setenforce 1 |
临时开启 selinux | 转为强制模式,重启失效 |
sestatus |
查看 selinux 的详细状态 | - |
-
永久配置:
-
编辑 /etc/selinux/config 文件,修改 SELINUX=enforcing (或 disabled/permissive)。
-
修改后需重启系统生效。
-
# 安装所需软件
[root@server ~]# yum install selinux-policy selinux-policy-targeted -y
# 编辑selinux配置文件
[root@server ~]# vim /etc/selinux/config # 先转为临时模式
SELINUX=permissive
[root@server ~]# touch /.autorelabel # 重建文件
[root@server ~]# reboot
[root@server ~]# vim /etc/selinux/config # 改为强制模式
SELINUX=enforcing
[root@server ~]# reboot
3. SELinux的状态及其配置文件
3.1 状态
[root@server ~]# sestatus
SELinux status: enabled # 是否启用
SELinuxfs mount: /sys/fs/selinux # selinux临时文件系统的挂载点
SELinux root directory: /etc/selinux # 启动目录,配置文件位置
Loaded policy name: targeted # 当前加载的策略类型
# 策略类型
# targeted:只保护目标运行,默认
# minimum:少数选定进程进行保护
# mls:多级安全保护,最高级
Current mode: enforcing # 执行的模式,重要
Mode from config file: enforcing # 配置文件的模式
Policy MLS status: enabled
Policy deny_unknown status: allowed
Memory protection checking: actual (secure)
Max kernel policy version: 33
3.2 配置文件
[root@server ~]# vim /etc/selinux/config
SELINUX=enforcing # 设置模式
SELINUXTYPE=targeted # 设置策略类型
# 注意:/etc/sysconfig/selinux文件与上述配置问价内容相同,选择一个配置即可
4. 实验
实验一
-
使用nginx服务演示安全上下文值的设定
-
服务端操作
# 开启selinux
[root@node1 ~]# vim /etc/selinux/config
[root@node1 ~]# touch /.autorelabel
[root@node1 ~]# reboot
[root@node1 ~]# getenforce
Permissive
[root@node1 ~]# vim /etc/selinux/config
[root@node1 ~]# reboot
[root@node1 ~]# getenforce
Enforcing
# nginx软件安装
[root@node1 ~]# yum install nginx -y
[root@node1 ~]# systemctl enable --now nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
# 新建存储网页的目录
[root@node1 ~]# mkdir /www
[root@node1 ~]# ls /www
zy
# 编辑nginx主配置文件
[root@node1 ~]# vim /etc/nginx/nginx.conf
root /www/zy/zy;
[root@node1 ~]# systemctl restart nginx
# 测试,返回403,说明selinux对/www/zy/zy的安全上下文件检测未通过
# 将/www/zy的策略类型改为已知可以访问的策略
[root@node1 ~]# ls -Zd /usr/share/nginx/html/
system_u:object_r:httpd_sys_content_t:s0 /usr/share/nginx/html/
[root@node1 ~]# ls -Zd /www/zy
unconfined_u:object_r:default_t:s0 /www/zy
[root@node1 ~]# chcon -Rv -t httpd_sys_content_t /www/zy
# 注意:chcon命令也可以使用参照范例文件修改来实现访问
[root@node1 ~]# chcon -R --reference=/usr/share/nginx/html/ /www/zy/zy
[root@node1 ~]# ls -Zd /www/zy/zy
system_u:object_r:httpd_sys_content_t:s0 /www/zy
[root@node1 ~]# systemctl restart nginx
实验二
- 使用nginx服务的端口号修改演示selinux的设定
# 基于上例
# 检查selinux的状态
[root@server ~]# getenforce
Enforcing
# 编辑httpd的主配置文件修改监听端口号
[root@server ~]# vim /etc/nginx/nginx.conf
server {
listen 7777;
# 重启服务失败,selinux拦截端口的修改
[root@server ~]# systemctl restart nginx
Job for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xeu nginx.service" for details.
# 查看selinux允许的端口号
[root@server ~]# semanage port -l | grep http_port_t
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
# 使用semanage命令将7777端口号添加到http_port_t类型列表中
[root@server ~]# semanage port -a -t http_port_t -p tcp 7777
[root@server ~]# semanage port -l | grep http_port_t
# 重启服务
[root@server ~]# systemctl restart nginx
# 测试,浏览器输入:192.168.48.130:7777
实验三
- 演示ssh端口号修改的selinux设定
[root@server ~]# vim /etc/ssh/sshd_config # 修改ssh的端口号为2222
Port 2222
[root@server ~]# systemctl restart sshd # 重启服务失败
Job for sshd.service failed because the control process exited with error code.
See "systemctl status sshd.service" and "journalctl -xeu sshd.service" for details.
[root@server ~]# semanage port -l | grep ssh_port_t # 查看ssh的的端口号策略
ssh_port_t tcp 22
[root@server ~]# semanage port -a -t ssh_port_t -p tcp 2222 # 策略中添加新端口
[root@server ~]# semanage port -l | grep ssh_port_t
ssh_port_t tcp 2222, 22
[root@server ~]# systemctl restart sshd