Linux操作系统在嵌入式、移动设备和服务器上取得巨大成功的原因之一是内核、相关服务和应用程序具有相当高的安全性。 但如果
Linux 安全模块和 SELinux 的背景
安全增强型Linux是一套基于强制和基于角色的访问模型的规则和访问机制,旨在保护Linux系统免受潜在威胁,并纠正传统Unix安全系统自主访问控制(DAC)的缺点。 该项目起源于美国国家安全局内部,主要由承包商SecureComputingCorporation和MITRE以及多家研究实验室直接开发。
Linux 安全模块
Linus Torvalds 对 NSA 的新开发发表了许多评论,以便将它们包含在主线 Linux 内核中。 他描述了一个通用环境,其中包含一组拦截器来控制对象的操作,以及一组内核数据结构中的某些保护字段来存储相应的属性。 然后,可加载内核模块可以使用该环境来实现任何所需的安全模型。 LSM于2.6年全面进入Linux内核v2003。
LSM 框架在数据结构中包含保护字段,并在内核代码的关键点调用拦截函数来操作它们并执行访问控制。 它还添加了注册安全模块的功能。 /sys/kernel/security/lsm 接口包含系统上活动模块的列表。 LSM 挂钩存储在按照 CONFIG_LSM 中指定的顺序调用的列表中。 有关钩子的详细文档包含在头文件 include/linux/lsm_hooks.h 中。
LSM子系统使得SELinux与同版本的稳定Linux内核v2.6的完全集成成为可能。 几乎立即,SELinux 成为安全 Linux 环境的事实标准,并包含在最流行的发行版中:RedHat Enterprise Linux、Fedora、Debian、Ubuntu。
SELinux 术语表
- 身分 — SELinux 用户与通常的 Unix/Linux 用户 ID 不同;它们可以共存于同一系统上,但本质上完全不同。 每个标准Linux 帐户可以对应SELinux 中的一个或多个。 SELinux 身份是整体安全上下文的一部分,它决定您可以加入和不能加入哪些域。
- 域 - 在 SELinux 中,域是主体(即进程)的执行上下文。 域直接决定进程拥有的访问权限。 域基本上是进程可以执行的操作或进程可以对不同类型执行的操作的列表。 域的一些示例包括用于系统管理的 sysadm_t 和普通的非特权用户域 user_t。 init系统在init_t域中运行,named进程在named_t域中运行。
- 用户身份 — 充当域和 SELinux 用户之间中介的角色。 角色决定用户可以属于哪些域以及他们可以访问哪些类型的对象。 这种访问控制机制可以防止权限升级攻击的威胁。 角色被写入 SELinux 中使用的基于角色的访问控制 (RBAC) 安全模型中。
- 类型 — 分配给对象并确定谁可以访问该对象的类型强制列表属性。 与域定义类似,只不过域适用于进程,而类型适用于目录、文件、套接字等对象。
- 主体和客体 - 进程是主体并在特定上下文或安全域中运行。 操作系统资源:文件、目录、套接字等,是被分配某种类型(即隐私级别)的对象。
- SELinux 政策 — SELinux 使用多种策略来保护系统。 SELinux 策略定义用户对角色、角色对域以及域对类型的访问。 首先,用户被授权获得角色,然后角色被授权访问域。 最后,域只能访问某些类型的对象。
LSM 和 SELinux 架构
尽管有这个名称,LSM 通常并不是可加载的 Linux 模块。 然而,与 SELinux 一样,它是直接集成到内核中的。 对 LSM 源代码的任何更改都需要新的内核编译。 必须在内核设置中启用相应的选项,否则引导后LSM代码将不会被激活。 但即使在这种情况下,也可以通过操作系统引导加载程序选项来启用它。
LSM检查堆栈
LSM 在核心内核函数中配备了与检查相关的钩子。 LSM 的主要特征之一是它们是堆叠的。 因此,仍然执行标准检查,LSM的每一层仅添加额外的控制和控制。 这意味着该禁令无法撤销。 如图所示;如果例行 DAC 检查的结果是失败,那么问题甚至不会到达 LSM 挂钩。
SELinux采用Fluke研究操作系统的Flask安全架构,特别是最小权限原则。 顾名思义,这个概念的本质是仅授予用户或进程执行预期操作所需的权限。 该原理是使用强制访问类型来实现的,因此 SELinux 中的访问控制基于域 => 类型模型。
由于强制访问类型,SELinux 比 Unix/Linux 操作系统中使用的传统 DAC 模型具有更强的访问控制功能。 例如,您可以限制 ftp 服务器连接的网络端口号、允许写入和更改某个文件夹中的文件,但不允许删除它们。
SELinux 的主要组件有:
- 策略执行服务器 — 组织访问控制的主要机制。
- 系统安全策略数据库。
- 与 LSM 事件拦截器交互。
- 种子文件系统 - 伪FS,与/proc相同,挂载在/sys/fs/selinux中。 由 Linux 内核在运行时动态填充,并包含包含 SELinux 状态信息的文件。
- 访问向量缓存 ——提高生产力的辅助机制。
SELinux 的工作原理
一切都是这样的。
- 在 SELinux 术语中,某个主体在 DAC 检查后对对象执行允许的操作,如上图所示。 该执行操作的请求将发送至 LSM 事件拦截器。
- 从那里,请求连同主体和客体安全上下文一起被传递到 SELinux 抽象和钩子逻辑模块,该模块负责与 LSM 交互。
- 主体访问客体的决策机构是策略执行服务器,它从 SELinux AnHL 接收数据。
- 为了做出有关访问或拒绝的决策,策略执行服务器转向访问向量缓存 (AVC) 缓存子系统来获取最常用的规则。
- 如果在缓存中没有找到相应规则的解决方案,则将请求传递到安全策略数据库。
- 来自数据库和 AVC 的搜索结果返回到策略执行服务器。
- 如果找到的策略与请求的操作匹配,则允许该操作。 否则,禁止操作。
管理 SELinux 设置
SELinux 以三种模式之一运行:
- 执行 - 严格遵守安全策略。
- 允许 - 允许违反限制;在日志中做出相应的注释。
- 已禁用 — 安全策略未生效。
您可以使用以下命令查看 SELinux 处于什么模式。
[admin@server ~]$ getenforce
Permissive
重启前更改模式,例如设置为enforcing或1。permissive参数对应数字代码0。
[admin@server ~]$ setenfoce enforcing
[admin@server ~]$ setenfoce 1 #то же самое
您还可以通过编辑文件来更改模式:
[admin@server ~]$ cat /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=目标
与setenfoce的区别在于,当操作系统启动时,会按照配置文件中SELINUX参数的值设置SELinux模式。 此外,对强制 <=> 禁用的更改只能通过编辑 /etc/selinux/config 文件并在重新引导后生效。
查看简短的状态报告:
[admin@server ~]$ sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: permissive
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 31
要查看 SELinux 属性,一些标准实用程序使用 -Z 参数。
[admin@server ~]$ ls -lZ /var/log/httpd/
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log-20200920
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log-20200927
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log-20201004
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log-20201011
[admin@server ~]$ ps -u apache -Z
LABEL PID TTY TIME CMD
system_u:system_r:httpd_t:s0 2914 ? 00:00:04 httpd
system_u:system_r:httpd_t:s0 2915 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 2916 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 2917 ? 00:00:00 httpd
...
system_u:system_r:httpd_t:s0 2918 ? 00:00:00 httpd
与 ls -l 的正常输出相比,有几个附加字段,格式如下:
<user>:<role>:<type>:<level>
最后一个字段表示类似于安全分类的内容,由两个元素的组合组成:
- s0 - 显着性,也写为 lowlevel-highlevel 区间
- c0、c1…c1023 - 类别。
更改访问配置
使用 semodule 加载、添加和删除 SELinux 模块。
[admin@server ~]$ semodule -l |wc -l #список всех модулей
408
[admin@server ~]$ semodule -e abrt #enable - активировать модуль
[admin@server ~]$ semodule -d accountsd #disable - отключить модуль
[admin@server ~]$ semodule -r avahi #remove - удалить модуль
一队 管理登录 将 SELinux 用户连接到操作系统用户,第二个显示一个列表。 最后,带有 -r 开关的最后一个命令删除 SELinux 用户到操作系统帐户的映射。 MLS/MCS 范围值的语法说明在上一节中。
[admin@server ~]$ semanage login -a -s user_u karol
[admin@server ~]$ semanage login -l
Login Name SELinux User MLS/MCS Range Service
__default__ unconfined_u s0-s0:c0.c1023 *
root unconfined_u s0-s0:c0.c1023 *
system_u system_u s0-s0:c0.c1023 *
[admin@server ~]$ semanage login -d karol
团队 管理用户 用于管理 SELinux 用户和角色之间的映射。
[admin@server ~]$ semanage user -l
Labeling MLS/ MLS/
SELinux User Prefix MCS Level MCS Range SELinux Roles
guest_u user s0 s0 guest_r
staff_u staff s0 s0-s0:c0.c1023 staff_r sysadm_r
...
user_u user s0 s0 user_r
xguest_u user s0 s0 xguest_r
[admin@server ~]$ semanage user -a -R 'staff_r user_r'
[admin@server ~]$ semanage user -d test_u
命令参数:
- - 添加自定义角色映射条目;
- -l 匹配的用户和角色列表;
- -d 删除用户角色映射条目;
- -R 附加到用户的角色列表;
文件、端口和布尔值
每个 SELinux 模块都提供一组文件标记规则,但如果需要,您也可以添加自己的规则。 例如,我们希望Web服务器具有/srv/www文件夹的访问权限。
[admin@server ~]$ semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?
[admin@server ~]$ restorecon -R /srv/www/
第一个命令注册新的标记规则,第二个命令根据当前规则重置或设置文件类型。
同样,TCP/UDP 端口的标记方式使得只有适当的服务才能侦听它们。 例如,为了让Web服务器监听8080端口,您需要运行以下命令。
[admin@server ~]$ semanage port -m -t http_port_t -p tcp 8080
许多 SELinux 模块都具有可以采用布尔值的参数。 使用 getsebool -a 可以查看此类参数的完整列表。 您可以使用setsebool更改布尔值。
[admin@server ~]$ getsebool httpd_enable_cgi
httpd_enable_cgi --> on
[admin@server ~]$ setsebool -P httpd_enable_cgi off
[admin@server ~]$ getsebool httpd_enable_cgi
httpd_enable_homedirs --> off
研讨会,访问 Pgadmin-web 界面
让我们看一个实际的例子:我们在 RHEL 7.6 上安装了 pgadmin4-web 来管理 PostgreSQL 数据库。 我们走了一点
我们从典型的嫌疑人开始,检查 /var/log/httpd/error_log。 那里有一些有趣的条目。
[timestamp] [core:notice] [pid 23689] SELinux policy enabled; httpd running as context system_u:system_r:httpd_t:s0
...
[timestamp] [wsgi:error] [pid 23690] [Errno 13] Permission denied: '/var/lib/pgadmin'
[timestamp] [wsgi:error] [pid 23690]
[timestamp] [wsgi:error] [pid 23690] HINT : You may need to manually set the permissions on
[timestamp] [wsgi:error] [pid 23690] /var/lib/pgadmin to allow apache to write to it.
此时,大多数 Linux 管理员都会强烈地想要运行 setencorce 0,然后就结束了。 坦白说,我第一次就是这样做的。 这当然也是一种出路,但远非最好。
尽管设计繁琐,SELinux 仍然是用户友好的。 只需安装setroubleshoot包并查看系统日志即可。
[admin@server ~]$ yum install setroubleshoot
[admin@server ~]$ journalctl -b -0
[admin@server ~]$ service restart auditd
请注意,尽管操作系统中存在 systemd,但审计服务必须以这种方式重新启动,而不是使用 systemctl。 在系统日志中 将被指出 不仅包括阻塞的事实,还包括阻塞的原因和原因 克服禁令的方法.
我们执行这些命令:
[admin@server ~]$ setsebool -P httpd_can_network_connect 1
[admin@server ~]$ setsebool -P httpd_can_network_connect_db 1
我们检查对 pgadmin4-web 网页的访问,一切正常。
来源: habr.com