IPTABLES - Velocità limite di un IP in entrata specifico


103

Non desidero limitare la tariffa di un servizio specifico. Il mio obiettivo è limitare la tariffa esclusivamente in base all'indirizzo IP in arrivo. Ad esempio usando una pseudo-regola:

john.domain.local (192.168.1.100) can only download from our httpd/ftp servers at "10KB/s" (instead of 1MB/s)

Come posso limitare il limite utilizzando le tabelle IP basate sugli indirizzi IP in arrivo?

Risposte:


165

IPTables non è fatto per questo tipo di lavoro, dove è necessario analizzare un sacco di pacchetti per prendere queste decisioni. IPTables è in parte la risposta però!

La vera risposta a ciò sono le fantastiche e sottoutilizzate strutture di controllo del traffico in Linux. Ricorda che non ti preoccupare di ciò senza sapere cosa sta succedendo potrebbe farti perdere la connettività di rete con la macchina! Sei stato avvertito!

Supponendo che eth0 sia il dispositivo in uscita, sarà necessario creare una coda di controllo del traffico basata su classi che, per impostazione predefinita, genererà la maggior parte del traffico attraverso la coda "veloce" e inserirà un elenco specifico di persone nella coda "lenta".

Il bello di questo è che puoi creare una situazione in cui permetti un sacco di traffico in uscita per l'utente lento a meno che una classe dominante non desideri la larghezza di banda, ma questo esempio non lo fa (fornirà sempre 10kbps agli utenti lenti). Il sistema di accodamento sarà simile a questo:

                         Inbound traffic
                              +
                              |
                              |
                              v
                     +------------------+
                     |   Class 1:1      |
                     |------------------|
                     |  Root (all flows)|
                     |       100mbit    |
                     +-----+-----+------+
                           |     |
                           |     |
                           |     |
                           |     |
                           |     |
          +----------+     |     |     +----------+
          |    1:11  +-----+     +-----+    1:12  |
          |----------|                 |----------|
          | Default  |                 | Slow     |
          |100mb-80kb|                 |   80kb   |
          +----------+                 +----------+

Per fare ciò, devi prima impostare la disciplina di accodamento nel kernel. Quanto segue lo farà per te .. devi eseguirlo come un intero script

#!/bin/bash
tc qdisc add dev eth0 parent root handle 1: hfsc default 11
tc class add dev eth0 parent 1: classid 1:1 hfsc sc rate 100mbit ul rate 100mbit
tc class add dev eth0 parent 1:1 classid 1:11 hfsc sc rate 99920kbit ul rate 100000kbit
tc class add dev eth0 parent 1:1 classid 1:12 hfsc sc rate 80kbit ul rate 80kbit

tc qdisc add dev eth0 parent 1:11 handle 11:1 pfifo
tc qdisc add dev eth0 parent 1:12 handle 12:1 pfifo

L '"11 predefinito" è importante in quanto indica al kernel cosa fare con il traffico non classificato.

Una volta fatto ciò, è quindi possibile impostare una regola iptables per classificare i pacchetti che soddisfano determinati criteri. Se hai intenzione di mettere molte e molte persone in questa regola lenta, una regola ipset è più appropriata (che dovrebbe essere disponibile su rhel6 credo).

Quindi, crea un database ipset per fare la corrispondenza contro ...

ipset create slowips hash:ip,port

Quindi crea la regola iptables per eseguire la corrispondenza.

iptables -t mangle -I OUTPUT -m set --match-set slowips dst,src -j CLASSIFY --set-class 1:12

Questo indica al kernel che se abbini l'IP di destinazione con la porta di origine del set, classificalo nella coda lenta che imposti con il controllo del traffico.

Ora, finalmente, ogni volta che vuoi rallentare un IP puoi usare il comando ipset per aggiungere l'ip al set come questo:

ipset add slowips 192.168.1.1,80
ipset add slowips 192.168.1.1,21
...

Puoi testarlo funziona usando il comando "tc -s class show dev eth0" e vedrai lì delle statistiche che indicano che i pacchetti vengono reindirizzati alla coda lenta.

Nota l'unico vero svantaggio di questo è far sopravvivere ai riavvii. Non credo che ci siano script di init disponibili per creare ipset dai dump al riavvio (e devono anche essere creati prima delle regole di iptables) e sono certo che non ci sono script di init per ripristinare le regole di controllo del traffico al riavvio. Se non ti da fastidio, puoi semplicemente ricreare il tutto invocando uno script in rc.local.


3
Bene, non posso ringraziarti abbastanza. Questo è molto descrittivo e molto informativo. In seguito ho capito che sarebbe stata necessaria la conoscenza di TC e da allora ho iniziato a esaminare questo. Grazie ancora!
James,

Oh, e per quanto riguarda la perdita di connessione. Mi assicuro di avere la configurazione disattivata prima di passare dal mio VPS al computer host. Inoltre, ho accesso VPN alla rete privata su ETH0. Lavorerò solo su ETH1, quindi in teoria non avrò il problema. Ma avvertimento sentito!
James,

2
Non posso dirvi quante volte ho letto tutorial simili, questo è il primo che aveva un senso
RC1140

5
Come sidenote, in genere è più appropriato fare una limitazione delle risorse come questa nei gruppi di controllo (di nuovo, anche possibile e anche sottoutilizzato e fantastico) in quanto è possibile definire limiti per applicazione su CPU, memoria, I / O e rete in un policy store centralizzato '. Ma devo ancora vedere una simile domanda posta per offrire una risposta.
Matthew Ife,

2
Se non ti piace la tcsintassi, potresti provare tcng che aggiunge un linguaggio un po 'più user friendly che genera tccomandi. Ho usato come questo negli script di shell: echo '... multi line tcng configuration ...' | tcng | sh.
Mattias Wadman,

5

È semplice come prendere una regola di limitazione della velocità e aggiungere l' -sinterruttore. Lo -sswitch corrisponde agli IP in entrata. Ad esempio, iptables -A INPUT -s 1.1.1.1per poi finire con il tuo metodo preferito di limitazione della frequenza per quella regola.


Grazie per la vostra pronta risposta. Purtroppo il mio problema principale è la seconda metà. Ho esaminato --limit e non ho visto nulla che mi permetta di limitare in base a KB / s - qualsiasi direzione mi puoi indicare?
James,

1
@James, sarei tornato da te, ma dovevo uscire a casa di un amico. Sono appena tornato e vedo che MIfe ha fatto un buon lavoro. =)
Wesley,
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.