5.3. 修复分析的 SELinux 拒绝问题
在大多数情况下,sealert
工具提供的建议将为您提供有关如何修复与 SELinux 策略相关的问题的正确指导。有关如何使用 sealert
分析 SELinux 拒绝的信息,请参阅分析 SELinux 拒绝信息。
当工具建议使用 audit2allow
工具进行配置更改时,请小心。当您看到 SELinux 拒绝时,您不应该使用 audit2allow
来生成本地策略模块作为您的第一个选项。故障排除应该先检查是否有标记问题。第二个最常见的情况是您更改了进程配置,并且忘记了要让 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 file-context 配置的上下文。semanage
程序不会更改上下文。以 root 用户身份,使用 restorecon
程序应用更改:
# restorecon -R -v /srv/myweb
不正确的上下文
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.html
和 page1.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
以非标准方式配置受限应用程序
服务可以以多种方式运行。要考虑这一点,您需要指定如何运行您的服务。您可以通过 SELinux 布尔值达到此目的,允许在运行时更改 SELinux 策略的部分。这启用了更改,比如允许服务访问 NFS 卷而无需重新载入或者重新编译 SELinux 策略。另外,在非默认端口号中运行服务需要使用 semanage
命令来更新策略配置。
例如,要允许 Apache HTTP 服务器与 MariaDB 通信,请启用 httpd_can_network_connect_db
布尔值:
# setsebool -P httpd_can_network_connect_db on
请注意,-P
选项可使系统重启后设置具有持久性。
如果特定服务无法访问,请使用 getsebool
和 grep
实用程序查看是否有布尔值是否可用于访问。例如,使用 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
命令。要获得包括布尔值的列表,并找出它们是否启用或禁用,请安装 selinux-policy-devel
软件包并以 root 用户身份使用 semanage boolean -l
命令。
端口号
根据策略配置,服务只能在某些端口号中运行。尝试更改服务在没有更改策略的情况下运行的端口可能会导致服务无法启动。例如,以 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
命令为端口分配不同的标签:
# semanage port -a -t http_port_t -p tcp 9876
a
选项添加新的记录; -t
选项定义类型; -p
选项定义协议。最后的参数是要添加的端口号。
个别情况、演变或损坏的应用程序以及被破坏的系统
应用程序可能会包含程序漏洞,从而导致 SELinux 拒绝访问。另外,SELinux 规则会不断演变 - SELinux 可能没有了解某个应用程序会以某种特定方式运行,因此即使应用程序按预期工作,也有可能出现拒绝访问的问题。例如,当一个 PostgreSQL 的新版本发布后,它可能会执行一些当前策略无法处理的操作,从而导致访问被拒绝,即使应该允许访问。
对于这样的情形,在访问被拒绝后,使用 audit2allow
实用程序创建自定义策略模块以允许访问。您可以在 Red Hat Bugzilla 中报告 SELinux 策略中缺少的规则。对于 Red Hat Enterprise Linux 9,针对 Red Hat Enterprise Linux 9
产品创建 bug,然后选择 selinux-policy
组件。在此类程序漏洞报告中包含 audit2allow -w -a
和 audit2allow -a
命令的输出。
如果应用程序请求主要的安全特权,这可能代表,应用程序可能已被破坏。使用入侵检测工具检查此类行为。
红帽客户门户网站中的 Solution Engine 也以文章的形式提供了相关的指导信息。它包括了您遇到的相同或非常类似的问题的解决方案。选择相关的产品和版本,并使用与 SELinux 相关的关键字,如 selinux 或 avc,以及您阻断的服务或应用程序的名称,例如: selinux samba
。