User:Bbbush/draft/ZendInSELinux

在 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 能访问的文件上下文被标记.

正在允许访问 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 并不被期望请求这种访问，它可能是尝试入侵的一 个信号 . 也可能是应用程序的特别版本或配置导致它请求附加的 访问.

正在允许访问 您可以产生一个本地策略模块来允许这个 访问 - 参阅 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

正在允许访问 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/Zend Optimizer.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)!

dwalsh_~ are you there? 	yes [23:42] 	 	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. 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] 		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 like said in the fc5 selinux faq? looks so complicated :( [23:52] 		No it is fairly easy. Are you running FC5? 	no, rawhide. [23:53] 		I am not familiar with Zend Optimizer. Are the avc's httpd_t or httpd_sys_script_t? [23:54] 	 	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] 		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. bad Zend programmers. :( [00:06] 		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