live log of php engine - php

Is there any way to watch php activities online? I am looking for something like apache logs that I can I run tail -f /var/log/httpd/access.log in the terminal and then open the URL in a browser and see what apache prints.
So, I am seeking for similar thing for php web pages. The php is 7.2
UPDATE1:
Trying to watch system log with tail -f /var/log/messages, I get many messages similar to this in the terminal when the page is reloaded from browser.
python: SELinux is preventing /usr/sbin/httpd from write access on the directory /var/www/html/ow_userfiles/plugins/admin.#012#012***** Plugin httpd_write_content (92.2 confidence) suggests ***************#012#012If you want to allow httpd to have write access on the admin directory#012Then you need to change the label on '/var/www/html/ow_userfiles/plugins/admin'#012Do#012# semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/ow_userfiles/plugins/admin'#012# restorecon -v '/var/www/html/ow_userfiles/plugins/admin'#012#012***** Plugin catchall_boolean (7.83 confidence) suggests ******************#012#012If you want to allow httpd to unified#012Then you must tell SELinux about this by enabling the 'httpd_unified' boolean.#012#012Do#012setsebool -P httpd_unified 1#012#012***** Plugin catchall (1.41 confidence) suggests **************************#012#012If you believe that httpd should be allowed write access on the admin directory by default.#012Then you should report this as a bug.#012You can generate a local policy module to allow this access.#012Do#012allow this access for now by executing:#012# ausearch -c 'httpd' --raw | audit2allow -M my-httpd#012# semodule -i my-httpd.pp#012
It is an ugly message! I think I have to run semanage fcontext -a -t with some paths. Not sure which paths exactly!
UPDATE2:
A more clear log is available with the following command
[root#localhost html]# sealert -l e254cabb-7005-4a3c-8f91-8620c924c5e0
SELinux is preventing /usr/sbin/httpd from write access on the file /var/www/html/ow_includes/config.php.
***** Plugin httpd_write_content (92.2 confidence) suggests ***************
If you want to allow httpd to have write access on the config.php file
Then you need to change the label on '/var/www/html/ow_includes/config.php'
Do
# semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/ow_includes/config.php'
# restorecon -v '/var/www/html/ow_includes/config.php'
***** Plugin catchall_boolean (7.83 confidence) suggests ******************
If you want to allow httpd to unified
Then you must tell SELinux about this by enabling the 'httpd_unified' boolean.
Do
setsebool -P httpd_unified 1
***** Plugin catchall (1.41 confidence) suggests **************************
If you believe that httpd should be allowed write access on the config.php file 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 'httpd' --raw | audit2allow -M my-httpd
# semodule -i my-httpd.pp
Additional Information:
Source Context system_u:system_r:httpd_t:s0
Target Context unconfined_u:object_r:httpd_sys_content_t:s0
Target Objects /var/www/html/ow_includes/config.php [ file ]
Source httpd
Source Path /usr/sbin/httpd
Port <Unknown>
Host localhost.localdomain
Source RPM Packages
Target RPM Packages
Policy RPM selinux-policy-3.13.1-192.el7_5.6.noarch
Selinux Enabled True
Policy Type targeted
Enforcing Mode Enforcing
Host Name localhost.localdomain
Platform Linux localhost.localdomain
3.10.0-862.11.6.el7.x86_64 #1 SMP Tue Aug 14
21:49:04 UTC 2018 x86_64 x86_64
Alert Count 108
First Seen 2018-09-02 16:51:25 +0430
Last Seen 2018-09-02 23:00:19 +0430
Local ID e254cabb-7005-4a3c-8f91-8620c924c5e0
Raw Audit Messages
type=AVC msg=audit(1535913019.143:9913): avc: denied { write } for pid=5121 comm="httpd" name="config.php" dev="dm-0" ino=18219610 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:httpd_sys_content_t:s0 tclass=file
Hash: httpd,httpd_t,httpd_sys_content_t,file,write

This is an SELinux issue, as is apparent by the logs messages...
SELinux is preventing /usr/sbin/httpd from write access on the directory /var/www/html/ow_userfiles/plugins/admin.#012#012*****
...
If you want to allow httpd to have write access on the admin directory
Then you need to change the label on '/var/www/html/ow_userfiles/plugins/admin'
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/ow_userfiles/plugins/admin'
restorecon -v '/var/www/html/ow_userfiles/plugins/admin'
Start with the first error, do exactly as it states.. and see if that resolves e others.
If other errors still exist after running these commands, follow the res of the instructions in the very clear error message you were presented.

Here is a php « tail » from my notes to play around.
It is similar to tail -n 5 access.log
This will answer the last 5 lines of access.log.
To make it acting like tail -f, just use a loop.
$check = "access.log";
$end = "5";
$fp= fopen($check, "r");
$count=0;
while($line = fgetss($fp))
$count++;
// echo "Total lines ".$count.PHP_EOL;
fclose($fp);
$start = $count - $end;
$file = new SplFileObject($check);
$file->seek($start);
for($i = 0; !$file->eof() && $i < $end; $i++) {
echo $file->current();
$file->next();
}
It is also very fast, the whole file isn't taken in memory, just like tail.
SplFileObject

Related

Selinux blocks the crontab command from php

There are Fedora 25 and apache on our server.
I want to do so that the php script on our web site can change crontab settings.
I created the following test php script:
<?php
system("echo '*/2 * * * * date > /var/www/logs/testlog.txt' | crontab - 2>&1");
But it did not work. I got the message:
/var/spool/cron/#tmp.mh203-95.XXXXG0KrFF: Permission denied
I looked at output of sealert -a /var/log/audit/audit.log
and found:
SELinux is preventing crontab from write access on the directory /var/spool/cron.
Okay. It sounds like apache is not allowed the write access to /var/spool/cron because that directory has not the httpd_sys_rw_content_t label.
So I executed the command:
chcon -v -R -t httpd_sys_rw_content_t /var/spool/cron
My php script begun to work. The crontab -l command gave normal output.
But the new problem appeared. :( The cron tasks was not executed.
In the /var/log/cron I saw the error:
Mar 23 18:05:01 mh203-95 crond[1653]: (apache) Unauthorized SELinux context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 file_context=system_u:object_r:httpd_sys_rw_content_t:s0 (/var/spool/cron/apache)
Mar 23 18:05:01 mh203-95 crond[1653]: (apache) FAILED (loading cron table)
After many time of research... I found that the /var/spool/cron must have the user_cron_spool_t label. So I executed: chcon -v -R -t user_cron_spool_t /var/spool/cron.
The cron tasks begun to works. But my php script did not work again. The same problem as at the beginning.
sealert suggested the commands like:
ausearch -c 'crontab' --raw | audit2allow -M my-crontab
semodule -X 300 -i my-crontab.pp
But it did not help.
What am I missing?
How to solve the problem?
Can I somehow combine two labels user_cron_spool_t and httpd_sys_rw_content_t for /var/spool/cron directory?
I had solved the problem.
The reason was in this: sealert generates the same politic name my-crontab in all suggested commands. The new politic overwrote the old.
It is just needed to change this name slightly.
So i executed:
ausearch -c 'crontab' --raw | audit2allow -M my-crontab
semodule -X 300 -i my-crontab.pp
ausearch -c 'crontab' --raw | audit2allow -M my-crontab2
semodule -X 300 -i my-crontab2.pp
ausearch -c 'crontab' --raw | audit2allow -M my-crontab3
semodule -X 300 -i my-crontab3.pp
...
Before every ausearch ... I executed:
echo -n "" > /var/log/audit/audit.log
My php script.
sealert -a /var/log/audit/audit.log

SELinux blocking php's exec('kill pid') without any error in log

I'm trying to get a process PID and kill it with this code:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
$_script_path = "/path/to/scriptname.php";
$cmd_find_process = "ps aux | grep '[p]hp -f ".$_script_path."'";
echo $cmd_find_process.PHP_EOL;
echo exec($cmd_find_process);
echo PHP_EOL.PHP_EOL;
$cmd = "kill $(".$cmd_find_process." | awk '{print $2}')";
echo $cmd;
echo exec($cmd);
?>
Initially I couldn't list processes, which I fixed by compiling a custom SELinux module, selinux-httpd-allow-ps-aux.te:
policy_module(myhttpd,1.0.0)
gen_require(`
type httpd_t;
')
domain_read_all_domains_state(httpd_t);
I've already disabled dontaudit statements with:
semodule -DB
But I can't kill any process which I've previously started by the same user: apache. No errors logged in the /var/log/audit/audit.log file.
For a complete understanding, the PHP script which I'm trying to kill is executed with this command:
su -s /bin/sh apache -c php -f /path/to/scriptname.php
I know it's SELinux because turning off SELinux with
echo 0 > /selinux/enforce
will make it work.
Apparently I had to restart auditd for the errors to show up.
service auditd restart
This is the error:
type=AVC msg=audit(1459790992.546:15889813): avc: denied { signal } for pid=25478 comm="sh" scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:system_r:initrc_t:s0 tclass=process
Was caused by:
Missing type enforcement (TE) allow rule.
You can use audit2allow to generate a loadable module to allow this access.
I was able to solve the issue through the audit2allow tool. This is the generated custom module that fixed the issue.
module selinux-httpd-allow-signal 1.0;
require {
type httpd_t;
type initrc_t;
class process signal;
}
#============= httpd_t ==============
allow httpd_t initrc_t:process signal;

Starting FOREVER or PM2 as WWW-DATA from a PHP script

I have a nodejs script named script.js.
var util = require('util');
var net = require("net");
process.on("uncaughtException", function(e) {
console.log(e);
});
var proxyPort = "40000";
var serviceHost = "1.2.3.4";
var servicePort = "50000";
net.createServer(function (proxySocket) {
var connected = false;
var buffers = new Array();
var serviceSocket = new net.Socket();
serviceSocket.connect(parseInt(servicePort), serviceHost);
serviceSocket.pipe(proxySocket).pipe(serviceSocket);
proxySocket.on("error", function (e) {
serviceSocket.end();
});
serviceSocket.on("error", function (e) {
console.log("Could not connect to service at host "
+ serviceHost + ', port ' + servicePort);
proxySocket.end();
});
proxySocket.on("close", function(had_error) {
serviceSocket.end();
});
serviceSocket.on("close", function(had_error) {
proxySocket.end();
});
}).listen(proxyPort);
I am runing it normally like nodejs script.js, but now i want to include forever or pm2 functionalities as well. When i am root everything works smootly:
chmod -R 777 /home/nodejs/forever/;
-- give rights
watch -n 0.1 'ps ax | grep forever | grep -v grep'
-- watch forwarders (where i see if a forever is opened)
/usr/local/bin/forever -d -v --pidFile "/home/nodejs/forever/file.pid" --uid 'file' -p '/home/nodejs/forever/' -l '/home/nodejs/forever/file.log' -o '/home/nodejs/forever/file.log' -e '/home/nodejs/forever/file.log' -a start /etc/dynamic_ip/nodejs/proxy.js 41789 1.2.3.4:44481 414 file
-- open with forever
forever list
-- it is there, i can see it
forever stopall
-- kill them all
The problem is when i want to run the script from a PHP script with the system or exec functions :
sudo -u www-data /usr/local/bin/forever -d -v --pidFile "/home/nodejs/forever/file.pid" --uid 'file' -p '/home/nodejs/forever/' -l '/home/nodejs/forever/file.log' -o '/home/nodejs/forever/file.log' -e '/home/nodejs/forever/file.log' -a start /etc/dynamic_ip/nodejs/proxy.js 41789 1.2.3.4:44481 414 file
-- open as www-data (or i can do this just by accessing `http://1.2.3.4/test.php`, it is the same thing)
forever list
-- see if it is there, and it is not (i see it in watch)
forever stopall
-- says no forever is opened
kill PID_ID
-- the only way is to kill it by pid ... and on another server all of this works very well, can create and kill forevers from a php script when accessing it from web ... not know why
-- everything is in /etc/sudoers including /usr/local/bin/forever
Why is that? How can i solve this?
I also made some trick, created a user 'forever2', i created a script.sh with this content :
sudo su forever2 user123; /usr/local/bin/forever -d -v --pidFile "/home/nodejs/forever/file.pid" --uid 'file' -p '/home/nodejs/forever/' -l '/home/nodejs/forever/file.log' -o '/home/nodejs/forever/file.log' -e '/home/nodejs/forever/file.log' -a start /etc/dynamic_ip/nodejs/proxy.js 41789 1.2.3.4:44481 414 file;
where user123 is not existent, is just a trick to exit the shell after execution. The script works, runs forever, i can close all forevers with the command forever stopall from root. When i try the same thing running the http://1.2.3.4/test.php or as www-data user i cannot close it from root or www-data, so not even this works.
I tried from Ubuntu 14.04.3 LTS, Ubuntu 14.04 LTS , Debian GNU/Linux 8 ... still the same thing.
Any ideeas?
Thanks.
If you are starting the process from within Apache or the web-server you are already as the www-data user, so doing a sudo su to the user context you already have is likely not necessary.
When you start this forever task you may also be required to shut the terminals/inputs and directly send to background. Something like this:
// Assemble command
$cmd = '/usr/bin/forever';
$cmd.= ' -d -v --pidfile /tmp/my.pid'; // add other options
$cmd.= ' start';
$cmd.= ' /etc/dynamic_ip/nodejs/proxy.js';
// "magic" to get details
$cmd.= ' 2>&1 1>/tmp/output.log'; // Route STDERR to STDOUT; STDOUT to file
$cmd.= ' &'; // Send whole task to background.
system($cmd);
Now, there won't be any output here but you should have something in /tmp/output.log which could show why forever failed, or the script crashed.
If you've been running the script sometimes as root, then trying the same command as www-data you may also be running into a permissions on one or more files/directories created from the execution as root which now conflict when running as www-data.
This is part of PHP security you say you're running it from a php script and your not your running it from Apache via a php script.
PHP web scripts should not have root access as such they run under the same permissions as Apache user www-data.
There are ways to prevent php running as root but run a task as root but it's a little hacky and I'm not going to share the code but I will explain so you can look into it. here is where to start
http://php.net/manual/en/function.proc-open.php
With a Proccess like this you can then execute a proc. Like your script.js via nodeJS using SUDO and then read stdOut and stdErr wait for password request then provide it by writing to stdIn for that process.
Don't forget in doing this the user www-data has to have a password and be in the sudoers list
Per the OPs Comment
Due to the way SUDO works the PATH does not appear to contain the path to the node executables npm, node so your best of building a .sh (bash script) and using sudo to run that.
You still need to monitor this process as it will still ask for a password
#!/bin/bash
sudo -u ec2-user -i
# change this to the path you want to run from
cd ~
/usr/local/bin/pm2 -v

php fopen failed to open stream: Permission denied

i'm having problem writing to a text file using php. this might sound simple but i've set the file owner and group to apache/root, permission to 777 and i'm still unable to write to file. i'm running centos with php 5.3.8.
====================
New info
====================
semanage fcontext -l | grep httpd | grep rw
/var/lib/drupal(/.*)? all files system_u:object_r:httpd_sys_script_rw_t:s0
/var/spool/gosa(/.*)? all files system_u:object_r:httpd_sys_script_rw_t:s0
/var/lib/bugzilla(/.*)? all files system_u:object_r:httpd_bugzilla_script_rw_t:s0
/var/spool/viewvc(/.*)? all files system_u:object_r:httpd_sys_script_rw_t:s0
To allow the directory to be r/w, i used the chcon command to add the httpd_sys_script_rw_t type to the directory and anything under it:
chcon -R -t httpd_sys_script_rw_t <directory>
The -R flag makes the command recursive.
The -t flag sets the extended attribute on the file to the specified file context. In this case the httpd file context httpd_sys_script_rw_t which is used when:
you want httpd_sys_script_exec_t scripts to read/write the data, and disallow other non sys scripts from access.
The appropriate file contexts to use for allowing HTTPd to write to disk (as well as booleans for other operations) are described in the httpd_selinux(8) man page.

Browser unable to open php page?

First of all I am showing the PHP code ....
<?php
echo ("hello");
echo exec("sendip -v -p ipv6 -6s 2001::100 -p tcp -ts 21 -td 21 2001::200 2>
&1");
echo ("hi");
?>
When I entered the command through linux command line it is working fine.The command is sending a tcp ipv6 packet on 2001::200 machine from 2001::100.
[root#udit-pc]# sendip -v -p ipv6 -6s 2001::100 -p tcp -ts 21
-td 21 2001::200 > /dev/null &
/* (-v for verbose) */
Output of above command ...
Added 34 options
Initializing module ipv6
Initializing module tcp
Finalizing module tcp
Finalizing module ipv6
Final packet data:
60 00 00 00 `...
/*
here other packet
contents gets printed
*/
7D 62 00 00 }b..
61 62 63 64 abcd
Sent 64 bytes to 2001::200
Freeing module ipv6
Freeing module tcp
When I execute the php script through command line...
[root#udit-pc]# php test.php
Freeing module tcp
hellohi gets printed and packet arrived at 2001::200.
But problem arise when I try to run php script through browser...
http:://localhost/test.php
hellohi gets printed but packet does not arrive at other machine.
sh: sendip: command not found
Also in both case packet contents are not printed at terminal although using verbose option but when directly using command verbose option works fine.
I tried with many things although I do not think they would help like......
I added /usr/local/lib and usr/local/bin to PATH variable but no benefit.
chmod +s /usr/local/bin/sendip .Sticky bit set but again no benefit.
paste the /usr/local/bin/sendip itself in /var/www/html folder although I have changed the PATH variable but as i said i m just using hit n trial getting no clue.....
There are some output snapshots which may further help ....
[root#cc html]# echo $PATH
/usr/lib/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerberos/bin:
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:
/usr/X11R6/bin:/root/bin:/usr/local/lib
[root#cc html]# locate sendip
.....
/usr/local/bin/sendip
/usr/local/lib/sendip
.....
[root#cc bin]# chmod +s sendip
[root#cc bin]# ls -l sendip
-rwsrwsrwx 1 apache apache 41071 Sep 26 19:41 sendip
[root#cc bin]# cd /usr/local/lib/
[root#cc lib]# ls -ld sendip
drwxrwxrwx 2 root root 4096 Sep 28 22:48 sendip
[root#cc lib]# chmod +s sendip
[root#cc lib]# ls -ld sendip
drwsrwsrwx 2 root root 4096 Sep 28 22:48 sendip
When file contents are changed .......
<?php
echo exec("/usr/bin/sendip ........ 2 > &1");
?>
Then oputput is :
[root#cc html]# php test.php
Freeing module tcp[root#cc html]#
On browser....
No error gets printed but packet still not arrived.
I am stuck in between.Please suggest me what else should I rather try ??????/
is sendip() in the path of the shell being invoked by PHP? You're not checking for error conditions, so possibly you're not actually executing sendip, and just getting a "no such program or file" type errors.
Instead of redirecting the exec()'d command's output to null, redirect it all to the browser so you can see what happens:
echo exec("sendiip yada yada yada 2>&1");
Try using the full path:
exec("/usr/lib/sendip -v -p ipv6 -6s 2001::100 -p tcp -ts 21 -td 21 2001::200 > /dev/null &");
The server is most likely not running with the same permissions as the user, you are testing with.
The server is most likely discarding any PATH variable. Make sure that you specify the complete path to sendip in the exec call.
The Problem is solved although I can not say its fully solved but as per my need its working.
What i did is I re-installed the sendip ,then I set its sticky bit and then after that I set the Path variable to as above mentioned in question.
Actually the tool is by default installing the libraries in /usr/local/lib/sendip folder and sendip in /usr/local/bin folder.
Although after setting PATH variable still I need to use full path in the PHP Script
/usr/local/bin/sendip -v .....
(one of my friend suggested me this..)
What I think is PHP Path is something different from Shell PATH.I need to paste sendip to /usr/bin and then I need to run updatedb before setting its sticky bit if I don't want to mention full path in PHP Script .Now this command will work fine in PHP Script.
sendip -v .........
Although May be I am wrong but this all works fine for me.

Categories