云计算一阶段Ⅱ——12. SELinux 加固 Linux 安全

12. SELinux 加固 Linux 安全

SELinux 介绍

SELinux 概述

文件权限控制了哪些用户或用户组可以访问哪些特定文件,但未限定用户访问文件的方式。

例如:对于文件的写入权限而言, 结构化数据文件是否应当设计为只能使用特定的程序写入,但其他编辑器仍可以打开和修改此文件,而这可能会导致损坏。文件权限仅仅是控制谁可以读取、写入或运行文件,无法控制如何使用文件。

Security Enhanced Linux (SELinux)是一个额外的系统安全层,主要目标是防止已遭泄露的系统服务访问用户数据。

例如:恶意人员成功入侵了 Web服务器进程,获得进程的权限,也就是apache用户和apache组的权限。该用户和组对文档根目录/var/www/html具有读取权限,还可以访问/tmp和/var/tmp,以及全局可写的其他任何文件和目录。

SELinux 强制执行一组访问规则,明确定义进程和资源之间允许的操作。每个进程、文件、目录和端口都具有专门的安全标签, 称为SELinux上下文。上下文是一个名称, SELinux策略使用它来确定某个进程能否访问文件、目录或端口。除非显式规则授予访问权限,否则,在默认情况下,策略不允许任何交互。

SELinux 标签有多个内容:用户,角色,类型和敏感度。rhel中默认策略targeted,基于类型部分。类型部分通常以_t结尾。

示例:

示例:

  • web 服务器守护进程类型是 httpd_exec_t
  • web 服务器的网页类型是 httpd_sys_content_t
  • web 服务器的端口类型是 http_port_t
  • /tmp 标签 tmp_t
基本原理
  • SELinux默认策略允许apache进程访问在/var/www/html文件夹下的文件和文件夹,以及其他一些具有httpd_sys_content_t上下文的文件夹,禁止访问具有其他不匹配标签的目录。
  • 在 SELinux 的保护下,apache进程不允许访问/tmp和/var/tmp目录。因为/tmp、/var/tmp目录的标签是tmp_t,与默认策略不匹配。
命令选项 -Z

许多处理文件的命令都一个-Z 选项,用于显示和设置SELinux上下文。

bash 复制代码
[root@centos7 ~]# ps -C sshd -Z
LABEL                               PID TTY          TIME CMD
system_u:system_r:sshd_t:s0-s0:c0.c1023 951 ?    00:00:00 sshd
system_u:system_r:sshd_t:s0-s0:c0.c1023 1261 ?   00:00:00 sshd
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 1276 ? 00:00:00 sshd
system_u:system_r:sshd_t:s0-s0:c0.c1023 2455 ?   00:00:00 sshd
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2459 ? 00:00:00 sshd

[root@centos7 ~]# ls -Z /home
unconfined_u:object_r:user_home_dir_t:s0 laoma

# 其他命令中 -Z 选项
# cp -Z     set SELinux security context of destination file to default type
# mkdir -Z     set SELinux security context of each created directory to the default type
SELinux 模式
  • enforcing 模式 : SELinux强制执行访问控制规则。 在强制模式下,如果规则没有明确允许访问,则拒绝访问,并写入日志。此模式是默认模式。
  • Permissive 模式 :SELinux 加载策略并处于活动状态,但不强制执行 访问控制规则,⽽是记录访问违规。此模式有助于对应用和规则进行测试和故障排除。
  • disable 模式 :完全关闭 SELinux。不拒绝任何SELinux违规,不予记录。

查看当前模式

bash 复制代码
[root@centos7 ~]# getenforce 

更改当前模式

bash 复制代码
[root@centos7 ~]# setenforce 
usage:  setenforce [ Enforcing | Permissive | 1 | 0 ]

# 强制模式临时切换为允许模式
[root@centos7 ~]# setenforce 0
# 或者
[root@centos7 ~]# setenforce Permissive

# 允许模式临时切换为强制模式
[root@centos7 ~]# setenforce 1
# 或者
[root@centos7 ~]# setenforce Enforcing

模式切换注意事项:

  • 强制模式和允许模式之间变更,不需要重启系统。
  • 从强制模式或者允许模式变更到禁用模式,或者从禁用模式变更到强制模式或者允许模式都需要重启系统。

更改 SELinux 默认模式

bash 复制代码
[root@centos7 ~]# vim /etc/selinux/config
SELINUX=enforcing
SELINUXTYPE=targeted

在启动时通过将向内核传递参数来设置SELinux 模式

  • enforcing=1,设置强制模式。
  • enforcing=0,设置许可模式。
  • selinux=0,来彻底禁用 SELinux。
  • selinux=1,启用 SELinux(当设置enforcing参数是,该参数可以省略)。

实验: selinux模式为enforcing情况下,破解root密码。破解完成后不执行 touch /.autorelabel命令。

重启测试:使用正确的密码登录。结果:登录失败。原因:用户验证程序无法访问/etc/shadow,因为破解密码过程中/etc/shadow文件标签被破坏了。

处理方法:系统启动时,内核添加参数 selinux=1 enforcing=0

控制文件 SELinux 上下文

新文件默认 SELinux 上下文

新文件通常从父目录继承其SELinux上下文,从而确保它们具有适当的上下文。

bash 复制代码
[root@server-gx ~ 18:38:11]# touch /tmp/whisky
[root@server-gx ~ 18:38:20]# ls -1dZ /tmp /tmp/whisky
drwxrwxrwt. root root system_u:object_r:tmp_t:s0       /tmp
-rw-r--r--  root root ?                                /tmp/whisky

[root@server-gx ~ 18:39:17]# cp /tmp/whisky /root/whisky
[root@server-gx ~ 18:39:48]# ls -1dZ /tmp /tmp/whisky /root /root/whisky
dr-xr-x---. root root system_u:object_r:admin_home_t:s0 /root
-rw-r--r--  root root ?                                /root/whisky
drwxrwxrwt. root root system_u:object_r:tmp_t:s0       /tmp
-rw-r--r--  root root ?                                /tmp/whisky

以下两种情况,文件的 SELinux 上下文保持不变:

  • cp -a 命令复制
  • 移动文件
bash 复制代码
[root@server-gx ~ 18:39:17]# cp /tmp/whisky /root/whisky
[root@server-gx ~ 18:39:48]# ls -1dZ /tmp /tmp/whisky /root /root/whisky
dr-xr-x---. root root system_u:object_r:admin_home_t:s0 /root
-rw-r--r--  root root ?                                /root/whisky
drwxrwxrwt. root root system_u:object_r:tmp_t:s0       /tmp
-rw-r--r--  root root ?                                /tmp/whisky
[root@server-gx ~ 18:41:17]# cp -a /tmp/whisky /root/whisky-a
[root@server-gx ~ 18:44:20]# ls -1dZ /tmp /tmp/whisky /root /root/whisky*
dr-xr-x---. root root system_u:object_r:admin_home_t:s0 /root
-rw-r--r--  root root ?                                /root/whisky
-rw-r--r--  root root ?                                /root/whisky-a
drwxrwxrwt. root root system_u:object_r:tmp_t:s0       /tmp
-rw-r--r--  root root ?                                /tmp/whisky

[root@server-gx ~ 18:46:04]# mv /tmp/whisky /root/whisky-mv
[root@server-gx ~ 18:46:58]# ls -1dZ /tmp /root /root/whisky*
dr-xr-x---. root root system_u:object_r:admin_home_t:s0 /root
-rw-r--r--  root root ?                                /root/whisky
-rw-r--r--  root root ?                                /root/whisky-a
-rw-r--r--  root root ?                                /root/whisky-mv
drwxrwxrwt. root root system_u:object_r:tmp_t:s0       /tmp
设置文件 SELinux 上下文

设置文件上下文命令

  • chcon 命令,直接更改文件SELinux上下文。但是,它不会将上下文更改保存到 SELinux 上下文数据库中。系统下一次对所有文件进行 relabel 操作时,将导致该上下文恢复。它对于测试和实验很有用。

  • restorecon 命令,根据 SELinux上下文数据库中规则,恢复文件SELinux上下文。原先通过 chcon命令所做的更改,将失效。

示例:

bash 复制代码
[root@centos7 ~]# mkdir /www
[root@centos7 ~]# ls -Zd /www
unconfined_u:object_r:default_t:s0 /www

[root@centos7 ~]# chcon -t httpd_sys_content_t /www
[root@centos7 ~]# ls -Zd /www
unconfined_u:object_r:httpd_sys_content_t:s0 /www

[root@centos7 ~]# restorecon -v /www
Relabeled /www from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:default_t:s0
[root@centos7 ~]# ls -Zd /www
unconfined_u:object_r:default_t:s0 /www

semanage fcontext 命令用于管理SELinux上下文数据库中规则,restorecon 命令根据这些规则恢复文件上下文。semanage fcontext命令使用扩展的正则表达式指定路径和文件名。比较常见的扩展正则表达式(/.*)?,表示随意匹配/后面接任意数量字符,递归匹配文件夹下的子文件和子文件夹。

示例:

bash 复制代码
[root@centos7 ~]# echo Hello World > /www/index.html
[root@centos7 ~]# ls -Zd /www/index.html
unconfined_u:object_r:default_t:s0 /www/index.html

# 安装 semanage 工具
[root@centos7 ~]# yum install -y policycoreutils-python-utils

# 添加默认规则
[root@centos7 ~]# semanage fcontext -a -t httpd_sys_content_t '/www(/.*)?'
[root@centos7 ~]# semanage fcontext -l |grep '^/www(/.*)?'
/www(/.*)?    all files   system_u:object_r:httpd_sys_content_t:s0 

# 只查看非默认策略
[root@centos7 ~]# semanage fcontext -lC
SELinux fcontext  type      Context
/www(/.*)?     all files    system_u:object_r:httpd_sys_content_t:s0

# 恢复文件上下文
[root@centos7 ~]# restorecon -Rv /www/
Relabeled /www from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
Relabeled /www/index.html from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
[root@centos7 ~]# ls -1Zd /www/ /www/index.html
unconfined_u:object_r:httpd_sys_content_t:s0 /www/
unconfined_u:object_r:httpd_sys_content_t:s0 /www/index.html

# 删除默认规则
[root@centos7 ~]# semanage fcontext -d -t httpd_sys_content_t '/www(/.*)?'

# 删除目录
[root@centos7 ~]# rm -fr /www
示例:配置 web 站点主目录
bash 复制代码
# 准备目录
[root@centos7 ~]# mkdir /www
[root@centos7 ~]# echo Hello World > /www/index.html
[root@centos7 ~]# semanage fcontext -a -t httpd_sys_content_t '/www(/.*)?'
[root@centos7 ~]# restorecon -Rv /www/

# 安装 httpd
[root@centos7 ~]# yum install -y httpd
[root@centos7 ~]# systemctl enable httpd --now
[root@centos7 ~]# vim /etc/httpd/conf/httpd.conf 
# 注释122 行DocumentRoot,在122行后,添加如下内容:
# DocumentRoot "/var/www/html"
DocumentRoot "/www"
<Directory "/www">
    AllowOverride None
    # Allow open access:
    Require all granted
</Directory>
# 重启服务
[root@centos7 ~]# systemctl restart httpd

# 访问验证
[root@centos7 ~]# curl http://server.laoma.cloud/
Hello World

控制端口 SELinux 上下文

端口 SELinux 上下文

**SELinux还可以对端口标记。**当某个进程希望侦听端口时, SELinux将检查是否允许与该进程相关联的标签绑定该端口标签。 这可以阻止恶意服务控制本应由其他网络服务使用的端口。

在 targeted 策略中:

  • 端口 22/TCP ,具有标签 ssh_port_t
  • 端口 80/TCP 和 443/TCP ,具有标签 http_port_t
bash 复制代码
# 查看端口标记
[root@centos7 ~]# 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

# 添加端口标记
[root@centos7 ~]# semanage port -a -t http_port_t -p tcp 18020
[root@centos7 ~]# semanage port -l|grep 18020
http_port_t                    tcp      18020, 80, 81, 443, 488, 8008, 8009, 8443, 9000

# 修改网络端口标记
[root@centos7 ~]# semanage port -m -t ssh_port_t -p tcp 18020
[root@centos7 ~]# semanage port -l | grep 18020
ssh_port_t                     tcp      18020, 22

# 删除端口标记
[root@centos7 ~]# semanage port -d -t ssh_port_t -p tcp 18020
[root@centos7 ~]# semanage port -l | grep 108020
示例:配置 web 站点监听端口
bash 复制代码
[root@centos7 ~]# vim /etc/httpd/conf/httpd.conf
# 修改原先的 Listen 80 为 Listen 18020
Listen 18020

# 重启服务vim 
[root@centos7 ~]# systemctl restart httpd
Job for httpd.service failed because the control process exited with error code.
See "systemctl status httpd.service" and "journalctl -xe" for details

[root@centos7 ~]# systemctl status httpd.service |cat |grep Per
......
Nov 29 11:55:26 rocky.laoma.cloud httpd[3939]: (13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:18020
......

# 配置端口
[root@centos7 ~]# semanage port -a -t http_port_t -p tcp 18020
[root@centos7 ~]# semanage port -l | grep 18020
http_port_t                    tcp      18020, 80, 81, 443, 488, 8008, 8009, 8443, 9000

# 只查看改动标签
[root@centos7 ~]# semanage port -lC
SELinux Port Type              Proto    Port Number
http_port_t                    tcp      18020

# 重启服务并访问
[root@centos7 ~]# systemctl restart httpd

# 访问验证
[root@centos7 ~]# curl http://server.laoma.cloud:18020/
Hello World

控制 SELinux 布尔值

SELinux 布尔值

SELinux 布尔值是可更改SELinux策略行为的开关,可以启用和禁用。

bash 复制代码
# 查看SELinux布尔值
[root@centos7 ~]# getsebool -a |grep httpd_enable_homedirs
httpd_enable_homedirs --> off
[root@centos7 ~]# getsebool httpd_enable_homedirs
sethttpd_enable_homedirs --> off

# 设置SELinux布尔值
[root@centos7 ~]# setsebool 
Usage:  setsebool [ -NPV ] boolean value | bool1=val1 bool2=val2...
# 启用value为1或者on或者true
# 禁用value为0或者off或者false

[root@centos7 ~]# setsebool httpd_enable_homedirs=1或者on或者true
[root@centos7 ~]# setsebool httpd_enable_homedirs=0或者off或者false

# 持久化设置布尔值,使用-P选项修改将写入SELinux数据库。
[root@centos7 ~]# setsebool httpd_enable_homedirs=1
[root@centos7 ~]# setsebool -P httpd_enable_homedirs=1

还可以semanage boolean 命令管理 SELinux 布尔值。

bash 复制代码
[root@centos7 ~]# semanage boolean 
usage: semanage boolean [-h] [-n] [-N] [-S STORE] [  --extract  | --deleteall  | --list -C | --modify ( --on | --off ) boolean ]

# 查看 SELinux 布尔值
[root@centos7 ~]# semanage boolean -l
# 只查看非默认的 SELinux 布尔值
[root@centos7 ~]# semanage boolean -l -C

# 设置 SELinux 布尔值
[root@centos7 ~]# semanage boolean -m -1|--on use_nfs_home_dirs
[root@centos7 ~]# semanage boolean -m -0|--off use_nfs_home_dirs
# 相当于setsebool -P

# 删除原先自定义的 SELinux 布尔值
[root@centos7 ~]# semanage boolean -D
示例:允许 httpd 访问用户家目录
bash 复制代码
[root@server ~ 10:24:31]# vim /etc/httpd/conf.d/userdir.conf
# 修改以下两个参数
    UserDir enabled
	UserDir public_html
# 重启服务
[root@server ~ 10:27:33]# systemctl restart httpd.service

# 设置权限
[root@server ~ 10:27:48]# mkdir public_html
[root@server ~ 10:28:01]# echo "Welcome to whisky homepage" > public_html/index.html
[root@server ~ 10:29:02]# ll /home/

total 0
drwx------. 4 whisky whisky 106 8月   3 15:05 whisky
[root@server ~ 10:30:21]# mkdir -p /home/whsiky/
[root@server ~ 10:31:02]# chmod o+x /home/whsiky/

# 未启用布尔值访问
[root@centos7 ~]# curl http://server.laoma.cloud:18020/~laoma/
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
</body></html>

# 启用布尔值访问
[root@centos7 ~]# setsebool httpd_enable_homedirs=1
[root@centos7 ~]# curl http://server.laoma.cloud:18020/~laoma/
Welcome to laoma home

调查和解决 SELinux 问题

SELinux 文档

selinux-policy-doc 软件包附带SELinux man page,介绍了 SELinux 使用方法。

bash 复制代码
[root@centos7 ~]# yum install -y selinux-policy-doc
[root@centos7 ~]# mandb
[root@centos7 ~]# man -k '_selinux'
......
httpd_selinux (8)    - Security Enhanced Linux Policy for the httpd processes
......

[root@centos7 ~]# man httpd_selinux
setroubleshoot-server 软件包

setroubleshoot-server 软件包中的 setroubleshoot 服务提供了诊断 SELinux 问题的⼯具。当 SELinux 拒绝某一操作时,会在 /var/log/audit/audit.log 安全⽇志文件中记录一条Access Vector Cache (AVC) 消息。SELinux 故障排除服务会监控 AVC 事件,并将事件摘要发送到 /var/log/messages 文件。

示例:基于上述实验环境模拟。

bash 复制代码
# 安装软件包
[root@centos7 ~]# yum install -y httpd setroubleshoot-server

# 关闭 httpd_enable_homedirs布尔值
[root@centos7 ~]# setsebool httpd_enable_homedirs=0

# 监控日志 /var/log/messages
[root@centos7 ~]# tail -f /var/log/messages

# 访问站点
[root@centos7 ~]# curl http://server.laoma.cloud:18020/~laoma/
Welcome to laoma home

# 此时日志显示
[root@centos7 ~]# tail -f /var/log/messages
......
Nov 30 10:39:34 server setroubleshoot[4035]: SELinux is preventing /usr/sbin/httpd from getattr access on the file /home/laoma/public_html/index.html. For complete SELinux messages run: sealert -l bb10b03c-bed2-4853-85cb-92c1824fd75d
......

# 根据提示进一步查看 SELinux 消息
[root@centos7 ~]# sealert -l bb10b03c-bed2-4853-85cb-92c1824fd75d
bash 复制代码
SELinux is preventing /usr/sbin/httpd from getattr access on the file /home/laoma/public_html/index.html.

*****  Plugin public_content (32.5 confidence) suggests   ********************

If you want to treat index.html as public content
Then you need to change the label on index.html to public_content_t or public_content_rw_t.
Do
# semanage fcontext -a -t public_content_t '/home/laoma/public_html/index.html'
# restorecon -v '/home/laoma/public_html/index.html'

*****  Plugin catchall_boolean (32.5 confidence) suggests   ******************

If you want to allow httpd to enable homedirs
Then you must tell SELinux about this by enabling the 'httpd_enable_homedirs' boolean.

Do
setsebool -P httpd_enable_homedirs 1

*****  Plugin catchall_boolean (32.5 confidence) suggests   ******************

If you want to allow httpd to unified
Then you must tell SELinux about this by enabling the 'httpd_unified' boolean.

Do
setsebool -P httpd_unified 1

*****  Plugin catchall (4.5 confidence) suggests   ***************************

If you believe that httpd should be allowed getattr access on the index.html file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'httpd' --raw | audit2allow -M my-httpd
# semodule -X 300 -i my-httpd.pp
......

提示给出了多种解决方法:

  1. 修改文件上下文。
  2. 设置布尔值。
SELinux 问题处理思路
  1. 确定是否是 SELinux 引起的。
  2. 在做调整前,首先考虑 SELinux 是否正确的阻止了访问。例如web服务器尝试访问/home目录,如果web的内容不是用户发布的,那么发生阻止信号是正确的阻止。如果这个访问是被允许的,参考下面步骤。
  3. 最常见的 SELinux 问题是不正确的文件上下文。当文件是另外一个地方创建的,然后移动到新的地方,而新的地方需要新的上下文。在大多数情况,执行restorecon可以修复这个问题。这种修复问题方式对系统其他部分安全影响非常小。
  4. 另外一个问题可能是布尔值设置不当导致拒绝访问。例如ftpd_anon_write布尔值控制匿名ftp用户是否可以上传文件。如果如需匿名用户上传文件,需要打开这个布尔值。调整布尔值需要小心,因为对系统影响范围比较大。
  5. 还有可能是 端口上下文不匹配。
  6. 还有可能是 SELinux bug。
相关推荐
用户9623779544840 分钟前
DVWA 靶场实验报告 (High Level)
安全
NineData1 小时前
数据库迁移总踩坑?用 NineData 迁移评估,提前识别所有兼容性风险
数据库·程序员·云计算
数据智能老司机4 小时前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机4 小时前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954485 小时前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star5 小时前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954489 小时前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
chlk1231 天前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑1 天前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件1 天前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux