nginx:转储 HTTP 请求以进行调试

nginx:转储 HTTP 请求以进行调试
  • Ubuntu 10.04.2
  • nginx 0.7.65

我发现一些奇怪的 HTTP 请求发送到我的 nginx 服务器。

为了更好地理解发生了什么,我想转储此类查询的整个 HTTP 请求数据。 (即将所有请求标头和正文转储到我可以读取的地方。)

我可以用 nginx 来做这个吗?或者,是否有一些 HTTP 服务器允许我开箱即用地执行此操作,我可以通过 nginx 将这些请求代理到该服务器?

更新:请注意,这个盒子有大量的正常流量,我想避免在低级别(例如,使用tcpdump)捕获所有这些流量并在稍后将其过滤掉。

我认为首先在重写规则中过滤好的流量会容易得多(幸运的是,在这种情况下我可以很容易地编写一个),然后只处理虚假流量。

并且我不想将虚假流量引导到另一个盒子只是为了能够在那里捕获它tcpdump

更新 2:更详细地说,虚假请求foo在 GET 查询中有一个参数名称(参数值可能不同)。 好的请求保证永远不会有这个参数。

如果我可以通过这种方式进行过滤tcpdumpngrep— 没问题,我会使用这些。

答案1

根据需要调整前/后行的​​数量(-B 和 -A 参数):

tcpdump -n -S -s 0 -A 'tcp dst port 80' | grep -B3 -A10 "GET /url"

这使您可以在盒子上获取所需的 HTTP 请求,而无需生成必须在其他地方卸载的巨大的 PCAP 文件。

请记住,BPF 过滤器永远不是精确的,如果有大量数据包流过任何盒子,BPF 可能会丢弃数据包。

答案2

我不太明白你转储请求的意思,但你可以使用 tcpdump 和/或wireshark分析数据:

# tcpdump port 80 -s 0 -w capture.cap

并且您可以使用wireshark打开文件并查看服务器之间的对话。

答案3

如果您使用安装了 mod_php 的 Apache 代理请求,则可以使用以下 PHP 脚本来转储请求:

<?php
$pid = getmypid();
$now = date('M d H:i:s');
$fp = fopen('/tmp/intrusion.log', 'a');

if (!function_exists('getallheaders')) 
{ 
    function getallheaders() 
    { 
           $headers = ''; 
       foreach ($_SERVER as $name => $value) 
       { 
           if (substr($name, 0, 5) == 'HTTP_') 
           { 
               $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; 
           } 
       } 
       return $headers; 
    } 
} 

function ulog ($str) {
    global $pid, $now, $fp;
    fwrite($fp, "$now $pid {$_SERVER['REMOTE_ADDR']} $str\n");
}

foreach (getallheaders() as $h => $v) {
    ulog("H $h: $v");
}
foreach ($_GET as $h => $v) {
    ulog("G $h: $v");
}
foreach ($_POST as $h => $v) {
    ulog("P $h: $v");
}
fclose($fp);

请注意,由于您使用的是 nginx,因此这$_SERVER['REMOTE_ADDR']可能毫无意义。您必须通过 将真实 IP 传递给 Apache proxy_set_header X-Real-IP $remote_addr;,然后您可以使用它(或者仅依靠通过 记录它getallheaders())。

相关内容