nginx: buang permintaan HTTP untuk debugging

17
  • Ubuntu 10.04.2
  • nginx 0.7.65

Saya melihat beberapa permintaan HTTP aneh yang datang ke server nginx saya.

Untuk lebih memahami apa yang sedang terjadi, saya ingin membuang seluruh data permintaan HTTP untuk pertanyaan semacam itu. (Yaitu membuang semua header dan badan permintaan di suatu tempat saya bisa membacanya.)

Bisakah saya melakukan ini dengan nginx? Atau, apakah ada beberapa server HTTP yang memungkinkan saya melakukan ini di luar kotak, di mana saya dapat mem-proxy permintaan ini dengan cara nginx?

Pembaruan: Perhatikan bahwa kotak ini memiliki banyak lalu lintas normal, dan saya ingin menghindari menangkap semuanya pada tingkat rendah (katakanlah, dengan tcpdump) dan memfilternya nanti.

Saya pikir akan jauh lebih mudah untuk menyaring lalu lintas yang baik terlebih dahulu dalam aturan penulisan ulang (untungnya saya bisa menulis satu dengan mudah dalam kasus ini), dan kemudian berurusan dengan lalu lintas palsu saja.

Dan saya tidak ingin menyalurkan lalu lintas palsu ke kotak lain hanya untuk dapat menangkapnya di sana tcpdump.

Pembaruan 2: Untuk memberikan sedikit lebih banyak detail, permintaan palsu memiliki parameter bernama (katakanlah) foodalam kueri GET mereka (nilai parameter dapat berbeda). Permintaan yang baik dijamin tidak memiliki parameter ini.

Jika saya dapat memfilter dengan ini tcpdumpatau ngrepentah bagaimana - tidak masalah, saya akan menggunakan ini.

Alexander Gladysh
sumber
Bisakah Anda mengkarakterisasi / mengklasifikasikan permintaan yang Anda anggap "aneh"? Bagaimana seseorang bisa membuat aturan untuk membantu Anda jika Anda tidak berbagi dengan kami apa yang 'normal' dan 'palsu'?
hobodave
Saya tidak meminta aturan - saya bisa menulisnya sendiri dengan mudah. Saya meminta cara untuk membuang data permintaan HTTP.
Alexander Gladysh
@obodave: tetapi, karena Anda sudah bertanya, saya telah menambahkan informasi ini ke pertanyaan.
Alexander Gladysh

Jawaban:

30

Sesuaikan jumlah baris sebelum / sesudah (-B dan -A args) sesuai kebutuhan:

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

Ini memungkinkan Anda mendapatkan permintaan HTTP yang Anda inginkan, di kotak, tanpa menghasilkan file PCAP besar yang harus Anda muat di tempat lain.

Perlu diingat, bahwa filter BPF tidak pernah tepat, jika ada sejumlah besar paket yang mengalir melalui kotak apa pun, BPF dapat dan akan menjatuhkan paket.

oo.
sumber
5

Saya tidak tahu persis apa yang Anda maksud dengan dump permintaan tetapi Anda dapat menggunakan tcpdump dan / atau wireshark untuk menganalisis data:

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

Dan Anda dapat menggunakan wireshark untuk membuka file dan melihat percakapan antara server.

coredump
sumber
Terima kasih, tapi saya punya sedikit lalu lintas di server ini (99% bagus), dan saya pikir akan sulit untuk menyaring banyak data untuk 1% palsu yang saya butuhkan.
Alexander Gladysh
... jika saya menangkap semuanya pada level rendah seperti itu. :-)
Alexander Gladysh
Saya telah memperbarui pertanyaan untuk mencerminkan hal itu.
Alexander Gladysh
Alexander - baik itu berarti 1 dari setiap 100 permintaan akan memiliki tajuk aneh yang Anda cari. Jalankan tangkapan untuk sementara waktu dan kemudian cari melalui log yang dihasilkan mencari header yang Anda inginkan - itu pasti bukan jumlah pekerjaan yang tak tertahankan.
EEAA
Masalahnya bukan pekerjaan, tetapi jumlah data untuk diproses. (Mungkin bisa ditoleransi, tetapi, bagaimanapun juga, saya ingin melihat solusi yang lebih ramah.)
Alexander Gladysh
0

Jika Anda mem-proxy permintaan ke Apache dengan mod_php terinstal, Anda dapat menggunakan skrip PHP berikut untuk membuang permintaan:

<?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);

Perhatikan bahwa karena Anda menggunakan nginx $_SERVER['REMOTE_ADDR']mungkin tidak ada gunanya. Anda harus meneruskan IP asli ke Apache melalui proxy_set_header X-Real-IP $remote_addr;, dan Anda dapat menggunakannya sebagai gantinya (atau hanya mengandalkan itu sedang login melalui getallheaders()).

hobodave
sumber
Terima kasih. Tapi saya tidak punya PHP di server saya. Gagasan itu masih berlaku untuk lagu-lagu pemrograman http-aware lainnya. :-)
Alexander Gladysh