Nilai Membatasi Permintaan URL Individual

8

Saya memiliki aplikasi Flask yang saya kembangkan yang sangat bergantung pada interaksi situs web eksternal dan diprakarsai oleh pengguna akhir. Jika saya meninggalkan aplikasi tanpa kontrol bandwidth / pembatasan tingkat apa pun maka aplikasi ini dapat disalahgunakan oleh pelaku dengan niat jahat.

Tujuan saya adalah pendekatan 2 tahap yang cukup sederhana:

  1. Batas tingkat sumber IP individu dari melakukan lebih dari xjumlah koneksi per menit. Ini bisa dicapai dengan mudah iptables. Inilah contoh yang mirip dengan tujuan saya:

     iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 \
       --connlimit-mask 32 -j REJECT --reject-with tcp-reset  
    
  2. Nilai membatasi kemampuan aplikasi untuk melakukan lebih dari xjumlah pencarian per URL . Contoh:

     APP ---- 10 pps --->  stackexchange.com   PERMIT
     APP ---- 25 pps --->  google.com          DENY / 15 SECOND BACKOFF
    

Sejauh yang saya tahu, iptablestidak memiliki cara untuk melacak URL terpisah. Ini hanya dapat menilai batas koneksi ini secara keseluruhan. Itu juga sepertinya bukan satu-satunya batasan untuk apa yang saya coba capai. Jika ada cara untuk mensetup iptablesdengan cara ini, itu mungkin memberikan beberapa masalah dengan aplikasi web saya karena permintaan ini diprakarsai oleh pengguna.

Saya menggunakan Flask, opsi yang mungkin menggunakan before_requesthook dan secara manual melacak tujuan-tujuan ini dengan penyimpanan data seperti Redis. Namun, ini cukup tinggi di stack untuk berurusan dengan koneksi dengan cara ini. Yang benar-benar saya butuhkan (atau pikir saya lakukan) adalah aplikasi firewall cerdas yang dapat membedah permintaan dengan cara kustom dan menutup koneksi ketika breakpoints tertentu telah tercapai.

Apakah ada cara untuk mencapai apa yang saya coba lakukan?

Jika ya, bagaimana caranya?

Ryan Foley
sumber

Jawaban:

3

iptables berurusan dengan lapisan Internet dan Transport (dalam model Internet) atau sebagai alternatif lapisan 3 dan 4 dalam model OSI, dengan beberapa pengecualian (memfilter pada alamat MAC, pembantu protokol NAT).

URI adalah bagian dari lapisan Aplikasi. iptablestidak berurusan dengan mereka.

Anda dapat menggunakan iptables untuk mengarahkan semua lalu lintas port TCP 80 keluar melalui proxy web, yang dapat membatasi tingkat Anda (misalnya, mungkin kolam penundaan Squid bisa melakukannya. Atau Apache mungkin bisa mod_proxy.) Melakukan ini dengan HTTPS lebih sulit ( meskipun mungkin Anda bisa mengonfigurasi aplikasi untuk menggunakan proxy web, yang akan menjadi pendekatan yang lebih baik daripada proxy transparan).

Tetapi Anda harus benar-benar memindahkan kedua batas tarif Anda ke aplikasi Anda. Alasannya adalah UX yang Anda setting sangat buruk ; "koneksi ditolak" gagal menjelaskan sama sekali apa yang terjadi. Akan jauh lebih baik bagi pengguna Anda jika Anda memberikan halaman kesalahan yang menjelaskan bahwa mereka membuat permintaan terlalu cepat, siapa yang harus dihubungi untuk dukungan, mungkin memberikan opsi untuk menyelesaikan CAPTCHA untuk melanjutkan, dll.

Masuk akal untuk memiliki batas tingkat koneksi pada koneksi yang masuk, tetapi seharusnya melindungi aplikasi agar tidak terjatuh karena serangan DoS — begitu banyak permintaan yang bahkan aplikasi Anda tidak bisa menayangkan laju yang melebihi halaman kesalahan kepada pengguna. Itu harus sedikit lebih tinggi daripada ketika Anda mulai melayani halaman kesalahan (dan mungkin harus menjadi batas global, bukan batas per-sumber-IP). Perhatikan bahwa jika aplikasi Anda berjalan melalui server web dan / atau membalikkan proxy, Anda mungkin dapat mengonfigurasi batas nilai masuk di sana (alih-alih melalui iptables) —dan melakukan penolakan yang sangat murah dengan mengirimkan halaman kesalahan statis, dan bahkan tidak mengirimkan permintaan ke aplikasi Anda.

derobert
sumber