Tariffa che limita le richieste di singoli URL


8

Sto sviluppando un'applicazione Flask che si basa fortemente sull'interazione di siti Web esterni e viene avviata dall'utente finale. Se lascio l'applicazione senza alcun tipo di controllo / limitazione della larghezza di banda, questa applicazione potrebbe essere abusata da attori con intenzioni nefaste.

Il mio obiettivo è un approccio in due fasi abbastanza semplice:

  1. La velocità limita le singole fonti IP dall'esecuzione di un xnumero di connessioni superiore al minuto. Questo può essere facilmente raggiunto con iptables. Ecco un esempio simile al mio obiettivo:

     iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 \
       --connlimit-mask 32 -j REJECT --reject-with tcp-reset  
    
  2. La velocità limita la capacità delle applicazioni di eseguire più del xnumero di ricerche per URL . Esempio:

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

Per quanto ne so, iptablesnon ha modo di tracciare URL separati. È solo in grado di limitare la velocità di queste connessioni nel loro insieme. Anche questo non sembra l'unico limite a ciò che sto cercando di ottenere. Se esistesse un modo per eseguire l'installazione iptablesin questo modo, potrebbero verificarsi alcuni problemi con la mia applicazione Web poiché queste richieste sono avviate dall'utente.

Sto usando Flask, un'opzione praticabile potrebbe essere l'utilizzo di un before_requesthook e il monitoraggio manuale di queste destinazioni con un archivio dati come Redis. Tuttavia, questo è abbastanza in alto nello stack per gestire le connessioni in questo modo. Ciò di cui ho veramente bisogno (o penso di farlo) è un'applicazione firewall intelligente in grado di analizzare le richieste in modo personalizzato e chiudere le connessioni quando sono stati raggiunti determinati punti di interruzione.

C'è un modo per ottenere ciò che sto cercando di fare?

Se é cosi, come?

Risposte:


3

iptables tratta i livelli Internet e Transport (nel modello Internet) o in alternativa i livelli 3 e 4 nel modello OSI, con alcune eccezioni (filtraggio su indirizzi MAC, helper del protocollo NAT).

Gli URI fanno parte del livello Applicazione. iptablesnon li affronta.

Puoi usare iptables per indirizzare tutto il traffico della tua porta TCP 80 in uscita attraverso un proxy web, il che potrebbe limitare la tua velocità (ad esempio, forse i pool di ritardo di Squid potrebbero farlo. O Apache probabilmente può mod_proxyfarlo.) Fare questo con HTTPS è più difficile ( anche se forse puoi semplicemente configurare la tua app per utilizzare un proxy Web, che sarebbe comunque un approccio migliore di un proxy trasparente).

Ma dovresti davvero spostare entrambi i tuoi limiti di velocità nella tua applicazione. Il motivo è che la UX che stai configurando è terribile ; "connessione rifiutata" non spiega affatto cosa sta succedendo. Sarebbe molto meglio per i tuoi utenti se invece fornissi una pagina di errore che spiega che stanno facendo richieste troppo in fretta, chi contattare per ricevere assistenza, magari dare un'opzione per risolvere un CAPTCHA per continuare, ecc.

È ragionevole avere un limite di velocità di connessione per le connessioni in entrata, ma dovrebbe essere per proteggere l'app da una caduta a causa di un attacco DoS, così tante richieste che la tua app non può nemmeno servire la pagina di errore che ha superato la frequenza per l'utente. Dovrebbe essere un po 'più alto di quando inizi a pubblicare la pagina di errore (e forse dovrebbe essere un limite globale, non un limite IP per sorgente). Tieni presente che se la tua app è in esecuzione attraverso un server Web e / o proxy inverso, puoi probabilmente configurare i limiti di velocità in entrata lì (anziché tramite iptables) e fare scarti molto economici inviando una pagina di errore statico e nemmeno passando la richiesta alla tua app.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.