SELinux-介绍和使用

简介

SELinux, Security Enhanced Linux.

SELinux 是 Linux 内核的一个模块, 也是 Linux 的一个安全子系统.

SELinux 基于 MAC (Mandatory Access Control, 强制访问控制) 来实现安全增强. 区别与传统的 DAC (Discretionary Access Control), 其基于用户, 组和其他权限.

MAC (Mandatory Access Control)

基于标签或标记的概念来实现访问控制.

每个进程和系统资源都被赋予特定的安全标签, 这些标签包含了关于主体和资源的安全属性和规则. 然后, 访问控制决策是基于标签之间的比较和安全策略规则来进行的.
(重点是安全上下文和安全策略)


查看当前 SELinux 状态

1
sestatus

安装 SELinux 策略

在 Fedora 上为:

1
dnf install -y selinux-policy-targeted, policycoreutils-python-utils

Policy

SELinux policy 是一组规则的集合, 定义了系统资源的访问权限. 描述了主体对客体有哪些允许操作.

主要有三种:

  • targeted, 默认
  • minimum, 最小化策略 (比较严格)
  • mls (multi-level-security), 最完整 (非常严格)

可以通过修改 /etc/selinux/config 中的:

1
SELINUXTYPE=

来切换.

三种模式

SELinux 分三种模式, 对应三种安全等级:

  • Permissive: SELinux 仅打印告警而不强制执行
  • Enforcing: SELinux 安全策略被强制执行
  • Disabled: 不加载 SELinux 安全策略

修改 /etc/selinux/config 文件中的模式后, 需要重新开机才会启用. (因为 SELinux 是整合到内核中的, 也就是说, 开机模式下, 不能在 enforcingdisabled 之间转换)

在从 Disabled 切换成 Enforcing 之后, 若出现很多错误, 可以运行:

1
restorecon -Rv /

重新还原所有 SELinux 的类型.

模式的查看与转换

查看当前的 SELinux 模式

1
getenforce

临时修改 SELinux 模式

切换为 permissive:

1
setenforce 0

切换为 enforcing:

1
setenforce 1

切换为 permissive:

1
setenforce 0

永久修改

修改 /etc/selinux/config 配置文件:

1
SELINUX=enforcing

安全上下文

“安全上下文” 也就是, 文件, 进程, 端口等的 “安全标签”.

其分为四个部分, 结构为:

1
user:role:type:sensitivity

当一个进程试图访问某个文件时, SELinux 内核会检查两者的安全上下文, 并根据预定义的策略来决定是否允许访问.

如果两者的安全上下文允许访问, 则操作成功; 否则, SELinux 会阻止该操作并记录日志.

User

User 表明是 SELinux 用户, 而非传统的 Linux 用户. SELinux 用户可以指代多个系统用户, 常见的有:

  • system_u: 用于系统进程和守护进程
  • unconfined_u: 用于没有严格限制的用户
  • staff_u: 用于具有管理员权限的用户

(可能是控制默认分配的 Role)

Role

Role 定义主体可以执行的操作范围, 用于限制主体的行为, 常见的有:

  • system_r: 用于系统进程
  • unconfined_r: 用于没有严格限制的用户
  • staff_r: 用于具有管理员权限的用户

Role 决定能访问的 Type 有哪些.

Role 确定具体的权限有哪些, User 和 Role 之间相互关联, 每个 User 都必须被分配至少一个角色.

一个 User 可以被分配多个角色, 但同一时间只能激活一个角色.

Type

Type 控制主体对对象的访问, 每个对象和主体都有一个类型, 策略通过类型来定义哪些主体可以访问哪些对象, 常见的 type 有:

  • httpd_t: 用于 Apache HTTP 服务器进程
  • sshd_t: 用于 SSH 服务器进程
  • user_home_t: 用于普通用户的家目录

Sensitivity 和 Category

Sensitivity 表示数据的保密级别 (例如, s0 表示最低级别), Category 通常表示数据的分类 (例如, c0 表示某个特定类别)

确定安全级别, 级别高则控制策略更多.

查看安全上下文

默认上下文

1
semanage fcontext -l

输出如:

1
2
3
4
5
6
7
SELinux fcontext      type               Context

/ directory system_u:object_r:root_t:s0
/.* all files system_u:object_r:default_t:s0
/[^/]+ regular file system_u:object_r:etc_runtime_t:s0
/\.autofsck regular file system_u:object_r:etc_runtime_t:s0
/\.autorelabel regular file system_u:object_r:etc_runtime_t:s0

进程

1
ps axZ

文件

1
ls -Z

端口

1
ss -lnpZ

修改安全上下文

注意使用 chconsemanage fcontext 的区别:

  • 使用 chcon 修改的 SELinux 上下文不会记录到文件系统, 可用 restorecon 恢复为默认的上
    下文; 使用 semanage fcontext 修改的 SELinux 上下文会被记录到文件系统, 修改的是默认
    上下文

chcon

1
chcon -t TYPE file/directory

如:

1
chcon unconfined_u:object_r:httpd_sys_content_t:s0 filename

semanage fcontext

1
semanage fcontext -[option] file/directory

给目录设置 httpd_sys_content_t 类型安全上下文

1
2
3
semanage -a -t httpd_sys_content_t "/home/myweb(/.*)?"
restorecon -R -v /home/myweb
setsebool -P httpd_enable_homedirs=on

允许第二条命令的原因如下:

  • 使用 semanage fcontext 命令只是设置了一个规则, 定义了某个目录或文件匹配的安全上下文类型. 但这个规则只存在于 SELinux 的数据库中, 并没有应用到实际的文件或目录上
  • restorecon 命令会将文件或目录的实际安全上下文设置为之前使用 semanage 命令定义的类型

若是直接重启电脑实际上也能实施新规则

semanage port

1
semanage port -[option] port

查看 SELinux 允许 httpd 监听的端口

1
semanage port -l | grep -w http_port_t
  • -l, --list

添加允许 httpd 监听的端口

1
semanage port -a -t http_port_t -p tcp 1982
  • -a, --add, 添加一个指定 object type 的记录
  • -t, --type, 指定 object 的 SELinux type
  • -p, --proto, 指定端口的协议

restorecon

1
restorecon -[option] file/directory

修复安全上下文

修复安全上下文检查文件的安全上下文以确保系统中所有文件的安全上下文都与 SELinux 策略保持一致.

fixfiles 命令, 如:

1
fixfiles -F onboot
  • -F, force reset, onboot 指在系统启动时实施

SELinux 的布尔值

SELinux 布尔值直接影响某个安全策略的开启或关闭, 如:

  • httpd_can_network_connect: 允许 HTTP 服务器 (如 Apache) 发起网络连接
  • httpd_can_network_connect_db: 允许 HTTP 服务器连接到数据库
  • samba_enable_home_dirs: 允许 Samba 共享访问用户的个人主目录
  • ftpd_anon_write: 允许 FTP 服务器接受匿名用户上传文件
  • allow_mount_anyfile: 允许任意文件系统类型的挂载

设置 SELinux 的布尔值为 on, 则开启对应 SELinux 的规则.

设置为 off 则表示禁用对应规则.

查看所有 SELinux 的布尔值

1
semanage boolean -l

查看当前生效的所有布尔值

1
getsebool -a

设置布尔值

1
setsebool -P rule on/off

加了 -P 选项才会将配置写入配置文件.

查询 SELinux type

使用 seinfo, sesearch 等工具.

seinfo

用于查看 SELinux 的类型, 角色, 用户, 扩展属性, 类别, 模块等信息.

1
seinfo [-option]

列出所有的 SELinux type attributes

1
seinfo -a

列出所有 SELinux types

1
seinfo -t

列出所有 SELinux roles

1
seinfo -r

列出所有 SELinux users

1
seinfo -u

sesearch

限制查询 rule 为 allow 和 allowxperm

1
sesearch -A [otheroptions]

查询一个 type/role 所放行的 rules

如:

1
sesearch -A -s cron_t

-s 指 “Source” type or role.

查询一个 type/role 对目标 type/role 放行的 rules

1
sesearch -A -s cron_t -t xxxx

-t 指 “Target” type or role.

日志

默认使用 auditd 服务. 位于 /var/log/audidt/audit.log

setroubleshoot 服务会将错误写入 /ver/log/messages/ver/log/setroubleshoot/* 文件中. 需安装 setroubleshoot 和 setroubleshoot-server 包. (但其现在被整合到了 auditd 服务中)

启用和查看

1
2
systemctl enable --now auditd.service
systemctl status auditd.service

搜索日志

ausearch 命令.

查看与 httpd 进程相关的 avc 事件

AVC, Access Vector Cache, 访问向量缓存.

在 SELinux 中, 当一个进程尝试访问某个资源时, SELinux 会根据预定义的安全策略来判断是否允许该访问. 这个判断过程会产生一个 “Access Vector” 对象, 记录了该次访问请求的详细信息.

而 AVC 事件指:

  • 当进程第一次尝试访问某个资源时, SELinux 会评估访问策略, 生成一个访问向量对象
  • 如果 SELinux 策略允许该访问, 则不会产生任何 AVC 事件
  • 但如果 SELinux 策略拒绝了该访问请求, 则会记录一个 AVC 事件, 记录该次被拒绝的访问行为

其会记录:

  • 哪个进程尝试访问了什么资源
  • 访问被拒绝的原因
  • SELinux 策略中相关的规则信息

示例:

1
ausearch -m avc -c httpd
  • -m, --message message-type
  • -c, --comm comm-name, 即 command name, 对于这里来说是 httpd

基本使用

相关命令集合

  • getenforce
  • setenforce
  • semanage
  • chcon
  • getsebool
  • setsebool
  • seinfo
  • sesearch

还原所有的 SELinux 类型

restorecon 用于将文件和目录的安全上下文恢复为默认值:

1
restorecon -Rv /
  • -R 表示递归恢复
  • -v 显示详细信息
  • / 指定从根目录

例如, 一个 /root 目录下的脚本 hello.sh, 原本的安全上下文为:

1
unconfined_u:object_r:admin_home_t:s0

利用 chcon 修改为;

1
unconfined_u:object_r:user_home_t:s0

运行:

1
restorecon -v hello.sh

则安全上下文恢复为:

1
unconfined_u:object_r:admin_home_t:s0

查看 SELinux 的统计状态

1
seinfo

与 Apache (httpd) 相关的 Boolean 设置

  • httpd_can_network_connect: 允许 httpd 进程建立网络连接
  • httpd_can_network_connect_db: 允许 httpd 进程与数据库进行网络连接
  • httpd_can_sendmail: 允许 httpd 进程发送邮件
  • httpd_use_nfs: 允许 httpd 进程使用 NFS (Network File System) 共享
  • httpd_enable_homedirs: 允许 httpd 进程访问用户的主目录
  • httpd_use_cifs: 允许 httpd 进程使用 CIFS (Common Internet File System) 共享

如开启了 proxy_mod, 并使用 ProxyPass 进行代理, 此时需要:

1
setsebool -P httpd_can_network_connect

常见的由于触发 SELinux 而导致的服务启动失败

修改服务的默认端口

如将 httpd 的监听端口从 80 改为 90 端口, 此时 SELinux 就会阻止服务启动, 并记录日志.

练习


SELinux-介绍和使用
http://example.com/2023/11/22/SELinux-介绍和使用/
作者
Jie
发布于
2023年11月22日
许可协议