11.2. 问题最多的三种原因


以下小节描述了问题的主要三个原因:标记问题、为服务配置布尔值和端口,以及不断发展的 SELinux 规则。

11.2.1. 标记问题

在运行 SELinux 的系统上,所有进程和文件都标有包含安全相关信息的标签。此信息称为 SELinux 上下文。如果这些标签错误,则可能会拒绝访问。标记不正确的应用可能会导致向其进程分配不正确的标签。这会导致 SELinux 拒绝访问,并且进程可能会创建标记错误的文件。
标记问题的常见原因是,当服务使用非标准目录时。例如,管理员想要使用 /srv/myweb/,而不是在网站中使用 /var/www/html/。在 Red Hat Enterprise Linux 中,/srv 目录使用 var_t 类型进行标记。在 /srv 中创建的文件和目录继承这个类型。另外,顶层目录中新创建的对象(如 /myserver)可以使用 default_t 类型进行标记。SELinux 会阻止 Apache HTTP 服务器(httpd)访问这两个类型。要允许访问,SELinux 必须知道 /srv/myweb/ 中的文件可以被 httpd 访问:
~]# semanage fcontext -a -t httpd_sys_content_t "/srv/myweb(/.*)?"
semanage 命令会将 /srv/myweb/ 目录(以及其下的所有文件和目录)的上下文添加到 SELinux 文件上下文配置中[8].semanage 程序不会更改上下文。以 root 用户身份运行 restorecon 工具以应用更改:
~]# restorecon -R -v /srv/myweb
有关在 file-context 配置中添加上下文的更多信息,请参阅 第 4.7.2 节 “持久性更改:semanage fcontext”

11.2.1.1. 什么是正确的上下文?

matchpathcon 程序检查文件路径的上下文,并将其与该路径的默认标签进行比较。以下示例演示了在包含错误标记文件的目录中使用 matchpathcon
~]$ matchpathcon -V /var/www/html/*
/var/www/html/index.html has context unconfined_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
/var/www/html/page1.html has context unconfined_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
在本例中,index.htmlpage1.html 文件使用 user_home_t 类型进行标识。这种类型用于用户主目录中的文件。使用 mv 命令从您的主目录移动文件可能会导致文件使用 user_home_t 类型进行标记。这个类型不应存在于主目录之外。使用 restorecon 实用程序将这些文件恢复到其正确类型:
~]# restorecon -v /var/www/html/index.html 
restorecon reset /var/www/html/index.html context unconfined_u:object_r:user_home_t:s0->system_u:object_r:httpd_sys_content_t:s0
要恢复目录中所有文件的上下文,请使用 -R 选项:
~]# restorecon -R -v /var/www/html/
restorecon reset /var/www/html/page1.html context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0
restorecon reset /var/www/html/index.html context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0
有关 matchpathcon 的详细示例,请参阅 第 4.10.3 节 “检查默认 SELinux 上下文”

11.2.2. 受限服务如何运行?

服务可以以多种方式运行。为了满足此需求,您需要指定如何运行您的服务。这可以通过布尔值来实现,允许在运行时更改 SELinux 策略的部分,而不必知晓编写 SELinux 策略。这允许更改,例如允许服务访问 NFS 卷,而无需重新加载或重新编译 SELinux 策略。另外,在非默认端口号中运行服务需要使用 semanage 命令来更新策略配置。
例如,要允许 Apache HTTP 服务器与 MariaDB 通信,请启用 httpd_can_network_connect_db 布尔值:
~]# setsebool -P httpd_can_network_connect_db on
如果特定服务无法访问,请使用 getseboolgrep 实用程序查看是否有布尔值可用于访问。例如,使用 getsebool -a | grep ftp 命令搜索 FTP 相关布尔值:
~]$ getsebool -a | grep ftp
ftpd_anon_write --> off
ftpd_full_access --> off
ftpd_use_cifs --> off
ftpd_use_nfs --> off

ftpd_connect_db --> off
httpd_enable_ftp_server --> off
tftp_anon_write --> off
如需布尔值列表以及是否处于打开状态,请运行 getsebool -a 命令。对于布尔值列表,请说明每个布尔值是什么,以及是否以 root 用户身份运行 semanage boolean -l 命令。有关列出和配置布尔值的详情,请查看 第 4.6 节 “布尔值”

端口号

根据策略配置,服务只能在某些端口号中运行。尝试更改服务在没有更改策略的情况下运行的端口可能会导致服务无法启动。例如,以 root 用户身份运行 semanage port -l | grep http 命令,以列出 http 相关端口:
~]# semanage port -l | grep http
http_cache_port_t              tcp      3128, 8080, 8118
http_cache_port_t              udp      3130
http_port_t                    tcp      80, 443, 488, 8008, 8009, 8443
pegasus_http_port_t            tcp      5988
pegasus_https_port_t           tcp      5989
http_port_t 端口类型定义了 Apache HTTP 服务器可以侦听的端口,本例中为 TCP 端口 80、443、488、8008、8009 和 8443。如果管理员配置了 httpd.conf,以便 httpd 侦听端口 9876(Listen 9876),但没有更新策略来反应这一点,以下命令会失败:
~]# systemctl start httpd.service
Job for httpd.service failed. See 'systemctl status httpd.service' and 'journalctl -xn' for details.
~]# systemctl status httpd.service
httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled)
   Active: failed (Result: exit-code) since Thu 2013-08-15 09:57:05 CEST; 59s ago
  Process: 16874 ExecStop=/usr/sbin/httpd $OPTIONS -k graceful-stop (code=exited, status=0/SUCCESS)
  Process: 16870 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
类似于以下内容的 SELinux 拒绝消息会记录到 /var/log/audit/audit.log
type=AVC msg=audit(1225948455.061:294): avc:  denied  { name_bind } for  pid=4997 comm="httpd" src=9876 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket
要允许 httpd 侦听没有为 http_port_t 端口类型列出的端口,请输入 semanage port 命令向策略配置添加端口[9]:
~]# semanage port -a -t http_port_t -p tcp 9876
a 选项 添加新记录; -t 选项定义类型; -p 选项定义协议。最后的参数是要添加的端口号。

11.2.3. 演进规则和损坏的应用程序

应用程序可能会损坏,从而导致 SELinux 拒绝访问。另外,SELinux 规则会不断演变 - SELinux 可能没有了解某个应用程序会以某种特定方式运行,因此即使应用程序按预期工作,也有可能出现拒绝访问的问题。例如,如果 PostgreSQL 的新版本发布,它可能会执行之前没有看到过的当前策略的操作,从而导致访问被拒绝,即使应该允许访问。
对于这样的情形,在访问被拒绝后,使用 audit2allow 实用程序创建自定义策略模块以允许访问。有关使用 audit2allow 的信息,请参阅 第 11.3.8 节 “允许访问: audit2 允许”


[8] /etc/selinux/targeted/contexts/files/ 中的文件为文件和目录定义上下文。此目录中的文件由 restoreconsetfiles 实用程序读取,用于将文件和目录恢复到其默认上下文。
[9] semanage port -a 命令在 /etc/selinux/targeted/modules/active/ports.local 文件中添加一个条目。请注意,默认情况下,该文件只能由 root 用户查看。
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.