Reputation: 7783
I have a PHP script that takes a long time to load. We have moved our sites to a new server which lives behind a cloud load balancer. The maximum time limit for the load balancer is 120 seconds, but the script takes well over 5 minutes. Splitting the script up is not an option.
I rewrote the script so it would run on the command line, and I can successfully call this:
php -f /path/to/long_php.php > /path/to/log_file.php
I can then call this from PHP by doing this:
exec('php -f /path/to/long_php.php > /path/to/log_file.php');
Of course, because this script takes a long time to load, I don't want the PHP page to wait. Back on the command line I successfully used the at
command like so:
echo "php -f /path/to/long_php.php > /path/to/log_file.php" | at now
So, I expected when running a similar thing in PHP it would work:
exec('echo "php -f /path/to/long_php.php > /path/to/log_file.php" | at now');
However this doesn't work. Unlike all the previou tries, the final command here give me SELinux errors:
----
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
Note: the above is from /var/log/audit/audit.log
piped through ausearch -i
After this I piped those in to audit2allow -w
to see why, and the first error was regarding allow_httpd_mod_auth_pam
not being enabled. I then enabled this and got some other errors. Running them through audit2allow -M tmpat
produced me tmpat.pp
, with an associated 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;
Unfortunately, when I run semodule -i tmpat.pp
it still doesn't work. Repeating the process of using audit2allow -w
above gives me more of the same Missing type enforcement (TE) allow rule.
errors. So with that in mind, I'm hoping someone can tell me what changes I need to make to the generated tmpat.te
to make this work?
Note: I'm on CentOS 6.5, with Apache 2.2, PHP 5.4
Update:
After looking in to policies, albeit it being something new to me, and I came up with the following:
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 };
Currently this compiles but won't install, giving me this:
[root@localhost tmp]# semodule -i tmpat
semodule: Failed on tmpat!
...but hopefully this might give some insight in to what I'm trying to do.
Upvotes: 2
Views: 4183
Reputation: 552
Environment CentOS 8, nginx, php-fpm
This solution worked for me
SELinux change to allow httpd to execute
setsebool -P httpd_ssi_exec 1
Policy on executable
Instead of compiling your own policy the executable can be made to match the httpd policy
chcon -t httpd_exec_t <path_to_executable_file> -R
From a security perspective probably not recommend if the executable can do any damage
Upvotes: 1
Reputation: 156
did you ever come up with a solution to this problem? if so, i would like to know.
i came across the same situation, so i will post my solution here.
after configuring selinux to allow apache to execute the at command, i too came across a problem where no errors were found, but the at command not executing.
so i changed apache's shell config to /bin/sh (from /usr/sbin/nologin) and logged into a shell as user apache.
then executed atq to find out that the at command was properly executed from the apache process.
$ atq
46 Fri Nov 21 17:23:00 2014 a apache
but it was spooled forever and never executed. so i tried to execute an at job from the shell, and that worked no problem. and also to find out that the job that was spooled from apache had started to run also
$ atq
46 Fri Nov 21 17:23:00 2014 = apache
so i added a cron task that just keeps spooling empty at jobs (as user apache)
$ crontab -l
*/1 * * * * echo echo|/usr/bin/at now
it will cause a maximum 1 minute delay, but now at commands run from apache(php) exec.
i don't know the reason or the logic to this result, but it is a working solution for me.
CentOS 7.0.1406, Apache/2.4.6, PHP 5.4.16, Kernel 3.10.0-123.9.3.el7.x86_64
EDIT: i found out a simpler solution. this allows immediate at command execution.
# chcon -t unconfined_exec_t /sbin/httpd
probably not a good idea if the server is shared by untrustful users
Upvotes: 2
Reputation: 21
You have to compile your policy to insert it with semanage
.
First you use audit2allow
to create a .te file (that would be the file you have in your updated post).
Then you compile your policy to insert it with audit2allow -M tmpat
, this will give you a .pp file. This file can be inserted, but look at the right syntax here:
semodule -i tmpat.pp
Upvotes: 0