![如何配置 SE Linux 以便 PHP 可以通过套接字连接到 Postgres](https://linux22.com/image/792577/%E5%A6%82%E4%BD%95%E9%85%8D%E7%BD%AE%20SE%20Linux%20%E4%BB%A5%E4%BE%BF%20PHP%20%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E5%A5%97%E6%8E%A5%E5%AD%97%E8%BF%9E%E6%8E%A5%E5%88%B0%20Postgres.png)
我有一个连接到 Postgresql 数据库的 PHP 应用程序。当我通过网络连接时,它可以正常工作,但当我尝试使用套接字连接时,会出现 SELinux 违规。我相信上下文设置正确,并且启用了正确的标志。
httpd_can_network_connect --> on
httpd_can_network_connect_db --> on
失败的 sealert 消息如下所示:
SELinux is preventing /usr/sbin/php-fpm from connectto access on the unix_stream_socket /run/postgresql/.s.PGSQL.5432.
***** Plugin catchall (100. confidence) suggests **************************
If you believe that php-fpm should be allowed connectto access on the .s.PGSQL.5432 unix_stream_socket by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'php-fpm' --raw | audit2allow -M my-phpfpm
# semodule -X 300 -i my-phpfpm.pp
Additional Information:
Source Context system_u:system_r:httpd_t:s0
Target Context system_u:system_r:unconfined_service_t:s0
Target Objects /run/postgresql/.s.PGSQL.5432 [ unix_stream_socket
]
Source php-fpm
Source Path /usr/sbin/php-fpm
Port <Unknown>
Host localhost.localdomain
Source RPM Packages php-fpm-8.2.13-1.el9.remi.x86_64
Target RPM Packages
SELinux Policy RPM selinux-policy-targeted-38.1.23-1.el9.noarch
Local Policy RPM selinux-policy-targeted-38.1.23-1.el9.noarch
Selinux Enabled True
Policy Type targeted
Enforcing Mode Enforcing
Host Name localhost.localdomain
Platform Linux localhost.localdomain
5.14.0-362.8.1.el9_3.x86_64 #1 SMP PREEMPT_DYNAMIC
Wed Nov 8 17:36:32 UTC 2023 x86_64 x86_64
Alert Count 1080
First Seen 2023-12-29 14:34:45 PST
Last Seen 2024-01-31 12:15:18 PST
Local ID e3bcfa07-6867-47e3-bedf-4d8ca2d16443
Raw Audit Messages
type=AVC msg=audit(1706732118.737:4455): avc: denied { connectto } for pid=516281 comm="php-fpm" path="/run/postgresql/.s.PGSQL.5432" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:unconfined_service_t:s0 tclass=unix_stream_socket permissive=0
type=SYSCALL msg=audit(1706732118.737:4455): arch=x86_64 syscall=connect success=no exit=EACCES a0=8 a1=561638666d58 a2=6e a3=7fa9f9d951a0 items=0 ppid=516267 pid=516281 auid=4294967295 uid=984 gid=984 euid=984 suid=984 fsuid=984 egid=984 sgid=984 fsgid=984 tty=(none) ses=4294967295 comm=php-fpm exe=/usr/sbin/php-fpm subj=system_u:system_r:httpd_t:s0 key=(null)
Hash: php-fpm,httpd_t,unconfined_service_t,unix_stream_socket,connectto
有一件事情看起来很奇怪,那就是缺少用于 postgres 套接字的 RPM 包。
其中提供了生成本地策略模块的说明;但我不明白这些命令到底起什么作用,并且犹豫着是否要运行它们。
ausearch -c 'php-fpm' --raw | audit2allow -M my-phpfpm
semodule -X 300 -i my-phpfpm.pp
答案1
这些命令创建了一个 selinux 策略。ausearch
扫描审计日志以查找 PHP 想要执行的操作,并audit2allow
创建一个允许第一个命令找到的任何操作的策略。然后semodule
激活新创建的策略。
我建议在命令中添加-a 4455
key ausearch
,以便只允许在此特定事件期间被禁止的内容。这样会更安全,因为它不会意外允许任何不相关的内容:
ausearch -a 4455 --raw | audit2allow -M my-phpfpm-pg5432
semodule -X 300 -i my-php-pg5432.pp
还请注意,我对该策略的命名略有不同,因为有了这个过滤器,我们就可以确切地知道它允许什么。
看man ausearch
和man audit2allow
和man semodule
了解详情。
套接字文件可能没有包。套接字是动态文件系统对象,可即时创建和删除。可以认为它是一个“临时文件”,仅在创建它的服务运行时才有效。因此,套接字通常在非易失性内存文件系统中创建,并以 形式挂载/run
,在重启期间不会保留。
真正奇怪的是套接字的 selinux 类型是unconfined_service_t
。应该有一个预定义的 Postgres 套接字类型和一个允许httd_t
进程访问它的策略。我认为提交功能请求以实现此功能是明智的。
答案2
这里的问题似乎是您正在php-fpm
以unconfined_service_t
服务形式运行。您是如何启动该服务的?
如果您通过以下方式启动它,systemd
我建议对包进行重新标记,因为某些东西标记不正确。php-fpm
在我的系统上出现了httpd_t
这样一堆已经为该服务运行的规则应该适用并为您工作。
fixfiles -R $(rpm -qa | grep php | paste -sd,) restore
应正确地重新标记所有 PHP 包。然后按正常方式php-fpm
重新启动。systemctl