我试图设置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_t
和httpd_initrc_exec_t
,然后查看如何实现。
如果你重写一个策略,你需要考虑一些事情:
php-fpm
可能需要数据库访问。 php-fpm
监听特定的networking端口,并让apache连接到它们以及unix套接字。 fc
文件。 user_content
types以及系统的types。 限制编程语言的效果可能相当棘手,因为该策略需要与多种不同的Web应用程序一起工作的程度如何。