SElinux的简介
我们先来了解什么是SElinux,
SELinux 是 Security-Enhanced Linux 的缩写,即 "安全增强型 Linux",它是一套基于 Linux 内核的强制访问控制(MAC)安全机制,由美国国家安全局(NSA)主导开发,旨在解决传统 Linux 系统中自主访问控制(DAC)的安全缺陷,为系统提供更精细、更严格的安全防护。
主要作用是:弥补传统 Linux 安全模型的不足
传统 Linux 采用自主访问控制(DAC) 模型,权限管理基于 "用户 - 组 - 其他" 的身份划分,资源所有者可自由分配权限。这种模型存在明显缺陷:
- 若普通用户账号被入侵,攻击者可利用该用户的权限操作其能访问的所有资源;
- 若 root 账号泄露,攻击者将获得系统完全控制权。
而 SELinux 基于强制访问控制(MAC) 模型,核心是 "强制"------ 系统通过预设的安全策略,对所有主体(进程)和客体(文件、网络端口等资源)实施强制访问限制,即便用户拥有 DAC 权限,若不符合 SELinux 策略,操作也会被拒绝,从根本上限制攻击面。
SElinux的管理及优化
1.查看当前SElinux状态
bash
[root@test ~]# getenforce
Enforcing #强制模式
# 更详细的状态信息,包括策略类型、安全上下文等
[root@test ~]# sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
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
2.更改SElinux的工作模式
临时更改
bash
#setenforce 0|1
[root@test ~]# setenforce 0
[root@test ~]# getenforce
Permissive
[root@test ~]# setenforce 1
[root@test ~]# getenforce
Enforcing
!NOTE
0 表示宽容模式
1 表示强制模式
注意:setenforce不能禁用SElinux
因为SELinux 的 "禁用模式(Disabled)" 需要彻底关闭内核中的 SELinux 模块,这涉及到内核参数的加载机制。由于内核模块在系统启动时初始化,一旦系统启动完成,无法通过临时命令(如
setenforce)动态卸载 SELinux 模块,因此必须通过修改配置文件并重启系统才能生效。
永久更改
bash
#更改配置文件
[root@test ~]# vim /etc/selinux/config 或者/etc/sysconfig/selinux

这里建议使用sed流编辑器来修改
bash
#-i 表示直接修改文件内容,不输出终端
#/^SELINUX=/ 则表达式,匹配以 SELINUX= 开头的行(^ 表示行首)
#c SELINUX=disabled:c 是 sed 的替换命令,将匹配到的行替换为 SELINUX=disable
[root@test ~]# sed -i '/^SELINUX=/ c SELINUX=disabled' /etc/selinux/config
!NOTE
永久更改需要重启系统即可生效

此外,还可以通过修改内核参数来禁用SElinux
bash
#添加参数
[root@test ~]# grubby --update-kernel ALL -args selinux=0
#selinux=0 是内核级参数,用于禁用 SELinux;对应的启用参数是 selinux=1
#移除参数
[root@test ~]# grubby --update-kernel ALL --remove-args selinux
!NOTE
修改完也需要重启系统
以下是两种修改方式的区别
| 对比维度 | 通过内核参数(grubby 添加 selinux=0) |
编辑配置文件(/etc/selinux/config 设为 SELINUX=disabled) |
|---|---|---|
| 作用层级 | 内核级:直接通过内核启动参数强制关闭 SELinux 机制,优先级最高(忽略 SELinux 子系统的配置)。 | 系统服务级:通过 SELinux 子系统的配置文件控制,依赖内核加载 SELinux 模块后读取配置生效。 |
| 修改对象 | 修改 grub 引导配置中的内核启动参数(如 /boot/grub2/grub.cfg)。 |
修改 SELinux 专用配置文件 /etc/selinux/config。 |
| 生效方式 | 需重启系统使内核参数生效。 | 需重启系统使配置文件生效(重启时 SELinux 模块加载并读取配置)。 |
| 优先级 | 更高:若同时设置 selinux=0 和配置文件 SELINUX=enforcing,内核参数会覆盖配置文件,最终 SELinux 仍为禁用。 |
较低:若内核参数已设置 selinux=0,配置文件的设置会被忽略。 |
| 适用场景 | 1. 配置文件损坏或无效时强制禁用;2. SELinux 策略错误导致系统无法启动(可临时在 grub 界面手动添加参数selinux=0);3. 需要从内核层面彻底关闭。 | 1. 常规场景下永久禁用 SELinux;2. 需通过配置文件统一管理 SELinux 状态(如切换 enforcing/permissive/disabled)。 |
| 恢复方式 | 需通过 grubby --update-kernel ALL --remove-args selinux=0 移除内核参数,再重启。 |
需编辑 /etc/selinux/config,将 SELINUX=disabled 改回 enforcing 或 permissive,再重启。 |
| 对系统的影响 | 完全跳过 SELinux 模块的初始化,内核层面不加载相关机制。 | SELinux 模块仍会加载,但根据配置文件执行 "禁用" 逻辑(不应用任何策略)。 |
| 典型使用命令 | grubby --update-kernel ALL -args selinux=0 |
sed -i '/^SELINUX=/ c SELINUX=disabled' /etc/selinux/config |
/.autorelabel
touch /.autorelabel 的作用:
创建该文件后,系统重启时会触发 SELinux 全系统重新标记。
例如在单用户模式下修改root用户密码时
#在启动界面按e,在linux行最后添加rw rd.break,进入单用户模式
chroot /sysroot/
echo redhat | passwd --stdin root
touch /.autorelabel
exit
eixt
在单用户模式或救援模式下,SELinux 通常处于宽容模式(Permissive) 或未完全加载状态 ,此时修改 /etc/shadow 可能导致:
- 文件的安全上下文被意外篡改(例如从
shadow_t变为其他类型); - 即使上下文未变,SELinux 可能认为 "非授权进程修改了文件"(因为破解操作绕过了正常的权限校验流程)。
- 而当开启SElinux时识别到修改root密码操作,就会使其不生效
此时创建/.autorelabel,其中会自动将 /etc/shadow 恢复为预设的安全上下文(shadow_t),确保其符合 SELinux 策略,从而避免因上下文异常导致的登录或权限问题。
3.管理文件的安全上下文
1.临时更改文件的安全上下文
chcon [-R] [-t type] [-u user] [-r role] 文件
-R:连同该目录下的子目录也同时修改
-t:后面接安全上下文的类型字段
-u:后面接身份识别
-r:后面接角色
chcon -R --reference=模板 目标文件 #将文件的安全上下文按照范例文件修改
2.永久修改安全上下文
semanage fcontext [-a|-d] [-t type] [-s user] [-r range] 文件、
-l:列出所有记录
-a:添加记录
-m:修改记录
-d:删除记录
-t:添加的类型
-p:指定添加的端口是tcp或udp协议的,port子命令下使用
-e:目标路径参考原路径的上下文类型,fcontext子命令下使用
-s:后面接身份识别
-r:后面接角色
!CAUTION
系统将每个目录的默认selinux type类型记录再/etc/selinux/targeted/contexts/目录内
用semanage这个命令的功能来查询:semanage
{login|user|port|interface|fcontext|translation} -l
在使用semanage更改完毕后必须要刷新否则不生效
3.刷新安全上下文
restorecon [-Rv] 文件或者目录
-R:连同子目录一起修改
-v:将过程显示到屏幕上
4.selinux对linux服务的影响
1.服务的功能影响
在系统SElinux开启后会为服务添加新的开关,我们把这个开关叫做sebool
a)查看sebool值
getsebool -a | grep 服务名称
b)修改sebool值
setsebool -P <bool类型> <0|1>
-P:表示永久生效
0:表示功能关闭
1:表示功能开启
2.服务的端口影响
在系统SElinux开启后会规定服务使用端口
a)查看服务被允许使用的端口
semanage port -l | grep ssh
ssh_port_t tcp 22
b)根据需求更改被允许使用的端口
semanage port -a -t ssh_port_t -p tcp 6666
semanage port -l | grep ssh
ssh_port_t tcp 6666,22
!WARNING
当更改端口之前一定要确认此端口没有被其他服务使用
例题
非标准端口 82 上运行的 WEB 服务器在提供内容时遇到问题。根据需要调试
并解决问题, 并使其满足以下条件:
web 服务器能够提供 /var/www/html 中所有现有的 html 文件(注意:不要删除或改动现有的文件内容)
Web 服务器通过 82 端口访问
bash
[root@servera ~]# dnf install httpd -y
[root@servera ~]# systemctl enable --now httpd
[root@servera ~]# firewall-cmd --permanent --add-service=http
[root@servera ~]# firewall-cmd --permanent --add-port=82/tcp
[root@servera ~]# firewall-cmd --reload
[root@servera ~]# semanage port -l | grep 80 #查询要添加端口的安全上下文
[root@servera ~]# semanage port -a -t http_port_t -p tcp 82
[root@servera ~]# ls -ldZ /var/www/ #查询要更改的目录的安全上下文
[root@servera ~]# semanage fcontext -m -t httpd_sys_content_t "/var/www/html/"
[root@servera ~]# restorecon -Rv /var/www/html #由于semanage是永久修改,所以要刷新安全上下文
#最后重启httpd服务即可
[root@servera ~]# systemctl restart httpd
