网站的 httpd.conf 中指定的访问日志仅显示传入连接的信息。对于传出连接(例如由 php file_get_contents 函数发出的连接),我该如何获取日志?
答案1
修改第三方 PHP 应用程序可能不是一个可行的解决方案。应该使用 HTTP 代理,至少有两个原因:
- 每次任何 PHP 脚本尝试访问外部资源时,它都会使用代理,该代理有自己的访问日志
- 代理应该具有访问控制规则,仅允许某些地址并阻止所有其他地址。
答案2
没有任何解决方案可以仅仅通过开启就可以实现,但是必须实现该功能。
一种可能的方法是:
对发出传出请求的函数进行包装:
function log_file_get_contents( $url ) {
log_request( $url ); // A separate logging function that you create
file_get_contents( $url );
}
然后,将其log_file_get_contents()
用于您想要记录的所有请求。
需要为用于传出请求的其他函数编写类似的包装函数。
答案3
适应我的答案到如何轻松获取应用程序外部连接的所有HTTPS地址?:
从使用 lsof 持续监控文件,您可以lsof
结合重复 ( -r
) 选项使用。以下内容每两秒重复一次
$ lsof -i TCP:80,443 -r 2
每 2 秒将为你提供一次渐进的历史记录:
=======
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
firefox 9542 user 27u IPv4 1068219 0t0 TCP user-300V3Z-300V4Z-300V5Z:37360->192.0.78.23:https (ESTABLISHED)
firefox 9542 user 48u IPv4 1053405 0t0 TCP user-300V3Z-300V4Z-300V5Z:45948->ec2-54-213-37-69.us-west-2.compute.amazonaws.com:https (ESTABLISHED)
=======
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
firefox 9542 user 27u IPv4 1068219 0t0 TCP user-300V3Z-300V4Z-300V5Z:37360->192.0.78.23:https (ESTABLISHED)
firefox 9542 user 48u IPv4 1053405 0t0 TCP user-300V3Z-300V4Z-300V5Z:45948->ec2-54-213-37-69.us-west-2.compute.amazonaws.com:https (ESTABLISHED)
firefox 9542 user 52u IPv4 1138942 0t0 TCP user-300V3Z-300V4Z-300V5Z:57602->kul08s01-in-f10.1e100.net:https (SYN_SENT)
firefox 9542 user 102u IPv4 1139934 0t0 TCP user-300V3Z-300V4Z-300V5Z:49102->kul09s13-in-f14.1e100.net:https (ESTABLISHED)
firefox 9542 user 110u IPv4 1138950 0t0 TCP user-300V3Z-300V4Z-300V5Z:49104->kul09s13-in-f14.1e100.net:https (SYN_SENT)
=======
...
=======
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
firefox 9542 user 27u IPv4 1068219 0t0 TCP user-300V3Z-300V4Z-300V5Z:37360->192.0.78.23:https (ESTABLISHED)
firefox 9542 user 48u IPv4 1053405 0t0 TCP user-300V3Z-300V4Z-300V5Z:45948->ec2-54-213-37-69.us-west-2.compute.amazonaws.com:https (ESTABLISHED)
firefox 9542 user 51u IPv4 1140129 0t0 TCP user-300V3Z-300V4Z-300V5Z:52284->kul09s13-in-f10.1e100.net:https (ESTABLISHED)
firefox 9542 user 108u IPv4 1137384 0t0 TCP user-300V3Z-300V4Z-300V5Z:55886->103.229.10.236:https (ESTABLISHED)
firefox 9542 user 122u IPv4 1137399 0t0 TCP user-300V3Z-300V4Z-300V5Z:55870->kul08s12-in-f1.1e100.net:https (ESTABLISHED)
firefox 9542 user 126u IPv4 1137402 0t0 TCP user-300V3Z-300V4Z-300V5Z:47370->stackoverflow.com:https (SYN_SENT)
笔记:每两秒间隔=======
。
然后,您可以将输出传输到文件,如下所示
$ lsof -i TCP:80,443 -r 2 > /tmp/http_out.log
如果你不想登录全部传出的 HTTP(S) 请求,你可以grep
为脚本/进程命名:
$ lsof -i TCP:80,443 -r 2 | grep <name of your process>
我认为它grep
应该可以工作,但我无法测试它。
不可否认,输出并不像使用
watch -n1 lsof -i TCP:80,443
但这只能让你瞬间了解当前的传出请求:
dropbox 3280 saml 23u IPv4 56015285 0t0 TCP greeneggs.qmetricstech.local:56003->snt-re3-6c.sjc.dropbox.com:http (ESTABLISHED)
thunderbi 3306 saml 60u IPv4 56093767 0t0 TCP greeneggs.qmetricstech.local:34788->ord08s09-in-f20.1e100.net:https (ESTABLISHED)
mono 3322 saml 15u IPv4 56012349 0t0 TCP greeneggs.qmetricstech.local:54018->204-62-14-135.static.6sync.net:https (ESTABLISHED)
chrome 11068 saml 175u IPv4 56021419 0t0 TCP greeneggs.qmetricstech.local:42182->stackoverflow.com:http (ESTABLISHED)
再次,要将输出限制为仅 PHP 进程,您可以使用 grep
watch -n1 lsof -i TCP:80,443 | grep <name of your process>
答案4
没有现成的日志。您需要一个专门针对您的操作系统的解决方案。
如果你是程序员,那么你可以研究利用命名空间和auto_prepend_file
php.ini 指令。
<?php
namespace override;
function file_get_contents( string $filename, $use_include_path = false, $context = null, $offset = 0, $length = null )
{
// If $filename seems like a URL then do log stuff
if( preg_match( '/^https?:\\/\\//i', $filename ))
{
// Do log stuff
echo 'Doing log stuff for '.$filename;
}
return \file_get_contents( $filename, $use_include_path, $context, $offset, $length );
}
\override\file_get_contents( 'https://onlinephp.io/' );
输出:
Doing log stuff for https://serverfault.com/
此外,您还必须确保对发出 Web 请求的任何其他函数或类执行此操作,例如:
curl_init("http://www.example.com/");
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt_array($ch, array(CURLOPT_URL => 'http://www.example.com/'));
fopen('http://www.example.com/', 'r');
可能还有更多我不知道的事情。