Traffic Shaping mit iptables
Beispiel eines Traffic Shaping Scripts auf einem WAR Board von pcengines.com. Dieses Bord hat nur einen Stromverbrauch von ca.6W und bietet 2-3 Ehternet Ports mit einem realen Durchsatz von ca. 80MBit. Damit in beide Richtungen geshapt werden kann, werden mindestens 2 Ethernet Ports benötigt. In diesem Beispiel ist eth3 für den externen Port und eth2 für den internen Port festgelegt.
Im ersten Step werden die Variablen festgelegt:
#!/bin/bash
iptables -F
iptables -X
iptables -t nat -F
iptables -t mangle -F
tc qdisc del dev eth3 root
tc qdisc del dev eth2 root
sleep 1
EXTIF=“eth3″
INTIF=“eth2″
MARKPRIO1=“1″
MARKPRIO2=“2″
MARKPRIO3=“3″
MARKPRIO4=“4″
MARKPRIO5=“5″
MARKPRIO6=“6″
MARKPRIO7=“7″
UPRATE=“100mbit“
DOWNRATE=“100mbit“
P2PRATE=“10kbit“
PRIORATE1=“100mbit“
PRIORATE2=“100mbit“
PRIORATE3=“45mbit“
PRIORATE4=“10mbit“
PRIORATE5=“10mbit“
PRIORATE6=“4mbit“
PRIORATE7=“1mbit“
Im zweiten Step werden die Pakete nach Protokoll und Inhalt markiert:
###### Hier können spezielle Markierungen gesetzt werden (siehe Ende dieses Beitrages)
######
# Prio 1 – absolut wichtig # related Pakete und ICMP
iptables -t mangle -A FORWARD -p icmp -j MARK –set-mark $MARKPRIO1
iptables -t mangle -A FORWARD -p icmp -j RETURN
iptables -t mangle -A FORWARD -p tcp -m length –length 0:128 –tcp-flags SYN,RST,ACK ACK -j MARK –set-mark $MARKPRIO1
iptables -t mangle -A FORWARD -p tcp -m length –length 0:128 –tcp-flags SYN,RST,ACK ACK -j RETURN
# Prio 2 – sollte bevorzugt werden
# DNS
iptables -t mangle -A FORWARD -p udp –dport 53 -j MARK –set-mark $MARKPRIO2
iptables -t mangle -A FORWARD -p udp –dport 53 -j RETURN
iptables -t mangle -A FORWARD -p udp –sport 53 -j MARK –set-mark $MARKPRIO2
iptables -t mangle -A FORWARD -p udp –sport 53 -j RETURN
# Playstation Network und Games
iptables -t mangle -A FORWARD -p tcp -m multiport –dport 26900:27039 -j MARK –set-mark $MARKPRIO2
iptables -t mangle -A FORWARD -p tcp -m multiport –dport 26900:27039 -j RETURN
iptables -t mangle -A FORWARD -p tcp -m multiport –sport 26900:27039 -j MARK –set-mark $MARKPRIO2
iptables -t mangle -A FORWARD -p tcp -m multiport –sport 26900:27039 -j RETURN
#SSH
iptables -t mangle -A FORWARD -p tcp –dport 22 -j MARK –set-mark $MARKPRIO2
iptables -t mangle -A FORWARD -p tcp –dport 22 -j RETURN
iptables -t mangle -A FORWARD -p tcp –sport 22 -j MARK –set-mark $MARKPRIO2
iptables -t mangle -A FORWARD -p tcp –sport 22 -j RETURN
# Prio 3 – normal # HTTP, HTTPS
iptables -t mangle -A FORWARD -p tcp -m multiport –dport 8443,443 -j MARK –set-mark $MARKPRIO3
iptables -t mangle -A FORWARD -p tcp -m multiport –dport 8443,443 -j RETURN
iptables -t mangle -A FORWARD -p tcp -m multiport –sport 8443,443 -j MARK –set-mark $MARKPRIO3
iptables -t mangle -A FORWARD -p tcp -m multiport –sport 8443,443 -j RETURN
iptables -t mangle -A FORWARD -p tcp -m multiport –dport 80:88,8000:8080 -j MARK –set-mark $MARKPRIO3
iptables -t mangle -A FORWARD -p tcp -m multiport –dport 80:88,8000:8080 -j RETURN
iptables -t mangle -A FORWARD -p tcp -m multiport –sport 80:88,8000:8080 -j MARK –set-mark $MARKPRIO3
iptables -t mangle -A FORWARD -p tcp -m multiport –sport 80:88,8000:8080 -j RETURN
# Prio 4 – weniger wichtig – IMAP,POP3,SMTP
iptables -t mangle -A FORWARD -p tcp -m multiport –dport 143,993,110 -j MARK –set-mark $MARKPRIO4
iptables -t mangle -A FORWARD -p tcp -m multiport –dport 143,993,110 -j RETURN
iptables -t mangle -A FORWARD -p tcp -m multiport –sport 143,993,110 -j MARK –set-mark $MARKPRIO4
iptables -t mangle -A FORWARD -p tcp -m multiport –sport 143,993,110 -j RETURN
iptables -t mangle -A FORWARD -p tcp –dport 25 -j MARK –set-mark $MARKPRIO4
iptables -t mangle -A FORWARD -p tcp –dport 25 -j RETURN
iptables -t mangle -A FORWARD -p tcp –sport 25 -j MARK –set-mark $MARKPRIO4
iptables -t mangle -A FORWARD -p tcp –sport 25 -j RETURN
# Prio 5 – Datenuebertragungen # FTP, große Pakete
iptables -t mangle -A FORWARD -p tcp –dport 20:21 -j MARK –set-mark $MARKPRIO5
iptables -t mangle -A FORWARD -p tcp –dport 20:21 -j RETURN
iptables -t mangle -A FORWARD -p tcp –sport 20:21 -j MARK –set-mark $MARKPRIO5
iptables -t mangle -A FORWARD -p tcp –sport 20:21 -j RETURN
iptables -t mangle -A FORWARD -p tcp -m length –length 1024: -m mark –mark 0 -j MARK –set-mark $MARKPRIO5
iptables -t mangle -A FORWARD -p tcp -m length –length 1024: -m mark –mark 0 -j RETURN
# Prio 6 – Usenet Traffic
iptables -t mangle -A FORWARD -p tcp –sport 119 -j MARK –set-mark $MARKPRIO6
iptables -t mangle -A FORWARD -p tcp –sport 119 -j RETURN
iptables -t mangle -A FORWARD -p tcp –dport 119 -j MARK –set-mark $MARKPRIO6
iptables -t mangle -A FORWARD -p tcp –dport 119 -j RETURN
# Prio 7 – spezielle Clients die gedrosselt werden muessen
# Default
iptables -t mangle -A FORWARD -j MARK –set-mark $MARKPRIO4
als dritter Step beginnt jetzt das eigentliche Shaping gestaffelt nach Markierung
# in Downloadrichtung (extern nach intern)
# Burst
BURST1=“6k“
BURST2=“4k“
BURST3=“2k“
BURST4=“1k“
BURST5=“0k“
BURST6=“0k“
BURST7=“0k“
CBURST1=“3k“
CBURST2=“2k“
CBURST3=“1k“
CBURST4=“0k“
CBURST5=“0k“
CBURST6=“0k“
CBURST7=“0k“
# Downloadrichtung – aus Sicht vom Client
# Set queue length for $EXTIF
ifconfig $EXTIF txqueuelen 16
# Specify queue discipline
tc qdisc add dev $EXTIF root handle 1:0 htb default 106 r2q 1
# Set root class
tc class add dev $EXTIF parent 1:0 classid 1:1 htb rate $UPRATE burst $BURST1 cburst $CBURST1
# Specify sub classes
tc class add dev $EXTIF parent 1:1 classid 1:101 htb rate $PRIORATE1 ceil $UPRATE burst $BURST1 cburst $CBURST1 prio 1
tc class add dev $EXTIF parent 1:1 classid 1:102 htb rate $PRIORATE2 ceil $UPRATE burst $BURST2 cburst $CBURST2 prio 2
tc class add dev $EXTIF parent 1:1 classid 1:103 htb rate $PRIORATE3 ceil $UPRATE burst $BURST3 cburst $CBURST3 prio 3
tc class add dev $EXTIF parent 1:1 classid 1:104 htb rate $PRIORATE4 ceil $UPRATE burst $BURST4 cburst $CBURST4 prio 4
tc class add dev $EXTIF parent 1:1 classid 1:105 htb rate $PRIORATE5 ceil $UPRATE burst $BURST5 cburst $CBURST5 prio 5
tc class add dev $EXTIF parent 1:1 classid 1:106 htb rate $PRIORATE6 ceil $P2PRATE burst $BURST6 cburst $CBURST6 prio 6
tc class add dev $EXTIF parent 1:1 classid 1:107 htb rate $PRIORATE7 ceil $P2PRATE burst $BURST7 cburst $CBURST7 prio 7
# Filter packets
tc filter add dev $EXTIF parent 1:0 protocol ip prio 1 handle $MARKPRIO1 fw classid 1:101
tc filter add dev $EXTIF parent 1:0 protocol ip prio 2 handle $MARKPRIO2 fw classid 1:102
tc filter add dev $EXTIF parent 1:0 protocol ip prio 3 handle $MARKPRIO3 fw classid 1:103
tc filter add dev $EXTIF parent 1:0 protocol ip prio 4 handle $MARKPRIO4 fw classid 1:104
tc filter add dev $EXTIF parent 1:0 protocol ip prio 5 handle $MARKPRIO5 fw classid 1:105
tc filter add dev $EXTIF parent 1:0 protocol ip prio 6 handle $MARKPRIO6 fw classid 1:106
tc filter add dev $EXTIF parent 1:0 protocol ip prio 7 handle $MARKPRIO7 fw classid 1:107
# Add queuing disciplines
tc qdisc add dev $EXTIF parent 1:101 sfq perturb 16
tc qdisc add dev $EXTIF parent 1:102 sfq perturb 16
tc qdisc add dev $EXTIF parent 1:103 sfq perturb 16
tc qdisc add dev $EXTIF parent 1:104 sfq perturb 16
tc qdisc add dev $EXTIF parent 1:105 sfq perturb 16
tc qdisc add dev $EXTIF parent 1:106 sfq perturb 16
tc qdisc add dev $EXTIF parent 1:107 sfq perturb 16
# in Uploadrichtung (intern nach extern)
ifconfig $INTIF txqueuelen 16
# Specify queue discipline
tc qdisc add dev $INTIF root handle 1:0 htb default 106 r2q 1
# Set root class
tc class add dev $INTIF parent 1:0 classid 1:1 htb rate $UPRATE burst $BURST1 cburst $CBURST1
# Specify sub classes
tc class add dev $INTIF parent 1:1 classid 1:101 htb rate $PRIORATE1 ceil $DOWNRATE burst $BURST1 cburst $CBURST1 prio 1
tc class add dev $INTIF parent 1:1 classid 1:102 htb rate $PRIORATE2 ceil $DOWNRATE burst $BURST2 cburst $CBURST2 prio 2
tc class add dev $INTIF parent 1:1 classid 1:103 htb rate $PRIORATE3 ceil $DOWNRATE burst $BURST3 cburst $CBURST3 prio 3
tc class add dev $INTIF parent 1:1 classid 1:104 htb rate $PRIORATE4 ceil $DOWNRATE burst $BURST4 cburst $CBURST4 prio 4
tc class add dev $INTIF parent 1:1 classid 1:105 htb rate $PRIORATE5 ceil $DOWNRATE burst $BURST5 cburst $CBURST5 prio 5
tc class add dev $INTIF parent 1:1 classid 1:106 htb rate $PRIORATE6 ceil $P2PRATE burst $BURST6 cburst $CBURST6 prio 6
tc class add dev $INTIF parent 1:1 classid 1:107 htb rate $PRIORATE7 ceil $P2PRATE burst $BURST7 cburst $CBURST7 prio 7
# Filter packets
tc filter add dev $INTIF parent 1:0 protocol ip prio 1 handle $MARKPRIO1 fw classid 1:101
tc filter add dev $INTIF parent 1:0 protocol ip prio 2 handle $MARKPRIO2 fw classid 1:102
tc filter add dev $INTIF parent 1:0 protocol ip prio 3 handle $MARKPRIO3 fw classid 1:103
tc filter add dev $INTIF parent 1:0 protocol ip prio 4 handle $MARKPRIO4 fw classid 1:104
tc filter add dev $INTIF parent 1:0 protocol ip prio 5 handle $MARKPRIO5 fw classid 1:105
tc filter add dev $INTIF parent 1:0 protocol ip prio 6 handle $MARKPRIO6 fw classid 1:106
tc filter add dev $INTIF parent 1:0 protocol ip prio 7 handle $MARKPRIO7 fw classid 1:107
# Add queuing disciplines
tc qdisc add dev $INTIF parent 1:101 sfq perturb 16
tc qdisc add dev $INTIF parent 1:102 sfq perturb 16
tc qdisc add dev $INTIF parent 1:103 sfq perturb 16
tc qdisc add dev $INTIF parent 1:104 sfq perturb 16
tc qdisc add dev $INTIF parent 1:105 sfq perturb 16
tc qdisc add dev $INTIF parent 1:106 sfq perturb 16
tc qdisc add dev $INTIF parent 1:107 sfq perturb 16
fertig!
Das Script kann zum Beispiel als shaping.sh gespeichert und beim starten automatisch ausgeführt werden.
Weitere Tipps:
Schutz gegen DNS DOS (wird auch verwendet bei Scannern). Begrenzt die DNS Anfrage pro IP-Adresse auf 15/sekunde:
iptables -A FORWARD -p udp –dport 53 -m state –state NEW -m recent –set –name DNSQF –rsource
iptables -A FORWARD -p udp –dport 53 -m state –state NEW -m recent –update –seconds 1 –hitcount 15 –name DNSQF –rsource -j MARK –set-mark $MARKPRIO7
Filtern nach Streaminhalten (URL, Filenamen u.ä.). In diesem Beispiel werden Torrent Downloads und der jdoawnloader markiert. Das Ganze unabhängig vom verwendeten Port.
iptables -t mangle -A FORWARD -m string –algo bm –string „BitTorrent“ -j MARK –set-mark $MARKPRIO7
iptables -t mangle -A FORWARD -m string –algo bm –string „BitTorrent“ -j RETURN
iptables -t mangle -A FORWARD -m string –algo bm –string „.torrent“ -j MARK –set-mark $MARKPRIO7
iptables -t mangle -A FORWARD -m string –algo bm –string „.torrent“ -j RETURN
iptables -t mangle -A FORWARD -m string –algo bm –string „jdownloader“ -j MARK –set-mark $MARKPRIO7
iptables -t mangle -A FORWARD -m string –algo bm –string „jdownloader“ -j RETURN