我如何查看出站连接的 httpd 日志?

我如何查看出站连接的 httpd 日志?

网站的 httpd.conf 中指定的访问日志仅显示传入连接的信息。对于传出连接(例如由 php file_get_contents 函数发出的连接),我该如何获取日志?

答案1

修改第三方 PHP 应用程序可能不是一个可行的解决方案。应该使用 HTTP 代理,至少有两个原因:

  1. 每次任何 PHP 脚本尝试访问外部资源时,它都会使用代理,该代理有自己的访问日志
  2. 代理应该具有访问控制规则,仅允许某些地址并阻止所有其他地址。

答案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_filephp.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');

可能还有更多我不知道的事情。

相关内容