IPTABLES - Grenzrate einer bestimmten eingehenden IP

103

Ich möchte den Tarif für eine bestimmte Dienstleistung nicht einschränken. Mein Ziel ist es, die Rate ausschließlich auf der Grundlage der eingehenden IP-Adresse zu begrenzen. Zum Beispiel mit einer Pseudoregel:

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

Wie kann ich die Verwendung von IPTables basierend auf eingehenden IP-Adressen einschränken?

James
quelle

Antworten:

165

IPTables ist nicht für diese Art von Arbeit geeignet, bei der viele, viele Pakete analysiert werden müssen, um diese Entscheidungen zu treffen. IPTables ist zum Teil die Antwort!

Die eigentliche Antwort auf diese Frage sind die fantastischen und wenig genutzten Verkehrssteuerungsfunktionen in Linux. Beachten Sie, dass Sie die Netzwerkverbindung zum Computer verlieren können, wenn Sie nicht wissen, was gerade passiert. Du wurdest gewarnt!

Angenommen, eth0 ist das ausgehende Gerät, das Sie benötigen, um eine klassenbasierte Verkehrssteuerungswarteschlange zu erstellen, die standardmäßig den meisten Verkehr über die "schnelle" Warteschlange ausgibt und eine bestimmte Liste von Personen in die "langsame" Warteschlange stellt.

Das Schöne daran ist, dass Sie eine Situation erstellen können, in der Sie viel ausgehenden Datenverkehr für langsame Benutzer zulassen, es sei denn, eine übergeordnete Klasse möchte die Bandbreite. In diesem Beispiel wird dies jedoch nicht ausgeführt (den langsamen Benutzern werden immer 10 KBit / s bereitgestellt). Das Warteschlangensystem sieht ungefähr so ​​aus:

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

Dazu müssen Sie zuerst die Warteschlangendisziplin im Kernel einrichten. Das Folgende erledigt dies für Sie. Sie müssen dies als ein ganzes Skript ausführen

#!/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

Die "Standard 11" ist wichtig, da sie dem Kernel mitteilt, was mit nicht klassifiziertem Datenverkehr zu tun ist.

Anschließend können Sie eine iptables-Regel einrichten, um Pakete zu klassifizieren, die bestimmten Kriterien entsprechen. Wenn Sie vorhaben, viele, viele Leute in diese langsame Regel einzubeziehen, ist eine Ipset-Regel geeigneter (die meines Erachtens auf rhel6 verfügbar sein sollte).

Erstellen Sie also eine ipset-Datenbank, um den Abgleich gegen ...

ipset create slowips hash:ip,port

Erstellen Sie dann die iptables-Regel, um den Abgleich durchzuführen.

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

Dies weist den Kernel an, dass, wenn Sie die Ziel-IP mit dem Quellport aus der Gruppe abgleichen, diese in die langsame Warteschlange klassifizieren, die Sie mit der Verkehrssteuerung eingerichtet haben.

Nun, wann immer Sie eine IP verlangsamen möchten, können Sie den Befehl ipset verwenden, um die IP der Gruppe wie folgt hinzuzufügen:

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

Sie können testen, ob es mit dem Befehl "tc -s class show dev eth0" funktioniert. Dort sehen Sie Statistiken, die angeben, dass Pakete an die langsame Warteschlange umgeleitet werden.

Beachten Sie, dass der einzige wirkliche Nachteil darin besteht, Neustarts zu überstehen. Ich glaube nicht, dass Init-Skripte verfügbar sind, um die IPSets beim Neustart aus Speicherauszügen zu erstellen (und sie müssen auch vor den Iptables-Regeln erstellt werden), und ich bin sicher, dass es keine Init-Skripte gibt, mit denen die Regeln für die Verkehrssteuerung beim Neustart zurückgesetzt werden können. Wenn es Sie nicht stört, können Sie das Ganze einfach durch Aufrufen eines Skripts in rc.local neu erstellen.

Matthew Ife
quelle
3
Nun, ich kann dir nicht genug danken. Dies ist sehr anschaulich und sehr informativ. Später wurde mir klar, dass TC-Kenntnisse erforderlich sein würden, und seitdem habe ich mich damit befasst. Danke noch einmal!
James
Oh und was den Verbindungsverlust angeht. Ich stelle sicher, dass die Konfiguration nicht funktioniert, bevor ich von meinem VPS auf den Hostcomputer wechsle. Ich habe auch VPN-Zugang zum privaten Netzwerk auf ETH0. Ich werde nur an ETH1 arbeiten, also werde ich theoretisch kein Problem haben. Aber Warnung gehört!
James
2
Ich kann Ihnen nicht sagen, wie oft ich ähnliche Tutorials gelesen habe. Dies ist das erste, das Sinn macht
RC1140
5
Als Randbemerkung ist es in der Regel sinnvoller, eine solche Ressourcenbeschränkung in Kontrollgruppen vorzunehmen (wiederum möglich und auch nicht ausgelastet und beeindruckend), da Sie in einem zentralen Richtlinienspeicher anwendungsspezifische Beschränkungen für CPU, Speicher, E / A und Netzwerk definieren können '. Aber noch nicht gesehen, dass eine solche Frage gestellt wird, um eine Antwort zu geben.
Matthew Ife
2
Wenn Ihnen die tcSyntax nicht gefällt, können Sie tcng ausprobieren, um eine benutzerfreundlichere Sprache hinzuzufügen , mit der tcBefehle generiert werden. Ich habe verwendet diese Skripte in der Schale mögen: echo '... multi line tcng configuration ...' | tcng | sh.
Mattias Wadman
5

Es ist so einfach wie eine Ratenbegrenzungsregel anzunehmen und den -sSchalter hinzuzufügen . Der -sSwitch stimmt mit eingehenden IP-Adressen überein. Zum Beispiel iptables -A INPUT -s 1.1.1.1und zum Schluss mit Ihrer bevorzugten Methode zur Begrenzung der Rate für diese Regel.

Wesley
quelle
Danke für deine schnelle Antwort. Leider ist mein Hauptproblem die zweite Hälfte davon. Ich habe mich mit --limit befasst und nichts gesehen, was es mir erlaubt, die Anzahl der KB / s zu begrenzen - in welche Richtung können Sie mich weisen?
James
1
@James Ich hätte mich bei dir gemeldet, aber ich musste zum Haus eines Freundes gehen. Komme gerade zurück und ich sehe, dass MIfe einen ziemlichen Job gemacht hat. =)
Wesley