Faire de la QoS sur un Pont réseau avec la commande tc sous Debian

Intro

Voici une technique pour faire de la QoS sur un réseau existant.

La première chose à faire est de mesurer la bande passante de son lien wan. Ensuite nous ajouterons un Pont réseau Debian juste avant notre accès wan.

L'exemple suivant montrera un cas concret dans lequel l'accès vers une ip précise (ici : 169.254.18.10) devra être prioritaire sur les autres flux.

Configuration

Installation

Bridge

Nous installons ici le paquet bridge-utils qui nous fournira les utilitaires destinés à configurer notre pont Ethernet.

root@host:~# apt-get install bridge-utils

Nom des Interfaces

Non obligatoire, mais pour une meilleure visibilité nous changeons le nom de nos interfaces réseau en lan et wan.

root@host:~# vi /etc/udev/rules.d/70-persistent-net.rules
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="b4:83:dc:c2:c4:b8", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="enp*", NAME="lan"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="a8:1b:11:c4:c2:2e", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="enp*", NAME="wan"

Configuration des interfaces

On paramètre le "permanent bridge" et on demande à lancer le script /usr/local/sbin/iptables.sh une fois notre interface br0 active.

root@host:~# vi /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo br0
iface lo inet loopback

iface lan inet manual

iface wan inet manual

iface br0 inet static
bridge_ports lan wan
        address 10.0.0.10
        broadcast 10.0.0.255
        netmask 255.255.255.0
        gateway 10.0.0.254
        up /usr/local/sbin/iptables.sh

QoS script

Notre script QoS. Ici notre lien wan a les caractéristiques suivante : 1Mo/s=8Mbit/s=8192kbit/s en upload/download (SDSL).

Nous attriburons de 5500kbit à 7040kbit pour le traffic concernant 169.254.18.10 (en upload et download).

Tous les autres flux auront de 800kbit à 2048kbit. Enfin, je garde de la bande passante pour le traffic ssh pour pouvoir être en mesure d'administrer le bridge.

/usr/local/sbin/iptables.sh

#!/bin/sh
#iptables reset
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

#commands
TC=/usr/bin/tc
IP=/usr/bin/ip

# load modules
modprobe ifb numifbs=2
modprobe sch_fq_codel
modprobe act_mirred
modprobe br_netfilter #in order to netfilter aware about bridge traffic

#QoS reset
for IFB in ifb0 ; do
        $IP link set dev $IFB down
done

for IF in wan ifb0 lan ; do
        $TC qdisc del dev $IF root    2> /dev/null > /dev/null
        $TC qdisc del dev $IF ingress 2> /dev/null > /dev/null
done

iptables -t mangle -F

for IFB in ifb0 ; do
        $IP link set dev $IFB up
done

modemif=wan

#iptables rules if needed
#iptables -t mangle -A POSTROUTING -o $modemif -p tcp -m tos --tos Minimize-Delay -j CLASSIFY --set-class 1:10
#iptables -t mangle -A POSTROUTING -o $modemif -p tcp --dport 53 -j CLASSIFY --set-class 1:10
#iptables -t mangle -A POSTROUTING -o $modemif -p tcp --dport 80 -j CLASSIFY --set-class 1:10
#iptables -t mangle -A PREROUTING -s tcp --dport 443 -j CLASSIFY --set-class 1:10

##############
#UPLOAD RULES#
##############
#RULES
tc qdisc add dev $modemif root handle 1: htb default 10
tc class add dev $modemif parent 1: classid 1:1 htb rate 7600kbit ceil 7600kbit #800kbit #ceil 1500kbit # burst 10k
tc class add dev $modemif parent 1:1 classid 1:10 htb rate 800kbit ceil 2048kbit prio 2 # ceil 2000kbit prio 3 # burst 10k
tc class add dev $modemif parent 1:1 classid 1:12 htb rate 5500kbit ceil 7040kbit prio 1 #ceil 300kbit prio 1
tc class add dev $modemif parent 1:1 classid 1:13 htb rate 80kbit ceil 200kbit prio 3 #ceil 300kbit prio 2

#FILTERS
tc filter add dev $modemif protocol ip parent 1:0 prio 2 u32 match ip sport 22 0xffff flowid 1:13 #ssh traffic
tc filter add dev $modemif protocol ip parent 1:0 prio 2 u32 match ip dport 22 0xffff flowid 1:13 #ssh traffic
tc filter add dev $modemif protocol ip parent 1:0 prio 1 u32 match ip dst 169.254.18.10/32 flowid 1:12  #remote traffic 

## Martin Devera, author of HTB, then recommends SFQ for beneath these classes:
tc qdisc add dev $modemif parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $modemif parent 1:12 handle 20: sfq perturb 10
tc qdisc add dev $modemif parent 1:13 handle 30: sfq perturb 10

################
#DOWNLOAD RULES#
################
#Create ingress on external interface
tc qdisc add dev wan ingress handle ffff:
#Forward all ingress traffic to the IFB device
tc filter add dev wan parent ffff: protocol all u32 match u32 0 0 action mirred egress redirect dev ifb0

#RULES
tc qdisc add dev ifb0 root handle 2: htb default 10
tc class add dev ifb0 parent 2: classid 2:1 htb rate 7600kbit ceil 7600kbit
tc class add dev ifb0 parent 2:1 classid 2:10 htb rate 800kbit ceil 2048kbit prio 3
tc class add dev ifb0 parent 2:1 classid 2:12 htb rate 5500kbit ceil 7040kbit prio 1
tc class add dev ifb0 parent 2:1 classid 2:13 htb rate 80kbit ceil 200kbit prio 2

#FILTERS
tc filter add dev ifb0 protocol ip parent 2:0 prio 1 u32 match ip src 169.254.18.10/32 flowid 2:12  #traffic 
tc filter add dev ifb0 protocol ip parent 2:0 prio 2 u32 match ip sport 22 0xffff flowid 2:13    #ssh traffic 
tc filter add dev ifb0 protocol ip parent 2:0 prio 2 u32 match ip dport 22 0xffff flowid 2:13    #ssh traffic

Commandes utiles

root@host:~# tc -s class ls dev wan
root@host:~# tc -s qdisc ls dev wan
root@host:~# tc qdisc show
root@host:~# tc qdisc show dev wan
root@host:~# tc filter show dev wan
root@host:~# tc qdisc del dev wan root

Source : https://www.funtoo.org/Traffic_Control ; Gentoo Wiki

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :