[[Vorlage(Getestet, general)]] [[Vorlage(Fortgeschritten)]] {{{#!vorlage Wissen [:Editor: Einen Editor öffnen] }}} [[Inhaltsverzeichnis()]] [wikipedia:Traffic-Shaping:] hat die Fähigkeit, verschiedene Netzwerk-Verbindungen unterschiedlich zu behandeln und somit Datenpaketen im Netzwerk unterschiedliche Prioritäten einzuräumen. Der Nutzen besteht zum Beispiel darin, dass eine bestehende Netzwerkverbindung, welche die verfügbare Bandbreite des Netzwerks vollständig ausschöpft, eine weitere Netzwerkverbindung nicht zur Gänze ausbremsen kann. Es lässt eine spezifische Bandbreitenverteilung der unterschiedlichen Netzwerk-Protokolle zu. Falls man es in einem Router einsetzt, kann man damit auch die Netzwerk-Nutzung der angeschlossenen Rechner reglementieren. Insgesamt sorgt es für eine optimierte Abarbeitung der Datenpakete und stellt eine effiziente Ausnutzung der verfügbaren Bandbreite sicher. {{{#!vorlage Hinweis Wer ein etwas einfacher zu verstehendes Programm bevorzugt, kann sich [:Trickle:] anschauen. }}} = Installation = Die nötigen Programme und Pakete sind bei jeder Ubuntu-Installation bereits installiert. Man muss sie nur noch mittels eines Scripts, das man selbst anlegt [1], konfigurieren und aktivieren. Dazu bedient man sich folgender Programme: * '''/sbin/tc''' (definiert die Bandbreitenverteilung) * '''/sbin/iptables''' (markiert die Pakete für IPv4, s. [:iptables:]) * '''/sbin/ip6tables''' (markiert die Pakete für IPv6) * '''/usr/sbin/nft''' (kann __statt__ iptables ab Kernel 5 verwendet werden, s. [wikipedia_en:Nftables: nftables]) = Beispiel: DSL = Ein einfaches, aber sehr nützliches Einsatzszenario für Traffic-Shaping ist die Beeinflussung des Netzwerktraffics des DSL-Anschlusses. Da bei DSL der Upstream geringer als der Downstream ist, kann der Upstream schnell "verstopfen". Dies geschieht, weil bei TCP-Verbindungen jedes empfangene Paket mit einer "Empfangsbestätigung" beantwortet werden muss. Die Lage verschlimmert sich noch, wenn andere Netzwerkverbindungen den Upstream gleichfalls benutzen wollen. Genaueres dazu findet man bei [wikipedia:TCP/IP:]. Um den Traffic zu beeinflussen, werden sogenannte "Regeln" angelegt, welche vom Kernel abgearbeitet werden. == Initialisierung == Der DSL-Anschluss mittels Modem läuft in der Regel über das Netzwerkgerät `ppp0`. Ist man über einen Router mit dem Internet verbunden, so ist heißt das zuständige Netzwerkgerät oft `eth0`. Das zuständige Netzwerkgerät wird mit dem Variablennamen `DEV` in der ersten Zeile übergeben. {{{DEV=ppp0 IPT=/sbin/iptables TC=/sbin/tc $IPT -t mangle -F $TC qdisc del dev $DEV ingress > /dev/null 2>&1 $TC qdisc del dev $DEV root > /dev/null 2>&1 $TC qdisc del dev lo root > /dev/null 2>&1 }}} Die letzten vier Zeilen säubern das System von eventuell zuvor angelegten Regeln. == Bandbreiten == Tatsächlich interessiert nur der verfügbare Upstream des DSL-Anschlusses. Die Datenpakete im Downstream kommen sowieso so schnell herein, wie sie eben ankommen. In diesem Beispiel gehen wir von einem Anschluss mit einem Upstream von 192kbit aus. {{{$TC qdisc add dev $DEV root handle 1:0 htb default 12 r2q 6 $TC class add dev $DEV parent 1:0 classid 1:1 htb rate 190kbit ceil 190kbit }}} In Zeile eins wird das Traffic-Shaping aktiviert. Mit dem Eintrag `default 12` wird der Kanal `12` als derjenige festgelegt, der benutzt wird, wenn keine Regel zutrifft. In Zeile zwei wird die maximal verfügbare Bandbreite des Upstreams festgelegt. Hier wählt man sinnvollerweise einen Wert, der geringfügig unter dem tatsächlich höchstmöglichen Wert liegt, damit auf der Empfängerseite (beim Provider) kein Stau entsteht. Nun werden die eigentlichen Regeln festgelegt, die den Kanälen verschiedene Bandbreiten und Prioritäten zuweisen: {{{$TC class add dev $DEV parent 1:1 classid 1:10 htb rate 30kbit ceil 190kbit prio 0 $TC class add dev $DEV parent 1:1 classid 1:11 htb rate 60kbit ceil 190kbit prio 1 $TC class add dev $DEV parent 1:1 classid 1:12 htb rate 100kbit ceil 190kbit prio 2 }}} In Zeile eins wird der Kanal `10` definiert (`classid 1:10`). Er bekommt immer mindestens 30kbit Bandbreite (`rate 30kbit`) und darf maximal 190kbit nutzen (`ceil 190kbit`). Zeile zwei und drei legen die Werte für Kanal `11` und `12` analog fest. Die Summe aller `rate`-Werte darf die höchstmögliche Bandbreite nicht überschreiten. == Zuweisung == Nun muss man den verschiedenen Datenpaketen ihre Kanäle zuweisen. Dazu werden sie markiert: {{{$IPT -A POSTROUTING -t mangle -o $DEV -p tcp -m length --length :64 -j MARK --set-mark 10 $IPT -A POSTROUTING -t mangle -o $DEV -p udp --dport 53 -j MARK --set-mark 10 }}} In Zeile eins werden alle Pakete mit einer Länge bis zu 64 Byte mit dem Kanal `10` verknüpft. Dies ist ein einfacher Trick, um alle Pakete zu erfassen, die für einen schnellen Verbindungsaufbau nötig sind. Zeile zwei markiert alle Pakete, die für den [wikipedia:Domain_Name_System:DNS] nötig sind. Um auch bei großen Downloads per [wikipedia:File_Transfer_Protocol:FTP] noch schnell surfen zu können, werden nun die Pakete von [wikipedia:Hypertext_Transfer_Protocol:HTTP]-Verbindungen mit dem Kanal ``11`` verknüpft: {{{$IPT -A POSTROUTING -t mangle -o $DEV -p tcp --dport 80 -j MARK --set-mark 11 }}} Die Regeln werden nacheinander durchlaufen. Das bedeutet, dass ein Paket auch mehrmals ummarkiert werden kann, falls mehrere Bedingungen zutreffen. Nicht markierte Pakete landen automatisch im `default`-Kanal. == Management == Nun muss dem Kernel noch mitgeteilt werden, wie er die verschiedenen Kanäle zu behandeln hat: {{{$TC filter add dev $DEV parent 1:0 prio 0 protocol ip handle 10 fw flowid 1:10 $TC filter add dev $DEV parent 1:0 prio 0 protocol ip handle 11 fw flowid 1:11 $TC qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10 $TC qdisc add dev $DEV parent 1:11 handle 11: sfq perturb 10 $TC qdisc add dev $DEV parent 1:12 handle 12: sfq perturb 10 }}} Wer wissen will, was hiermit festgelegt wird, der sehe in der [:man:Manpage] zu '''tc''' nach. = Dauerhafte Aktivierung = Um das Script automatisch bei jedem Systemstart auszuführen, legt man es zum Beispiel unter dem Namen '''shaper''' im Verzeichnis '''/usr/local/sbin/''' ab, und lässt es vom Init-System [:systemd:] als selbst erstellte [:systemd/Units:Unit] starten. = Fertige Skripte = == DSL mit 192kbit Upstream == Verbindungen für TCP-Antwortpakete, DNS, SSH (ein- und ausgehend) und HTTP werden bevorzugt. {{{#!/bin/sh DEV=ppp0 IPT=/sbin/iptables TC=/sbin/tc $IPT -t mangle -F $TC qdisc del dev $DEV ingress > /dev/null 2>&1 $TC qdisc del dev $DEV root > /dev/null 2>&1 $TC qdisc del dev lo root > /dev/null 2>&1 $TC qdisc add dev $DEV root handle 1:0 htb default 12 r2q 6 $TC class add dev $DEV parent 1:0 classid 1:1 htb rate 190kbit ceil 190kbit $TC class add dev $DEV parent 1:1 classid 1:10 htb rate 20kbit ceil 190kbit prio 0 $TC class add dev $DEV parent 1:1 classid 1:11 htb rate 20kbit ceil 190kbit prio 1 $TC class add dev $DEV parent 1:1 classid 1:12 htb rate 150kbit ceil 190kbit prio 2 $IPT -A POSTROUTING -t mangle -o $DEV -p tcp -m length --length :64 -j MARK --set-mark 10 $IPT -A POSTROUTING -t mangle -o $DEV -p udp --dport 53 -j MARK --set-mark 10 $IPT -A POSTROUTING -t mangle -o $DEV -p tcp --dport 22 -j MARK --set-mark 11 $IPT -A POSTROUTING -t mangle -o $DEV -p tcp --sport 22 -j MARK --set-mark 11 $IPT -A POSTROUTING -t mangle -o $DEV -p tcp --dport 80 -j MARK --set-mark 11 $TC filter add dev $DEV parent 1:0 prio 0 protocol ip handle 10 fw flowid 1:10 $TC filter add dev $DEV parent 1:0 prio 0 protocol ip handle 11 fw flowid 1:11 $TC qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10 $TC qdisc add dev $DEV parent 1:11 handle 11: sfq perturb 10 $TC qdisc add dev $DEV parent 1:12 handle 12: sfq perturb 10 }}} == DSL mit 640kbit Upstream == Verbindungen für TCP-Antwortpakete, DNS und SSH (ein- und ausgehend) werden bevorzugt. Zudem werden Pakete zu den Ports 6881 bis 6889 (zum Beispiel für Bittorrent) auf einen maximalen Durchsatz von 250kbit beschränkt. {{{#!/bin/sh DEV=ppp0 IPT=/sbin/iptables TC=/sbin/tc $IPT -t mangle -F $TC qdisc del dev $DEV ingress > /dev/null 2>&1 $TC qdisc del dev $DEV root > /dev/null 2>&1 $TC qdisc del dev lo root > /dev/null 2>&1 $TC qdisc add dev $DEV root handle 1:0 htb default 12 r2q 6 $TC class add dev $DEV parent 1:0 classid 1:1 htb rate 635kbit ceil 635kbit $TC class add dev $DEV parent 1:1 classid 1:10 htb rate 40kbit ceil 635kbit prio 0 $TC class add dev $DEV parent 1:1 classid 1:11 htb rate 60kbit ceil 635kbit prio 1 $TC class add dev $DEV parent 1:1 classid 1:12 htb rate 500kbit ceil 635kbit prio 2 $TC class add dev $DEV parent 1:1 classid 1:13 htb rate 35kbit ceil 250kbit prio 3 $IPT -A POSTROUTING -t mangle -o $DEV -p tcp -m length --length :64 -j MARK --set-mark 10 $IPT -A POSTROUTING -t mangle -o $DEV -p udp --dport 53 -j MARK --set-mark 10 $IPT -A POSTROUTING -t mangle -o $DEV -p tcp --dport 22 -j MARK --set-mark 11 $IPT -A POSTROUTING -t mangle -o $DEV -p tcp --sport 22 -j MARK --set-mark 11 $IPT -A POSTROUTING -t mangle -o $DEV -p tcp --dport 6881:6889 -j MARK --set-mark 13 $TC filter add dev $DEV parent 1:0 prio 0 protocol ip handle 10 fw flowid 1:10 $TC filter add dev $DEV parent 1:0 prio 0 protocol ip handle 11 fw flowid 1:11 $TC filter add dev $DEV parent 1:0 prio 0 protocol ip handle 13 fw flowid 1:13 $TC qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10 $TC qdisc add dev $DEV parent 1:11 handle 11: sfq perturb 10 $TC qdisc add dev $DEV parent 1:12 handle 12: sfq perturb 10 $TC qdisc add dev $DEV parent 1:13 handle 13: sfq perturb 10 }}} == Gigabit LAN und 50MBit Uplink ins Internet == Bei dieser Variante wird der [wikipedia_en:Hierarchical_fair-service_curve:HFSC]-Scheduler und [wikipedia_en:Nftables: nftables] verwendet (Vorsicht: entweder '''iptables''' oder '''nftables''', beides zusammen geht nicht!). {{{#!/bin/sh DEV=eth0 TC=/sbin/tc $TC qdisc del dev lo root 2> /dev/null $TC qdisc del dev $DEV root 2> /dev/null $TC qdisc del dev $DEV ingress 2> /dev/null $TC qdisc add dev $DEV root handle 1: hfsc default 10 $TC class add dev $DEV parent 1: classid 1:1 hfsc ls rate 975mbit ul rate 975mbit $TC class add dev $DEV parent 1:1 classid 1:10 hfsc ls rate 850mbit ul rate 975mbit # lan default $TC class add dev $DEV parent 1:1 classid 1:11 hfsc ls rate 75mbit ul rate 975mbit # lan prio $TC class add dev $DEV parent 1:1 classid 1:20 hfsc ls rate 40mbit ul rate 50mbit # wan default $TC class add dev $DEV parent 1:1 classid 1:21 hfsc ls rate 10mbit ul rate 50mbit # wan prio $TC filter add dev $DEV parent 1:1 prio 1 protocol ip handle 10 fw flowid 1:10 $TC filter add dev $DEV parent 1:1 prio 2 protocol ip handle 11 fw flowid 1:11 $TC filter add dev $DEV parent 1:1 prio 3 protocol ip handle 20 fw flowid 1:20 $TC filter add dev $DEV parent 1:1 prio 4 protocol ip handle 21 fw flowid 1:21 $TC qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10 $TC qdisc add dev $DEV parent 1:11 handle 11: sfq perturb 10 $TC qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10 $TC qdisc add dev $DEV parent 1:21 handle 21: sfq perturb 10 }}} Die nftables rules dazu: {{{#!/usr/sbin/nft -f define lan4 = 192.168.1.0/24 define lan6 = { fd00::/8, fe80::/10 } table inet tcnat { chain postrouting { type route hook output priority -150; policy accept; ip daddr != $lan4 jump wan # leite nicht-LAN-traffic ipv4 um ip6 daddr != $lan6 jump wan # leite nicht-LAN-traffic ipv6 um ip daddr $lan4 tcp dport 22 meta priority set 1:11 # priorisiere SSH im LAN ip daddr $lan4 meta length 1-64 meta priority set 1:11 # priorisiere kleine Pakete im LAN } chain wan { tcp dport 22 meta priority set 1:21 return # priorisiere SSH ins Internet meta length 1-64 meta priority set 1:21 return # priorisiere kleine Pakete ins Internet meta priority set 1:20 counter # default ins Internet } } }}} = Links = * Artikel [https://www.linux-magazin.de/ausgaben/2005/02/vordraengler/ Traffic Control mit Linux] {de} Linux Magazin, 2005 (aber immer noch lesenswert) * Alternatives Wiki [https://wiki.openwrt.org/doc/howto/tc Traffic Control] {en}, umfassend und allgemein. Unter CC Attribution-Noncommercial-Share Alike 3.0 Unported-Lizenz. Deutsche Übersetzung möglich/erwünscht. * Dokumentation von Stef Coene [https://www.docum.org/docum.org/ Docum.org] {en}, viele nützliche Tipps, insbesondere hervorzuheben das [https://www.docum.org/docum.org/kptd/ Kernel Packet Traveling Diagram] {en}. * [iawm::][https://web.archive.org/web/20180407181159/http://lartc.org/howto Linux Advanced Routing & Traffic Control HOWTO] {en}, immer noch der beste Gesamtüberblick zur Thematik. Pflichtlektüre für jeden, der sich tiefgehender mit Traffic Shaping befassen will. * [http://linux-ip.net/articles/hfsc.en/ HSFC Scheduling mit Linux] {en}, mächtigere Alternative zum HTB Scheduler # tag: Internet, Netzwerk