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

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

我有一个运行 CentOS 6.2 和来自存储库的最新 Apache 的 Web 服务器。今天我在 Apache 上通过 CGI 运行可执行程序时遇到了问题。该程序应该连接到某个站点,下载某些内容,然后将其返回给用户(正常的 80 端口请求,没什么可疑的)。

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

其他不需要网络连接的简单 CGI 程序运行良好,并且此程序从命令行调用时也运行良好,因此我怀疑存在一些权限问题,而且由于在setuid可执行文件上设置并不能解决问题,我得出结论,这是 SELinux 可以控制的事情。

我从来没有真正使用过 SELinux,但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,而不是实际的可执行文件。SELinux 权限是从父进程继承的吗?我该如何将其设置为仅为脚本启用而不是为整个 启用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

答案1

就我个人而言,对于允许 CGI 处理从网络获取内容有所保留(这让我感到不舒服),但您可以使用以下策略启用此功能:

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并使之永久设置sebool -P httpd_script_can_http_connect 1

答案2

SELinux 权限是否从父进程继承?

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

我该如何设置它,使其仅为脚本启用,而不是为整个 httpd 启用?

您需要创建一个允许网络访问的新域,并编写一条规则,在调用脚本解释器时触发域转换。请注意,这将导致此解释器调用的任何脚本在被 httpd 调用时都遵循此转换;触发特定于脚本的域转换则不那么简单。

相关内容