php-fpm 套接字的 SElinux 標籤
我正在嘗試設置多個 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-fpm
and/etc/rc.d/init.d/php-fpm
tohttpd_exec_t
和httpd_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_content
httpd 的類型以及系統的類型。限制程式語言的實際效果可能非常棘手,因為該策略需要有多健壯才能與許多不同的 Web 應用程序一起使用。