Wie kann ich Traffic Shaping unter Linux per IP durchführen?

15

Wir haben ein transparentes Proxy-Setup. Ich habe versucht, Traffic Shaping in Linux zu finden, und alles, was ich online finden konnte, war, den Datenverkehr über die Schnittstelle (eth0 / eth1 ...) zu begrenzen.

Ich muss die Bandbreite nach IP-Adresse oder IP-Bereich begrenzen (nie ein bestimmtes Limit überschreiten), und ich kann keinen Weg finden, dies zu tun.

Gibt es eine Möglichkeit, das zu tun?

Osama ALASSIRY
quelle

Antworten:

17

Die Traffic-Shaping-Schicht des Kernels ist im Grunde ein Paket-Scheduler, der an Ihre Netzwerkkarte angeschlossen ist. Daher gilt eine Traffic-Shaping-Richtlinie für eine Netzwerkkarte.

In Ihrem Fall können Sie eine Liste der angehängten IP-Adressen und der Bandbreite erstellen und dann für jede IP-Adresse Folgendes erstellen:

  • Eine Traffic-Shaping-Regel, die von einer Classid identifiziert wird
  • Eine Netzfilterregel, die Pakete mit einem bestimmten Markierungswert markiert
  • Ein Filter, der diese Pakete bindet, markiert die Klassen-ID und wendet somit die Verkehrssteuerungsregel auf die angegebenen Pakete an.

Das Beispiel von @Zoredache funktioniert, aber ich persönlich bevorzuge die Verwendung der Netfilter-Funktion anstelle von TC zum Filtern von Paketen und HTB anstelle von CBQ für den Shapping-Algorithmus. Sie können also so etwas ausprobieren (erfordert Bash 4 für assoziative Arrays):

#! /bin/bash
NETCARD=eth0
MAXBANDWIDTH=100000

# reinit
tc qdisc del dev $NETCARD root handle 1
tc qdisc add dev $NETCARD root handle 1: htb default 9999

# create the default class
tc class add dev $NETCARD parent 1:0 classid 1:9999 htb rate $(( $MAXBANDWIDTH ))kbit ceil $(( $MAXBANDWIDTH ))kbit burst 5k prio 9999

# control bandwidth per IP
declare -A ipctrl
# define list of IP and bandwidth (in kilo bits per seconds) below
ipctrl[192.168.1.1]="256"
ipctrl[192.168.1.2]="128"
ipctrl[192.168.1.3]="512"
ipctrl[192.168.1.4]="32"

mark=0
for ip in "${!ipctrl[@]}"
do
    mark=$(( mark + 1 ))
    bandwidth=${ipctrl[$ip]}

    # traffic shaping rule
    tc class add dev $NETCARD parent 1:0 classid 1:$mark htb rate $(( $bandwidth ))kbit ceil $(( $bandwidth ))kbit burst 5k prio $mark

    # netfilter packet marking rule
    iptables -t mangle -A INPUT -i $NETCARD -s $ip -j CONNMARK --set-mark $mark

    # filter that bind the two
    tc filter add dev $NETCARD parent 1:0 protocol ip prio $mark handle $mark fw flowid 1:$mark

    echo "IP $ip is attached to mark $mark and limited to $bandwidth kbps"
done

#propagate netfilter marks on connections
iptables -t mangle -A POSTROUTING -j CONNMARK --restore-mark

- edit: vergaß die Standardklasse und verbreite Markierungen am Ende des Skripts.

Julien Vehent
quelle
ähm ... wie füge ich ein Standard-Bandbreitenlimit für diejenigen hinzu, die nicht auf der Liste stehen?
Kokizzu
Sie haben $ mark als Prio-Definition verwendet. Wäre es nicht besser, allen dieselbe Priorität einzuräumen?
Motobói
Wenn ich "iptables -t mangle -A INPUT" in "iptables -t mangle -A OUTPUT" ändere, kann ich dann die Rate von meinem Server auf eine bestimmte IP steuern?
Frank Barcenas
Wie stelle ich die Einstellungen danach wieder her?
Stefan Rogin
Cant 'scheint dies zu ermöglichen, indem Befehle manuell ohne Schleife für eine einzelne IP geschrieben werden.
Adones Pitogo
5

So etwas funktionierte für mich, um die Webkamera eines Auftragnehmers auf eine begrenzte Bandbreite zu beschränken. Weitere Informationen finden Sie auf der Manpage für tc .

#!/bin/bash
set -x

DEV=eth0
export DEV

tc qdisc del dev $DEV root
tc qdisc del dev $DEV root
tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 100mbit

# setup a class to limit to 1500 kilobits/s
tc class add dev $DEV parent 1: classid 1:1 cbq rate 1500kbit \
   allot 1500 prio 5 bounded isolated

# add traffic from 10.2.1.37 to that class
tc filter add dev $DEV parent 1: protocol ip prio 16 u32 \
   match ip src 10.2.1.37 flowid 1:1
Zoredache
quelle
3
CBQ ist ein bisschen aufgegeben ... Sie würden feststellen, dass HTB viel einfacher zu verwenden ist und dasselbe Ergebnis
erzielt wird
1
DEV muss nicht exportiert werden, wenn es nur in diesem Skript verwendet wird ....
Gert van den Berg
1

Ich bin nicht sicher, ob ich Ihre Frage richtig verstehe.

Transparentes Proxying (wie in Squid für HTTP) wird verwendet, um die meisten eingehenden Daten zu steuern. Während Traffic Shaping verwendet wird, um ausgehende Daten zu steuern.

Sie müssen weitere Details angeben. Wenn Sie viele Workstations hinter einem HTTP-Proxy haben und versuchen, deren Download-Geschwindigkeit zu begrenzen, sollten Sie sich für etwas wie Squid + Delay-Pools entscheiden.

halp
quelle