在 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