CGI脚本无法打开套接字(CentOS 6.2 / Apache2)

我有一个运行CentOS 6.2的networking服务器,以及来自仓库的最新的Apache。 Todey在Apache上通过CGI运行可执行程序时遇到了一个问题。 该程序应该连接到一些网站,下载一些东西,然后返回给用户(正常的端口80请求,没有什么可疑的)。

问题是,CGI程序返回Permission deniedsocket_open命令上Permission denied

其他更简单的CGI程序,不需要networking连接工作正常,这个程序工作,以及从命令行调用,所以我怀疑一些权限问题,因为设置可执行文件setuid没有解决问题,我来到这是SELinux控制的结论。

我从来没有真正与SELinux合作,但getsebool -a | grep httpd getsebool -a | grep httpd返回

 allow_httpd_anon_write --> off allow_httpd_mod_auth_ntlm_winbind --> off allow_httpd_mod_auth_pam --> off allow_httpd_sys_script_anon_write --> off httpd_builtin_scripting --> on httpd_can_check_spam --> off httpd_can_network_connect --> off httpd_can_network_connect_cobbler --> off httpd_can_network_connect_db --> off httpd_can_network_memcache --> off httpd_can_network_relay --> off httpd_can_sendmail --> off httpd_dbus_avahi --> on httpd_enable_cgi --> on httpd_enable_ftp_server --> off httpd_enable_homedirs --> off httpd_execmem --> off httpd_read_user_content --> off httpd_setrlimit --> off httpd_ssi_exec --> off httpd_tmp_exec --> off httpd_tty_comm --> on httpd_unified --> on httpd_use_cifs --> off httpd_use_gpg --> off httpd_use_nfs --> off 

我怀疑httpd_can_network_connect --> off在这里是有问题的,但这是httpd httpd_can_network_connect --> off ,而不是实际的可执行文件。 SELinux权限是从父进程inheritance的吗? 我如何将它设置为只为脚本启用,而不是整个httpd ? 还是有一个完全不同的问题,而不是一个SELinux相关的?

谢谢你的帮助。

编辑:我试过setenforce 0和脚本正在工作,所以这是一个SELinux的东西。

编辑2ausearch -ts recent -m avc返回

 time->Thu May 3 23:52:29 2012 type=SYSCALL msg=audit(1336081949.221:18563): arch=c000003e syscall=42 success=no exit=-13 a0=8 a1=7fff21161cb0 a2=10 a3=7fff21161a30 items=0 ppid=6813 pid=6814 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm=".stutsk" exe="/var/www/html/stutsk-cgi/.stutsk" subj=system_u:system_r:httpd_sys_script_t:s0 key=(null) type=AVC msg=audit(1336081949.221:18563): avc: denied { name_connect } for pid=6814 comm=".stutsk" dest=80 scontext=system_u:system_r:httpd_sys_script_t:s0 tcontext=system_u:object_r:http_port_t:s0 tclass=tcp_socket 

就个人而言,如果允许CGI处理能够从networking中获取东西(只是让我感觉不舒服),可以保留,但是可以使用以下策略启用它:

 policy_module(localhttpd_script_t, 1.0.0) gen_require(` type httpd_sys_script_t; type http_port_t; ') gen_tunable(`httpd_script_can_http_connect', `false') tunable_policy(`httpd_script_can_http_connect', ` allow httpd_sys_script_t self:tcp_socket rw_socket_perms; corenet_tcp_connect_http_port(httpd_sys_script_t) corenet_tcp_sendrecv_http_port(httpd_sys_script_t) ') 

如果还没有完成,你需要安装policycoreutils-python

要做到这一点,运行

 make -f /usr/share/selinux/devel/Makefile load 

这将编译和安装模块。 我编译了Fedora 15,但是我不认为这个系统特有的特殊策略。

要打开这个(暂时)运行命令setsebool httpd_script_can_http_connect 1并使永久setsebool -P httpd_script_can_http_connect 1

SELinux权限是从父进程inheritance的吗?

是的,除非规则导致转换到新域。

我如何将它设置为只为脚本启用,而不是整个httpd?

您需要创build一个允许networking访问的新域,并编写一个在脚本解释器被调用时导致域转换的规则。 请注意,这将导致由httpd调用的任何脚本被该解释器调用以跟随此转换; 导致特定于脚本的域转换并不那么简单。