web-dev-qa-db-ja.com

nginx:デバッグのためにHTTPリクエストをダンプします

  • Ubuntu 10.04.2
  • nginx 0.7.65

Nginxサーバーに送信される奇妙なHTTPリクエストがいくつかあります。

何が起こっているのかをよりよく理解するために、そのようなクエリのHTTPリクエストデータ全体をダンプしたいと思います。 (つまり、すべてのリクエストヘッダーと本文を読み取り可能な場所にダンプします)。

Nginxでこれを行うことはできますか?別の方法として、これをすぐに実行できるHTTPサーバーがあり、nginxを使用してこれらの要求をプロキシできますか?

pdate:このボックスには通常のトラフィックがたくさんあることに注意してください。低レベル(たとえばtcpdumpを使用)ですべてをキャプチャして後でフィルターで除外することは避けたいと思います。

最初に書き換えルールで適切なトラフィックをフィルタリングする方がはるかに簡単だと思います(幸い、この場合は非常に簡単に作成できます)。次に、偽のトラフィックのみを処理します。

そして、tcpdumpでそれをキャプチャできるようにするためだけに、偽のトラフィックを別のボックスにチャネリングしたくありません。

pdate 2:もう少し詳しく説明すると、偽のリクエストのGETクエリには(たとえば)fooという名前のパラメーターがあります(パラメーターの値は異なる場合があります)。良いリクエストは、このパラメータを持たないことが保証されています。

tcpdumpまたはngrepでこれでフィルタリングできる場合は、問題ありません。これらを使用します。

17

必要に応じて、前後の行(-Bおよび-A引数)の数を調整します。

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

これにより、他の場所でオフロードする必要のある巨大なPCAPファイルを生成せずに、必要なHTTPリクエストをボックスで取得できます。

BPFフィルターは正確ではないことに注意してください。いずれかのボックスを通過するパケットの数が多い場合、BPFはパケットをドロップできます。

30
oo.

リクエストのダンプの意味がわかりませんが、tcpdumpや wireshark を使用してデータを分析できます。

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

そして、wiresharkを使用してファイルを開き、サーバー間の会話を確認できます。

5
coredump

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に渡す必要があり、代わりにそれを使用できます(またはgetallheaders()を介してログに記録されることに依存します)。

0
hobodave