From Fedora Project Wiki

在 SELinux 设置为 targeted enforcing 时使用 Zend

成果


问题

安装 Zend Optimizer 3.3.0 后,无法在 SELinux targeted enforcing 模式下运行。

安装 Zend

系统中需要装有 apache httpd 和 php,使用 yum install httpd php 安装

在 www.zend.com 下载 Zend Optimizer, 2007-08-03 当日版本为 3.3.0。命令行下运行 ./install 会有提示安装路径,选择 /opt/Zend/ 目录。其他选项为默认。

准备调试环境

因为在 targeted permissive 模式下各种操作都不会带来问题,又可以得到全部的 selinux 调试信息(日志),因此首先运行 system-config-securitylevel 切换到这一模式。

运行 cat > /var/log/audit/audit.log 清空 audit.log,然后运行 service auditd restart 重启 auditd 服务。这一步操作在后面还需要做几次。同样的,cat > /var/log/messages 清空 messages,然后运行 service rsyslog restart 重启 rsyslog 服务。这一步操作不需要重复执行。

运行 service setroubleshoot status 确保 setroubleshoot 在运行。同样确保 auditd, rsyslog(在 fedora 7 中是 syslog) 在运行。

setroubleshoot 做些什么

setroubleshoot 负责将内核产生的 avc denied 消息(由 auditd 记录在 audit.log 中)加以翻译,将翻译结果发送给前端 sealert 小程序和 syslog(并写入 messages)。因此,只要这几个服务运行正常,在随后的调试过程中就可以在 sealert 和 messages 中看到需要的调试信息。

调试及解决每个调试信息中指出的错误

在两个终端分别运行 tail -f /var/log/audit/audit.log 和 tail -f /var/log/messages 查看日志的变化情况,在第三个终端进行操作。

第一阶段

运行 service httpd restart 启动 apache 服务。这时,messages 会记录三条消息,其中包含了获得更详细解释的办法。注意必须在 setroubleshoot 正在运行的时候才可以使用其中的指示,获得更详细的解释,因为 setroubleshoot 是消息的来源。

Aug  3 21:29:16 mstar setroubleshoot: #012    SELinux 正在
阻止 /usr/sbin/httpd 使用无标志文件 /opt/Zend/lib/ZendExtensionManager.so(usr_t)。#012
For complete SELinux messages. run sealert -l 0c37040d-27d6-4ee2-a173-b664480cac9b

Aug  3 21:29:16 mstar setroubleshoot: #012    SELinux 正在
阻止 /usr/sbin/httpd(httpd_t) "execmem"  <未知>。#012 阅读 audit.log 完整了解 SELinux 的消息。#012
For complete SELinux messages. run sealert -l dbd1c61d-9298-4bc9-8bd9-9bbde01cbcc1

Aug  3 21:29:16 mstar setroubleshoot: #012    SELinux 正在
阻止 /usr/sbin/httpd 装载 /opt/Zend/lib/Optimizer-3.3.0/php-5.2.x/ZendOptimizer.so,因为这需要文本重新布局。#012
For complete SELinux messages. run sealert -l e5509490-afb1-4b7c-b810-761489e656e7




[root@mstar ~] # sealert -l 0c37040d-27d6-4ee2-a173-b664480cac9b
摘要
SELinux 正在阻止 /usr/sbin/httpd 使用无标志文件
/opt/Zend/lib/ZendExtensionManager.so(usr_t)。

详细的描述
SELinux 拒绝了 /usr/sbin/httpd 对潜在错误标签的文件
/opt/Zend/lib/ZendExtensionManager.so 的访问。这意味着 SELinux
将不允许 http 使用这些文件。许多第三方应用程 序将 html
文件安装在 SELinux
策略无法预知的目录。这些目录必须以一个 httpd
能访问的文件上下文被标记。

<b>正在允许访问</b>
If you want to change the file context of
/opt/Zend/lib/ZendExtensionManager.so so that the httpd daemon can access
it, you need to execute it using chcon -t httpd_sys_content_t
/opt/Zend/lib/ZendExtensionManager.so.  You can look at the httpd_selinux
man page for additional information.

附加的信息

源上下文                  system_u:system_r:httpd_t
目标上下文               system_u:object_r:usr_t
目标对象                  /opt/Zend/lib/ZendExtensionManager.so [ file ] 
受影响的 RPM 包          httpd-2.2.4-4.1.fc7 [application] 
策略 RPM                    selinux-policy-3.0.4-3.fc8
Selinux 激活                True
策略类型                  targeted
MLS 激活                    True
强制模式                  Permissive
插件名称                  plugins.httpd_bad_labels
主机名                     mstar.sz
平台                        Linux mstar.sz 2.6.23-0.61.rc1.git9.fc8 #1 SMP Tue
Jul 31 17:23:22 EDT 2007 i686 i686
警告记数                  3
First Seen                    Fri Aug  3 20:34:21 2007
Last Seen                     Fri Aug  3 21:29:14 2007
Local ID                      0c37040d-27d6-4ee2-a173-b664480cac9b
行数

原始 Audit 消息

avc: denied { execute } for comm="httpd" dev=dm-0 egid=0 euid=0
exe="/usr/sbin/httpd" exit=946434048 fsgid=0 fsuid=0 gid=0 items=0
path="/opt/Zend/lib/ZendExtensionManager.so" pid=10084
scontext=system_u:system_r:httpd_t:s0 sgid=0 subj=system_u:system_r:httpd_t:s0
suid=0 tclass=file tcontext=system_u:object_r:usr_t:s0 tty=(none) uid=0


[root@mstar ~] # sealert -l dbd1c61d-9298-4bc9-8bd9-9bbde01cbcc1
摘要
SELinux 正在阻止 /usr/sbin/httpd(httpd_t) "execmem"  <未知>。 阅读
audit.log 完整了解 SELinux 的消息。

详细的描述
SELinux 拒绝了 /usr/sbin/httpd 请求的访问。 /usr/sbin/httpd
并不被期望请求这种访问,它可能是尝试入侵的一 个信号
。也可能是应用程序的特别版本或配置导致它请求附加的
访问。

<b>正在允许访问</b>
您可以产生一个本地策略模块来允许这个 访问 - 参阅
http://fedora.redhat.com/docs/selinux-faq-fc5/#id2961385 或您可以禁用
SELinux 保护。禁用 SELinux 保护的方法不被推荐使用。
请填写一个 http://bugzilla.redhat.com/bugzilla/enter_bug.cgi
来反映这个软件包的问题。

附加的信息

源上下文                  system_u:system_r:httpd_t
目标上下文               system_u:system_r:httpd_t
目标对象                  None [ process ] 
受影响的 RPM 包          httpd-2.2.4-4.1.fc7 [application] 
策略 RPM                    selinux-policy-3.0.4-3.fc8
Selinux 激活                True
策略类型                  targeted
MLS 激活                    True
强制模式                  Permissive
插件名称                  plugins.catchall
主机名                     mstar.sz
平台                        Linux mstar.sz 2.6.23-0.61.rc1.git9.fc8 #1 SMP Tue
Jul 31 17:23:22 EDT 2007 i686 i686
警告记数                  2
First Seen                    Fri Aug  3 20:34:21 2007
Last Seen                     Fri Aug  3 21:29:14 2007
Local ID                      dbd1c61d-9298-4bc9-8bd9-9bbde01cbcc1
行数

原始 Audit 消息

avc: denied { execmem } for comm="httpd" egid=0 euid=0 exe="/usr/sbin/httpd"
exit=0 fsgid=0 fsuid=0 gid=0 items=0 pid=10084
scontext=system_u:system_r:httpd_t:s0 sgid=0 subj=system_u:system_r:httpd_t:s0
suid=0 tclass=process tcontext=system_u:system_r:httpd_t:s0 tty=(none) uid=0


[root@mstar ~] # sealert -l e5509490-afb1-4b7c-b810-761489e656e7
摘要
SELinux 正在阻止 /usr/sbin/httpd 装载 /opt/Zend/lib/Optimizer-3.3.0/ph
p-5.2.x/ZendOptimizer.so,因为这需要文本重新布局。

详细的描述
/usr/sbin/httpd 应用程序试图读取/opt/Zend/lib/Optimizer-3.3.0/php-5.
2.x/ZendOptimizer.so,这将需要文本重定位。
这有潜在的安全问题。 多数程序库不需要这样做。有时候
程序库编码不正确会有这样的请求。
http://people.redhat.com/drepper/selinux-mem.html 页面说明如何移除
这个请求。你能够设置SELinux临时允许/opt/Zend/lib/Optimizer-3.3.0
/php-5.2.x/ZendOptimizer.so
在工作区使用重定位直到程序库被修正。
请生成一份关于这个程序包的
http://bugzilla.redhat.com/bugzilla/enter_bug.cgi

<b>正在允许访问</b>
If you trust /opt/Zend/lib/Optimizer-3.3.0/php-5.2.x/ZendOptimizer.so to run
correctly, you can change the file context to textrel_shlib_t. "chcon -t
textrel_shlib_t /opt/Zend/lib/Optimizer-3.3.0/php-5.2.x/ZendOptimizer.so"
You must also change the default file context files on the system in order
to preserve them even on a full relabel.  "semanage fcontext -a -t
textrel_shlib_t /opt/Zend/lib/Optimizer-3.3.0/php-5.2.x/ZendOptimizer.so"

以下命令将允许这个权限:
chcon -t textrel_shlib_t /opt/Zend/lib/Optimizer-3.3.0/php-5.2.x/ZendOptimizer.so

附加的信息

源上下文                  system_u:system_r:httpd_t
目标上下文               system_u:object_r:usr_t
目标对象                  /opt/Zend/lib/Optimizer-3.3.0/php-5.2.x/ZendOptimi
zer.so [ file ] 
受影响的 RPM 包          httpd-2.2.4-4.1.fc7 [application] 
策略 RPM                    selinux-policy-3.0.4-3.fc8
Selinux 激活                True
策略类型                  targeted
MLS 激活                    True
强制模式                  Permissive
插件名称                  plugins.allow_execmod
主机名                     mstar.sz
平台                        Linux mstar.sz 2.6.23-0.61.rc1.git9.fc8 #1 SMP Tue
Jul 31 17:23:22 EDT 2007 i686 i686
警告记数                  3
First Seen                    Fri Aug  3 20:34:21 2007
Last Seen                     Fri Aug  3 21:29:14 2007
Local ID                      e5509490-afb1-4b7c-b810-761489e656e7
行数

原始 Audit 消息

avc: denied { execmod } for comm="httpd" dev=dm-0 egid=0 euid=0
exe="/usr/sbin/httpd" exit=0 fsgid=0 fsuid=0 gid=0 items=0
path="/opt/Zend/lib/Optimizer-3.3.0/php-5.2.x/ZendOptimizer.so" pid=10084
scontext=system_u:system_r:httpd_t:s0 sgid=0 subj=system_u:system_r:httpd_t:s0
suid=0 tclass=file tcontext=system_u:object_r:usr_t:s0 tty=(none) uid=0



其中,第一条表示 apache 无法读取 Zend 的 .so 文件所在的目录,于是无法读取文件。它的解决方法是运行 chcon -t httpd_sys_content_t /opt/Zend/lib/Optimizer-3.3.0/php-5.2.x/ 为目录设置 httpd_sys_content_t 属性。第二条表示 apache 没有 execmem 权限,这一条处理比较困难,留到后面解决。第三条表示 Zend 的 .so 需要代码重定位。它的解决方法是运行 chcon -t textrel_shlib_t /opt/Zend/lib/Optimizer-3.3.0/php-5.2.x/ZendOptimizer.so 为文件设置 textrel_shlib_t。注意第一条的提示消息是错误的,因为与第三条冲突,不可能为一个文件同时设置两个不同的属性,实际应该为文件夹指定那一属性才是。


第二阶段

再次运行 service httpd restart 重启 apache 服务,这次除了尚未处理的 execmem 外,还有一个新的问题。根据提示,apache 无法读取 Zend 的另一个 .so 文件所在的目录 /opt/Zend/lib,于是无法读取文件。于是运行 chcon -t httpd_sys_content_t /opt/Zend/lib/ 同样为目录设置 httpd_sys_content_t 属性。

注意在不同的系统中,可能加载 .so 的顺序不同,因此调试遇到的信息和应当执行的正确处理方式也不同,请灵活变通。


第三阶段

只有 execmem 错误了,在 audit.log 中可以看到,实际还有另一个错误 execstack。

按照提示,运行命令 grep exec /var/log/audit/audit.log | audit2allow -M myhttpexec; semodule -i myhttpexec.pp 将 httpd_t 的 execmem 和 execstack 权限打开。这段提示可以在 fc5 selinux faq 看到。Thanks to DanielWalsh (dwalsh of #fedora-selinux)!

<hers>	dwalsh_~ are you there?
<dwalsh_>	yes
[23:42] 	<hers>	I have a little problem running Zend Optimizer in apache. The z-o is 3.3.0 (latest) while the httpd, policies are rawhide latest.
With the help of sealert and setroubleshoot, I can solve 3 of the avc denied message, but I think I have to learn something about booleans to solve the rest 2.
<hers>	the problem is execmem and execstack is required for httpd. I enabled "allow_execmem" but it has no effect, so I think a new boolean should be introduced?
[23:44] 	dwalsh_~ could you help me? btw, you've long not blogged! /me want to read more your articles.
[23:50] 	<dwalsh_>	hers, more are coming.
[23:51] 	I think you will need to create a loadable policy module to handle the execmem execmod problems.
grep exec /var/log/audit/audit.log | audit2allow -M myhttpexec; semodule -i myhttpexec.pp
<hers>	like said in the fc5 selinux faq? looks so complicated :(
[23:52] 	<dwalsh_>	No it is fairly easy.
Are you running FC5?
<hers>	no, rawhide.
[23:53] 	<dwalsh_>	I am not familiar with Zend Optimizer. Are the avc's httpd_t or httpd_sys_script_t?
[23:54] 	<hers>	httpd_t
not running any CGI yet, just service restart
type=AVC msg=audit(1186156444.187:363): avc: denied { execstack } for pid=20365 comm="httpd" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=process
type=AVC msg=audit(1186156444.187:363): avc: denied { execmem } for pid=20365 comm="httpd" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=process
[23:57] 	done that. it is now up and running in targeted enforcing mode! Thanks. what is the security risk of doing this?
[00:03] 	<dwalsh_>	It takes away some buffer overflow protection on the apache process. These checks basically stop writable memory from also being executable.
[00:04] 	http://people.redhat.com/~drepper/selinux-mem.html
[00:05] 	Overall you are still getting more protection from SELinux in enforcing mode, So I don't see this as a problem. You might want to report this as a bug to Zend. Attaching the above link.
<hers>	bad Zend programmers. :(
[00:06] 	<dwalsh_>	Maybe

注意在执行前做前面提到的 清空 audit.log 的操作,然后重新启动 apache 以获得唯一的错误记录。

验证结果

再次重启 apache,检验 audit.log 和 messages 都不再产生新的错误记录。

运行 echo '<? phpinfo(); ?>' > /var/www/html/index.php 建立网页以验证结果。访问 http://localhost/index.php 如果看到 Zend Engine 已加载 Zend Optimizer 那么就是正确的结果。


仍然存在的问题

正如 Dan 在 IRC 日志中提到的那样,危害最大的修改是去掉了 execmem 和 execstack 的保护,使 apache 可能遭到缓冲区溢出攻击。详细内容请查看他推荐的网页。但是,由于 selinux targeted enforcing 的强大安全性,这样的攻击不会带来很大威胁。真正的解决办法是联系 Zend 开发者,让他们为 selinux 调整代码(或者改善安装程序)。

使用 semodule -r myhttpexec 以删除刚才为处理 execmem 和 execstack 而为 httpd_t 增加的权限。 使用 restorecon 恢复文件和目录的权限为初始默认值。


DanielWalsh http://danwalsh.livejournal.com