nginx: дамп HTTP-запитів для налагодження


17
  • Ubuntu 10.04.2
  • nginx 0.7.65

Я бачу деякі дивні запити HTTP, що надходять на мій сервер nginx.

Щоб краще зрозуміти, що відбувається, я хочу скинути цілі дані HTTP-запиту для таких запитів. (Тобто скидайте всі заголовки та тіло запитів десь я можу їх прочитати.)

Чи можу я це зробити за допомогою nginx? Крім того, чи є якийсь HTTP-сервер, який дозволяє мені це робити з вікна, до якого я можу проксі ці запити за допомогою nginx?

Оновлення: Зауважте, що це поле має купу нормального трафіку, і я хотів би уникнути захоплення всього цього на низькому рівні (скажімо, за допомогою tcpdump) та відфільтрування його пізніше.

Я думаю, що було б набагато простіше відфільтрувати хороший трафік спочатку за допомогою правила перезапису (на щастя, я можу записати його досить легко в цьому випадку), а потім мати справу лише з неправдивим трафіком.

І я не хочу скеровувати фальшивий трафік на інший ящик лише для того, щоб мати змогу зафіксувати його там tcpdump.

Оновлення 2: Щоб надати трохи більше деталей, фіктивний запит має fooв своєму GET-запиті параметр, назване (скажімо) (значення параметра може відрізнятися). Гарні запити гарантовано не матимуть цього параметра ніколи.

Якщо я зможу відфільтрувати за цим способом tcpdumpабо ngrepякимось чином - не проблема, я використаю їх.


Чи можете ви охарактеризувати / класифікувати запити, які ви вважаєте "дивними"? Як можна придумати правило, яке допоможе вам, якщо ви не поділитесь з нами тим, що є "нормальним" і "хибним"?
hobodave

Я не прошу правила - я можу легко його написати. Я прошу засобів скинути дані HTTP-запиту.
Олександр Гладиш

@hobodave: але все одно, оскільки ви вже запитували, я додав цю інформацію до питання.
Олександр Гладиш

Відповіді:


30

За необхідності відрегулюйте кількість рядків до / після (аргументи -B та -A):

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

Це дозволяє отримувати потрібні вами запити HTTP, не створюючи величезний файл PCAP, який вам доведеться завантажувати десь в іншому місці.

Майте на увазі, що фільтр БНФ ніколи не є точним, якщо велика кількість пакетів протікає через будь-яку коробку, БНФ може і буде скидати пакети.


5

Я точно не знаю, що ви маєте на увазі під запитом dump, але ви можете використовувати tcpdump та / або wireshark для аналізу даних:

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

І ви можете використовувати wireshark, щоб відкрити файл і побачити розмову між серверами.


Дякую, але у мене досить трафік на цьому сервері (99% це добре), і я думаю, що було б важко відфільтрувати цю купу даних для цього неправдивого 1%, який мені потрібен.
Олександр Гладиш

... якщо я захоплю все це на такому низькому рівні. :-)
Олександр Гладиш

Я оновив питання, щоб це відобразити.
Олександр Гладиш

Олександр - це означає, що 1 з кожних 100 запитів матиме дивні заголовки, які ви шукаєте. Виконайте захоплення на деякий час, а потім пошукайте отриманий журнал, шукаючи заголовки, які ви хочете - це, звичайно, не є нестерпним обсягом роботи.
ЄЕАА

Проблема полягає не в роботі, а в кількості даних, що обробляються. (Це, мабуть, нестерпно, але, як би там не було, я хотів би побачити дружніше рішення.)
Олександр Гладиш

0

Якщо ви проксі просити Apache з встановленим mod_php, ви можете використовувати наступний скрипт 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()).


Дякую. Але я не маю PHP на своїх серверах. Але ця ідея справедлива для будь-яких інших програмних знаків програмування. :-)
Олександр Гладиш
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.