在 CentOS8 上使用 SELinux 上下文进行 Apache vhost 权限分离

在 CentOS8 上使用 SELinux 上下文进行 Apache vhost 权限分离

我有一台服务器上有多个应用程序,其中一个是专有代码,另一个可以根据我们的需求检查服务器上的文件。这不行。我试图实现每个虚拟主机的权限分离,以防止一个检查另一个。有几个减轻处罚的情况使情况变得复杂……

  • CentOS8
  • 必须使用 SELinux
  • Apache 2.4.37、PHP73、FCGI、PHP_FPM...使用mpm_event
  • mod_permissions,CentOS8 上开箱即用的mod_itk/mpm_itk模块mod_selinux

自 SELinux 以来必须在我们的案例中启用,并且它还提供了实现我们目的的最佳粒度,我已经开始走这条路了。为了安装它(从 Fedora Core 31 src),我遵循了以下步骤...

  1. dnf install httpd-devel selinux-policy-devel
  2. wget https://download.fedoraproject.org/pub/fedora/linux/releases/31/Everything/source/tree/Packages/m/mod_selinux-2.4.4-14.fc31.src.rpm
  3. rpmbuild --rebuild mod_selinux-2.4.4-14.fc31.src.rpm --define "_rpmdir /tmp"
  4. dnf install /tmp/x86_64/mod_selinux-2.4.4-14.el8.x86_64.rpm

一切进展顺利,没有错误,所有东西都安装在了应有的位置。

我已将我们服务器范围的设置合并到一个httpd.conf文件中,而不是使用许多不同的配置文件conf.d(这主要是因为使用 ansible 模板并在一个地方查看所有内容时比较简单)。注意:这不包括我们每一个vhost仍然是独立的conf文件/声明,并且包括单独地。

httpd 上下文的默认声明是...

selinuxServerDomain    *:s0

我有 4x 个虚拟主机,希望将它们分隔开来,并且想为将来的扩展留出空间,因此我将该声明调整为以下内容并将其添加到我的httpd.conf文件中...

selinuxServerDomain    *:s0-s0:c0.c50

然后我分别在每个vhost声明中添加了以下内容......

selinuxDomainVal *:s0:c10
selinuxDomainVal *:s0:c20
selinuxDomainVal *:s0:c30
selinuxDomainVal *:s0:c40

最后,我更改了每个相应 vhost 站点上的文档根目录的上下文,如下所示...

chcon -R -l s0:c10 /var/www/site1
chcon -R -l s0:c20 /var/www/site2
chcon -R -l s0:c30 /var/www/site3
chcon -R -l s0:c40 /var/www/site4

在使用 context-sites 之前,我已经使用标准 httpd 相关上下文(unconfined_u:object_r:httpd_sys_content_tsystem_u:object_r:httpd_sys_rw_content_t)成功运行了网站,因此我保持它们原样。

因此问题是,使用原始*:s0上下文,systemctl start httpd工作正常,尽管由于显而易见的原因,没有一个vhosts可访问,因为没有一个生成的处理程序使用正确的上下文。

但是,当我将上下文声明更改为时*:s0-s0:c0.c50systemctl start httpd失败。 status显示以下内容......

● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/httpd.service.d
           └─php73-php-fpm.conf
   Active: failed (Result: exit-code) since Fri 2020-01-10 09:56:45 EST; 7s ago
     Docs: man:httpd.service(8)
  Process: 19362 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
 Main PID: 19362 (code=exited, status=1/FAILURE)
   Status: "Reading configuration..."

Jan 10 09:56:45 myhost.tld systemd[1]: Stopped The Apache HTTP Server.
Jan 10 09:56:45 myhost.tld systemd[1]: Starting The Apache HTTP Server...
Jan 10 09:56:45 myhost.tld systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE
Jan 10 09:56:45 myhost.tld systemd[1]: httpd.service: Failed with result 'exit-code'.
Jan 10 09:56:45 myhost.tld systemd[1]: Failed to start The Apache HTTP Server.

我看不到任何有用的信息。同样journalctl -xe显示相同的消息行,没有额外的帮助。我唯一能找到的是error.log...

[Fri Jan 10 09:56:45.245476 2020] [core:notice] [pid 19362:tid 139989213628672] SELinux policy enabled; httpd running as context system_u:system_r:httpd_t:s0
[Fri Jan 10 09:56:45.253134 2020] [:error] [pid 19362:tid 139989213628672] (13)Permission denied: SELinux: setcon_raw("system_u:system_r:httpd_t:s0-s0:c0.c50") failed
AH00016: Configuration Failed

但由于我在处理 SEL 政策方面还处于起步阶段,我不太清楚它到底在告诉我什么。有人能帮我解释一下我在这里做错了什么吗?

我尝试在 conf 文件中上下移动上下文声明,以防它试图在另一个依赖项之前设置,但没有变化。我尝试在目录 contexts 中将上下文用户从 更改为 ,system_u然后unconfined_u又改回来,没有变化。不知道还能尝试什么。

提前感谢您提供的任何帮助!


编辑:

我能够获得关于AVC 拒绝来自审计日志...

type=AVC msg=audit(1578928482.042:458750): avc:  denied  { setcurrent } for  pid=11335 comm="httpd" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=process permissive=0
type=SYSCALL msg=audit(1578928482.042:458750): arch=c000003e syscall=1 success=no exit=-13 a0=d a1=55e37564e5c0 a2=29 a3=0 items=0 ppid=1 pid=11335 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null)^]ARCH=x86_64 SYSCALL=write AUID="unset" UID="root" GID="root" EUID="root" SUID="root" FSUID="root" EGID="root" SGID="root" FSGID="root"
type=PROCTITLE msg=audit(1578928482.042:458750): proctitle=2F7573722F7362696E2F6874747064002D44464F524547524F554E44
type=SERVICE_START msg=audit(1578928482.054:458751): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=httpd comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=failed'^]UID="root" AUID="unset"

这些帮助有用?

答案1

我回答这个问题是因为我找到了解决方案,但是我不太明白我做了什么,所以如果你能发表评论以提供澄清,我相信其他人会像我一样感激它......

为了在翻译中的神秘注释时获得更多帮助audit.log,我安装了两个实用程序:排除故障设置工具

dnf install setroubleshoot setools

它们到位后,我运行以下命令来分析audit.logAVC 错误...

sealert -a /var/log/audit/audit.log

回应是英语(与胡言乱语相比)并提供了一份有用的修复问题说明列表……

--------------------------------------------------------------------------------

SELinux is preventing /usr/sbin/httpd from using the setcurrent access on a process.

*****  Plugin catchall (100. confidence) suggests   **************************

If you believe that httpd should be allowed setcurrent access on processes labeled httpd_t 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


Additional Information:
Source Context                unconfined_u:system_r:httpd_t:s0
Target Context                unconfined_u:system_r:httpd_t:s0
Target Objects                Unknown [ process ]
Source                        httpd
Source Path                   /usr/sbin/httpd
Port                          <Unknown>
Host                          <Unknown>
Source RPM Packages           httpd-2.4.37-12.module_el8.0.0+185+5908b0db.x86_64
Target RPM Packages
Policy RPM                    selinux-policy-3.14.1-61.el8_0.2.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     ##REMOVEDFORPRIVACY###
Platform                      Linux ##REMOVEDFORPRIVACY###
                              4.18.0-80.11.2.el8_0.x86_64 #1 SMP Tue Sep 24
                              11:32:19 UTC 2019 x86_64 x86_64
Alert Count                   1
First Seen                    2020-01-09 18:02:47 EST
Last Seen                     2020-01-09 18:02:47 EST
Local ID                      22e251b9-72fc-42a1-875b-0db3ab095f9d

Raw Audit Messages
type=AVC msg=audit(1578610967.597:455070): avc:  denied  { setcurrent } for  pid=11650 comm="httpd" scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:system_r:httpd_t:s0 tclass=process permissive=0


type=SYSCALL msg=audit(1578610967.597:455070): arch=x86_64 syscall=write success=no exit=EACCES a0=c a1=56494ec9d5d0 a2=2c a3=0 items=0 ppid=11648 pid=11650 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=959 comm=httpd exe=/usr/sbin/httpd subj=unconfined_u:system_r:httpd_t:s0 key=(null)ARCH=x86_64 SYSCALL=write AUID=ecms UID=root GID=root EUID=root SUID=root FSUID=root EGID=root SGID=root FSGID=root

Hash: httpd,httpd_t,httpd_t,process,setcurrent

--------------------------------------------------------------------------------

解决方案是运行建议的命令......

ausearch -c 'httpd' --raw | audit2allow -M my-httpd
semodule -X 300 -i my-httpd.pp

之后我终于能够重新启动 Apache。

因此,很明显,按照上述步骤,我为 httpd 服务创建了一个自定义策略,但这就是我所了解的全部内容。这些命令未提及setcurrent错误报告中引用的命令/权限,并且这两个命令的输出均没有任何额外信息。我假设ausearch管道中的术语httpd本质audit2allow上使用错误报告来生成自定义策略,但我很想了解究竟发生了什么,以及该自定义策略现在存储在系统中的什么位置。

希望这会有所帮助,如果您能提供任何有用的解释说明原因,谢谢!

相关内容