php-fpm 套接字的 SElinux 标签

Mik*_*lRo 7 selinux php-fpm socket apache-2.2 centos6.5

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

在未来的某个时候,这将最终出现在共享托管环境中,因此我需要尽可能严格的安全性。

因此,我试图避免完全禁用 selinux,并尝试将策略设置得尽可能窄。

我对 selinux 比较陌生(我们现有的服务器只是将其禁用)。我已经对这个主题进行了大量阅读,但逻辑仍然无法理解(正如我确定这个问题所显示的那样)。

调用 php-script 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"
Run Code Online (Sandbox Code Playgroud)

包含 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
Run Code Online (Sandbox Code Playgroud)

基于此,我假设套接字的类型是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;
Run Code Online (Sandbox Code Playgroud)

但它拒绝访问套接字。

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)
Run Code Online (Sandbox Code Playgroud)

audit2allow -a产生:

allow httpd_t unconfined_t:unix_stream_socket connectto;
Run Code Online (Sandbox Code Playgroud)

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

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

谁能告诉我我误解了什么 - 或者如果我只是完全错误地解决这个问题,我应该如何处理?

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

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)
Run Code Online (Sandbox Code Playgroud)
  • 是否有任何合乎逻辑的解释没有反映在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
Run Code Online (Sandbox Code Playgroud)

Apache 已经定义了转换规则和 selinux 策略,因此该进程httpd_t在启动后立即自动转换到域,无论是在启动期间还是在手动service php-fpm-5.3 start(或restart)之后 - 并且 PHP 通过 apache 执行而不会出现问题。

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

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

我发现了如何创建一个新类型并让 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)
Run Code Online (Sandbox Code Playgroud)

规则是用 audit2allow 生成的,可能允许比需要的更多,但这有效……当然,php-fpm二进制文件仍然需要被赋予新类型:

chcon system_u:object_r:php_fpm_exec_t:s0 /usr/php-multi/5.3.28/sbin/php-fpm
Run Code Online (Sandbox Code Playgroud)

我仍然不确定哪种解决方案实际上是最好的安全明智的。

我也仍然愿意接受关于一般方法的任何评论,或对本政策的潜在改进的建议......

Mat*_*Ife 1

尝试这个

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)
Run Code Online (Sandbox Code Playgroud)

编辑

想想看,php-fpm实际上就是在做网络服务器所做的事情。尝试分别设置/usr/sbin/php-fpm/etc/rc.d/init.d/php-fpmhttpd_exec_thttpd_initrc_exec_t,然后看看效果如何。

如果您为其重写策略,您需要考虑以下事项:

  • 您可能应该确保 tmp 文件被标记为特殊的东西。
  • 让 php-fpm 也为 var_run 套接字和 pid 文件添加一些特殊的标签,然后更改 apache 以便能够连接到它们。
  • php-fpm执行 PHP 脚本时可能需要访问数据库。
  • 您可能需要允许php-fpm侦听特定的网络端口,并让 apache 连接回它们以及 unix 套接字。
  • 您需要定义一个fc文件来指定文件上下文。
  • 确保 php-fpm 可以执行其他操作,例如 imap、pop3、smtp、http、https 等。
  • 必须能够写回允许写入的 httpd 内容,并使用正确的标签。
  • 必须能够读取user_contenthttpd 类型以及系统类型。

限制编程语言的实际效果可能非常棘手,因为策略需要足够强大才能与许多不同的 Web 应用程序一起使用。