nginx : 디버깅을위한 HTTP 요청 덤프


17
  • 우분투 10.04.2
  • nginx 0.7.65

내 nginx 서버에 이상한 HTTP 요청이 오는 것을 볼 수 있습니다.

무슨 일이 일어나고 있는지 더 잘 이해하기 위해 그러한 쿼리에 대한 전체 HTTP 요청 데이터를 덤프하고 싶습니다. (모든 요청 헤더와 본문을 읽을 수있는 곳에 덤프하십시오.)

nginx로 이것을 할 수 있습니까? 또는 nginx를 통해 이러한 요청을 프록시 할 수있는 HTTP 서버가 있습니까?

업데이트 : 이 상자에는 정상적인 트래픽이 많으므로 모든 트래픽을 낮은 수준 (예 :)으로 캡처 tcpdump하고 나중에 필터링 하지 않도록하고 싶습니다 .

나는 다시 쓰기 규칙에서 좋은 트래픽을 먼저 필터링하는 것이 훨씬 쉽다고 생각합니다 (다행히도이 경우에는 아주 쉽게 작성할 수 있습니다). 그리고 가짜 트래픽 만 처리합니다.

그리고 나는 가짜 트래픽을 다른 상자로 보내지 않고 그것을 캡처 할 수 있기를 원합니다 tcpdump.

업데이트 2 : 좀 더 자세한 정보를 제공하기 위해 가짜 요청은 fooGET 쿼리에 매개 변수 (예 :)라는 매개 변수가 있습니다 (매개 변수 값이 다를 수 있음). 좋은 요청은이 매개 변수를 갖지 않도록 보장됩니다.

이것으로 tcpdump또는 ngrep어떤 식 으로든 필터링 할 수 있다면 문제 없습니다. 이것들을 사용할 것입니다.


"이상한"것으로 간주되는 요청을 특성화 / 분류 할 수 있습니까? '정상'과 '거짓'이 무엇인지 우리와 공유하지 않으면 어떻게 도와주는 규칙을 제시 할 수 있습니까?
hobodave

나는 규칙을 요구하지 않는다 – 나는 그것을 쉽게 쓸 수있다. HTTP 요청 데이터를 덤프 할 수단을 요청합니다.
Alexander Gladysh

@ hobodave : 그러나 어쨌든, 당신이 요구 한 이후, 나는이 정보를 질문에 추가했습니다.
Alexander Gladysh 2016 년

답변:


30

필요에 따라 사전 / 사후 라인 (-B 및 -A args) 수를 조정하십시오.

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

이를 통해 다른 곳으로 오프로드해야하는 거대한 PCAP 파일을 생성하지 않고도 원하는 HTTP 요청을 즉시 얻을 수 있습니다.

상자를 통해 많은 수의 패킷이 흐르면 ​​BPF 필터는 정확하지 않으므로 BPF는 패킷을 삭제할 수 있습니다.


5

요청을 덤프 할 때 정확히 무엇을 의미하는지 모르지만 tcpdump 및 / 또는 wireshark 를 사용하여 데이터를 분석 할 수 있습니다.

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

wireshark를 사용하여 파일을 열고 서버 간의 대화를 볼 수 있습니다.


고마워,하지만이 서버에는 꽤 많은 트래픽이 있으며 (99 %는 좋음), 내가 필요한 가짜 1 %에 대한 많은 양의 데이터를 필터링하는 것이 어려울 것이라고 생각합니다.
Alexander Gladysh

... 낮은 수준에서 모든 것을 포착하면. :-)
Alexander Gladysh 2016 년

그것을 반영하기 위해 질문을 업데이트했습니다.
Alexander Gladysh

알렉산더-100 건의 요청 중 1 개가 원하는 이상한 헤더를 갖습니다. 잠시 동안 캡처를 실행 한 다음 결과 로그를 검색하여 원하는 헤더를 찾으십시오. 이는 견딜 수없는 작업이 아닙니다.
EEAA

문제는 작업이 아니라 처리해야 할 데이터의 양입니다. (하지만 견딜 수는 있겠지만 어쨌든 더 우호적 인 해결책을보고 싶습니다.)
Alexander Gladysh

0

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;대신이를 사용하거나 로그를 통해 해당 IP에 의존 할 수 있습니다 getallheaders().


감사합니다. 그러나 서버에 PHP가 없습니다. 여전히이 아이디어는 다른 http-aware 프로그래밍 언어에 유효합니다. :-)
Alexander Gladysh 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.