2

我有一个 PHP 脚本需要很长时间才能加载。我们已将我们的站点移至位于云负载均衡器后面的新服务器。负载均衡器的最大时间限制为 120 秒,但脚本需要 5 分钟以上。拆分脚本不是一种选择。

我重写了脚本,让它在命令行上运行,我可以成功地调用它:

php -f /path/to/long_php.php > /path/to/log_file.php

然后我可以通过这样做从 PHP 调用它:

exec('php -f /path/to/long_php.php > /path/to/log_file.php');

当然,因为这个脚本需要很长时间才能加载,我不希望 PHP 页面等待。回到命令行,我成功地使用了at这样的命令:

echo "php -f /path/to/long_php.php > /path/to/log_file.php" | at now

所以,我希望在 PHP 中运行类似的东西时它会起作用:

exec('echo "php -f /path/to/long_php.php > /path/to/log_file.php" | at now');

但是,这不起作用。与之前的所有尝试不同,这里的最终命令给了我 SELinux 错误:

----
type=SYSCALL msg=audit(07/25/2014 21:12:50.027:793672) : arch=x86_64 syscall=open success=no exit=-13(Permission denied) a0=7fd6fc2186bb a1=80000 a2=1b6 a3=0 items=0 ppid=55040 pid=55041 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=1517 comm=unix_chkpwd exe=/sbin/unix_chkpwd subj=unconfined_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(07/25/2014 21:12:50.027:793672) : avc:  denied  { read } for  pid=55041 comm=unix_chkpwd name=shadow dev=md2 ino=11797556 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:shadow_t:s0 tclass=file
----
type=SYSCALL msg=audit(07/25/2014 21:12:50.028:793673) : arch=x86_64 syscall=socket success=no exit=-13(Permission denied) a0=10 a1=3 a2=9 a3=7fff46547e40 items=0 ppid=55038 pid=55040 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=1517 comm=at exe=/usr/bin/at subj=unconfined_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(07/25/2014 21:12:50.028:793673) : avc:  denied  { create } for  pid=55040 comm=at scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:system_r:httpd_t:s0 tclass=netlink_audit_socket
----
type=SYSCALL msg=audit(07/25/2014 21:12:50.028:793674) : arch=x86_64 syscall=socket success=no exit=-13(Permission denied) a0=10 a1=3 a2=9 a3=1 items=0 ppid=55038 pid=55040 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=1517 comm=at exe=/usr/bin/at subj=unconfined_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(07/25/2014 21:12:50.028:793674) : avc:  denied  { create } for  pid=55040 comm=at scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:system_r:httpd_t:s0 tclass=netlink_audit_socket
----
type=SYSCALL msg=audit(07/25/2014 21:12:50.028:793675) : arch=x86_64 syscall=socket success=no exit=-13(Permission denied) a0=10 a1=3 a2=9 a3=7fff46547eb0 items=0 ppid=55038 pid=55040 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=1517 comm=at exe=/usr/bin/at subj=unconfined_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(07/25/2014 21:12:50.028:793675) : avc:  denied  { create } for  pid=55040 comm=at scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:system_r:httpd_t:s0 tclass=netlink_audit_socket

注意:以上内容来自/var/log/audit/audit.log管道ausearch -i

在此之后,我通过管道输入audit2allow -w以查看原因,第一个错误是关于allow_httpd_mod_auth_pam未启用。然后我启用了这个并得到了一些其他错误。运行它们使audit2allow -M tmpat我产生tmpat.pp了相关的tmpat.te

module tmpat 1.0;

require {
        type initrc_var_run_t;
        type httpd_t;
        class capability audit_control;
        class file read;
}

#============= httpd_t ==============
allow httpd_t initrc_var_run_t:file read;
allow httpd_t self:capability audit_control;

不幸的是,当我运行semodule -i tmpat.pp它仍然无法正常工作。重复audit2allow -w上面的使用过程会给我更多相同的Missing type enforcement (TE) allow rule.错误。因此,考虑到这一点,我希望有人能告诉我需要对生成的文件进行哪些更改tmpat.te才能使其正常工作?

注意:我在 CentOS 6.5 上,使用 Apache 2.2,PHP 5.4

更新:

在研究了政策之后,尽管这对我来说是新事物,但我想出了以下几点:

module tmpat 1.1;
  require {
  type tmp_t;
  type httpd_t;
  class file { create getattr open read rename unlink write };
  class dir { add_name getattr open read remove_name search write };
}

#============= httpd_t ==============
allow httpd_t tmp_t:file { create getattr open read rename unlink write };
allow httpd_t tmp_t:dir { add_name getattr open read remove_name search write };

目前这个编译但不会安装,给我这个:

[root@localhost tmp]# semodule -i tmpat
semodule:  Failed on tmpat!

...但希望这可能会对我正在尝试做的事情有所了解。

4

3 回答 3

2

你有没有想过解决这个问题?如果是这样,我想知道。

我遇到了同样的情况,所以我会在这里发布我的解决方案。

在配置 selinux 以允许 apache 执行 at 命令后,我也遇到了一个问题,没有发现错误,但 at 命令没有执行。

所以我将 apache 的 shell 配置更改为 /bin/sh(来自 /usr/sbin/nologin)并以 apache 用户身份登录到 shell。

然后执行 atq 以发现 at 命令已从 apache 进程正确执行。

$ atq
46  Fri Nov 21 17:23:00 2014 a apache

但它被永远缠绕,从未被执行。所以我尝试从 shell 执行 at 作业,这没问题。并且还发现从 apache 假脱机的作业也开始运行

$ atq
46  Fri Nov 21 17:23:00 2014 = apache

所以我添加了一个 cron 任务,它只是在作业中保持假脱机(作为用户 apache)

$ crontab -l
*/1 * * * * echo echo|/usr/bin/at now

它会导致最多 1 分钟的延迟,但现在在从 apache(php) exec 运行的命令中。

我不知道这个结果的原因或逻辑,但它对我来说是一个可行的解决方案。

CentOS 7.0.1406、Apache/2.4.6、PHP 5.4.16、内核 3.10.0-123.9.3.el7.x86_64

编辑:我找到了一个更简单的解决方案。这允许立即执行命令。

# chcon -t unconfined_exec_t /sbin/httpd

在此处查看详细文档

如果服务器由不信任的用户共享,可能不是一个好主意

于 2014-11-21T11:25:58.037 回答
0

您必须编译您的策略以将其插入semanage.

首先,您使用audit2allow创建一个.te文件(这将是您在更新后的帖子中拥有的文件)。然后你编译你的策略来插入它audit2allow -M tmpat,这会给你一个.pp文件。可以插入此文件,但请在此处查看正确的语法:

semodule -i tmpat.pp
于 2014-08-20T12:02:35.320 回答
0

环境CentOS 8、nginx、php-fpm

这个解决方案对我有用

SELinux 更改以允许 httpd 执行

setsebool -P httpd_ssi_exec 1

可执行文件政策

可以使可执行文件与 httpd 策略相匹配,而不是编译您自己的策略

chcon -t httpd_exec_t <path_to_executable_file> -R

从安全角度来看,如果可执行文件会造成任何损害,可能不推荐

于 2020-08-26T00:38:57.303 回答