Apache-2.2

php-fpm 套接字的 SElinux 標籤

  • June 17, 2019

我正在嘗試設置多個 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"

包含 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

基於此,我假設套接字的類型是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

通過更改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)
  • 有沒有任何邏輯解釋這沒有反映在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 策略,因此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)

規則是使用 audit2allow 生成的,可能允許超出需要的範圍,但這有效……當然,php-fpm二進製文件仍然需要被賦予新的類型:

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

我仍然不確定哪種解決方案實際上是最安全的。

我仍然願意接受有關一般方法的任何評論,或對本政策的潛在改進的建議……

試試這個

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實際上就是在做網路伺服器所做的事情。嘗試分別設置/usr/sbin/php-fpmand /etc/rc.d/init.d/php-fpmtohttpd_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 應用程序一起使用。

引用自:https://serverfault.com/questions/596790