我看到一些奇怪的HTTP请求来到我的nginx服务器。
为了更好地理解正在发生的事情,我想为这样的查询转储整个HTTP请求数据。 (即转储所有的请求头和身体的地方,我可以阅读它们。)
我可以用nginx做这个吗? 另外,是否有一些HTTP服务器,允许我这样做的开箱即可,我可以通过nginx的方式代理这些请求?
更新:请注意,这个盒子有一堆正常的stream量,我想避免在低级别(比如使用tcpdump
)捕获所有的stream量,然后过滤掉。
我认为在重写规则中首先过滤好stream量将会容易得多(幸运的是,在这种情况下,我可以很轻松地写出一个stream量),然后只处理虚假stream量。
而且我不想将伪造的stream量引导到另一个盒子,只是为了能够使用tcpdump
捕获它。
更新2:为了给出更多的细节,伪请求在他们的GET查询中具有名称(说) foo
的参数(参数的值可以不同)。 好的请求保证不会有这个参数。
如果我可以通过tcpdump
或ngrep
以某种方式进行过滤 – 没问题,我会使用这些。
根据需要调整前/后行数(-B和-A args):
tcpdump -n -S -s 0 -A 'tcp dst port 80' | grep -B3 -A10 "GET /url"
这可以让你获得你想要的HTTP请求,而不会产生一个巨大的PCAP文件,你必须卸载其他地方。
请记住,BPFfilter从来不是确切的,如果有大量的数据包stream过任何一个盒子,BPF可以并且会丢弃数据包。
我不知道转储请求的确切含义,但可以使用tcpdump和/或wireshark来分析数据:
# tcpdump port 80 -s 0 -w capture.cap
您可以使用wireshark打开文件并查看服务器之间的对话。
如果您将请求代理到安装了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']
可能毫无意义。 您必须通过proxy_set_header X-Real-IP $remote_addr;
将真实的IP传递给Apache proxy_set_header X-Real-IP $remote_addr;
,你可以使用它(或只是依靠它通过getallheaders()
logging)。