用于php-fpm套接字的SElinux标签

我试图设置php-fpm的多个实例,通过运行在centos 6.5上的apache 2.2来运行多个版本的php。

在未来的某个时候,这将会在一个共享的宿主环境中结束,所以我需要最紧密的安全。

因此,我试图避免完全禁用selinux,并试图尽可能缩小策略。

我对selinux比较新(我们现有的服务器只是禁用了它)。 我在这个话题上做了大量的阅读,但逻辑仍然逃避了我(正如我确信这个问题所表明的那样)。

当调用一个php脚本apache产生这个错误:

[Sun May 18 10:46:17 2014] [error] [client 192.168.163.1] (13)Permission denied: FastCGI: failed to connect to server "/fcgi-bin-php5-fpm-i10000_test-1.testtest.org": connect() failed [Sun May 18 10:46:17 2014] [error] [client 192.168.163.1] FastCGI: incomplete headers (0 bytes) received from server "/fcgi-bin-php5-fpm-i10000_test-1.testtest.org" 

包含php-fpm套接字的目录如下所示:

 drwxr-xr-x. root root system_u:object_r:var_run_t:s0 . drwxr-xr-x. root root system_u:object_r:var_run_t:s0 .. srw-------. apache apache unconfined_u:object_r:var_run_t:s0 apache_default.sock srw-------. apache apache unconfined_u:object_r:var_run_t:s0 i10000_test-1.testtest.org.sock srw-------. apache apache unconfined_u:object_r:var_run_t:s0 i10000_test-2.testtest.org.sock srw-------. apache apache unconfined_u:object_r:var_run_t:s0 i10000_test-3.testtest.org.sock -rw-r--r--. root root unconfined_u:object_r:var_run_t:s0 php-fpm-5.3.pid -rw-r--r--. root root unconfined_u:object_r:initrc_var_run_t:s0 php-fpm.pid 

基于此,我会假设套接字的types是var_run_t

所以我试图在这个政策下运行:

 policy_module(httpd_php_fpm, 1.0) require { type unconfined_t; type var_run_t; type httpd_t; type httpd_sys_content_t; class sock_file write; } #============= httpd_t ============== allow httpd_t var_run_t:sock_file write; #doesn't work allow httpd_t var_run_t:unix_stream_socket connectto; #works #allow httpd_t unconfined_t:unix_stream_socket connectto; 

但它拒绝访问套接字。

audit.log说:

 type=AVC msg=audit(1400402777.579:642): avc: denied { connectto } for pid=11068 comm="httpd" path="/var/run/php-fpm/i10000_test-1.testtest.org.sock" scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=unix_stream_socket type=SYSCALL msg=audit(1400402777.579:642): arch=c000003e syscall=42 success=no exit=-13 a0=c a1=7ffe42329818 a2=32 a3=0 items=0 ppid=6136 pid=11068 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null) 

audit2allow -a产生:

 allow httpd_t unconfined_t:unix_stream_socket connectto; 

tcontext=unconfined_u:unconfined_r:unconfined_t来自何时目标是套接字,并且套接字被标记为var_run_t

通过audit2allow改变为“build议” unconfined_t它的作品(上面注释)。 但据我所知,添加涉及unconfined_t策略是一个坏主意(因为它允许访问大量不需要的套接字)?

任何人都可以告诉我我误解了什么 – 或者如果我完全错误地解决问题,我该如何处理这个问题?

更新:好的,所以'unconfined_t'来自父级php-fpm主进程; 而不是从.sock文件。

ps xZ | grep php-fpm ps xZ | grep php-fpm

 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 31436 ? Ss 0:00 php-fpm: master process (/etc/php-5.3/php-fpm.conf) 
  • 有没有什么合乎逻辑的解释,这不是反映在ls -Z

  • 这是否意味着问题实际上比我最初怀疑的要严重? IE浏览器。 php-fpm进程运行不受限制,几乎可以做任何事情。

更新:我设法让php-fpm运行在与apache相同的域中,只需简单地:

 chcon system_u:object_r:httpd_exec_t:s0 /usr/php-multi/5.3.28/sbin/php-fpm 

Apache已经定义了转换规则和selinux策略,所以一旦启动,无论是在启动时还是在手动service php-fpm-5.3 start (或restart )之后,进程都会自动转换到httpd_t域,阿帕奇没有打嗝。

但是我仍然不确定这个(与Apache共享域)一个理想的情况(仍然从安全的angular度来看)。 我是否应该继续尝试将其纳入自己的域并手动定义策略?

更新(我在这里是新的,所以有人告诉我是否不适合继续更新问题?):

我发现了如何创build一个新的types,并让php-fpm守护进程在那里运行; 这是我的新政策:

 policy_module(httpd_php_fpm, 1.0) require { type httpd_t; type var_run_t; type locale_t; type httpd_sys_content_t; } #============= httpd_t ============== allow httpd_t var_run_t:sock_file write; #============= php_fpm_t ============== type php_fpm_exec_t; files_type(php_fpm_exec_t); type php_fpm_t; files_type(php_fpm_t); allow php_fpm_t httpd_sys_content_t:file { read getattr open ioctl append }; allow php_fpm_t locale_t:dir search; allow php_fpm_t locale_t:file { read getattr open }; allow php_fpm_t self:capability { setuid chown kill setgid }; allow php_fpm_t self:process { signal sigkill }; allow php_fpm_t var_run_t:dir { write remove_name add_name }; allow php_fpm_t var_run_t:file { write create unlink open }; allow php_fpm_t var_run_t:sock_file { write create unlink setattr }; init_daemon_domain(php_fpm_t, php_fpm_exec_t) 

这些规则是用audit2allow生成的,并且可能允许超过需要,但是这个工作…当然, php-fpm二进制文件仍然需要被赋予新的types:

 chcon system_u:object_r:php_fpm_exec_t:s0 /usr/php-multi/5.3.28/sbin/php-fpm 

我仍然不确定哪个解决scheme实际上是最好的安全策略。

对于一般方法的任何意见,或对潜在改进政策的build议,

尝试这个

 policy_module(httpd_php_fpm, 1.0) require { type httpd_t; type var_run_t; } #============= httpd_t ============== allow httpd_t var_run_t:sock_file write_sock_file_perms; allow httpd_t var_run_t:unix_stream_socket client_stream_socket_perms; ## not sure what this is for but.. init_stream_connect_script(httpd_t) 

编辑

考虑一下, php-fpm实际上在做web服务器的function。 尝试将/usr/sbin/php-fpm/etc/rc.d/init.d/php-fpm分别设置为httpd_exec_thttpd_initrc_exec_t ,然后查看如何实现。

如果你重写一个策略,你需要考虑一些事情:

  • 你应该确保tmp文件被标记为特殊的东西。
  • 使php-fpm也将var_run套接字和pid文件标记为特殊的东西,然后修改apache以便能够连接到它们。
  • 执行PHP脚本时, php-fpm可能需要数据库访问。
  • 您可能需要允许php-fpm监听特定的networking端口,并让apache连接到它们以及unix套接字。
  • 您需要定义一个用于指定文件上下文的fc文件。
  • 确保php-fpm可以做其他的事情,如imap,pop3,smtp,http,https至less有几个。
  • 必须能够写回允许写入的httpd内容,并使用正确的标签。
  • 必须能够读取httpd的user_contenttypes以及系统的types。

限制编程语言的效果可能相当棘手,因为该策略需要与多种不同的Web应用程序一起工作的程度如何。