Gestion du traffic dans le réseau avec l'outil tc .

Contexte

On souhaite répartir suivant une priorité choisie la capacité fournie par le FAI. Dans notre cas il s'agit de 10 Mbps en descente. La priorité se fera ainsi par ordre décroissant:

La mise en oeuvre

On va utiliser principalement l'outil de contrôle de traffic tc pour cela. Il faudra, dans notre contexte, ajuster les règles de parefeu également.

Il faut au préalable charger le module ifb et activer l'interface qui sera exploitée

modprobe ifb numifbs=1
ip link set up ifb0

Le script de gestion du traffic

{i} J'ai choisi de placer mes règles dans /usr/local/sbin mais dans le contexte du démarrage je pense que je mettrais ailleurs et ferais un appel dans le fichier d'interface des cartes réseaux.

Voir la carte du réseau au besoin.

{i} Ce qui suit est un seul script mais que je présente par partie afin de mieux commenter.

Initialisation de variables et redirection du traffic émis par nos ressources en interne vers l'interface créée ifb0

IF_INTERNET=eth0.2
IP_PUB_PERSONNEL=195.24.196.119
IP_PUB_NOMADE=195.24.196.123
IP_PUB_BIBLIO=195.24.195.229
IP_PUB_FORMATION=195.24.195.230


#pour supprimer ce qui aurait été fait
tc qdisc del dev $IF_INTERNET ingress
tc qdisc del dev ifb0 root handle 1:

tc qdisc add dev $IF_INTERNET ingress

tc filter add dev $IF_INTERNET parent ffff: protocol ip prio 1 u32 \
        match ip dst 195.24.196.112/28 flowid 1:1 \
        action mirred egress redirect dev ifb0

tc filter add dev $IF_INTERNET parent ffff: protocol ip prio 1 u32 \
        match ip dst 195.24.195.224/29 flowid 1:1 \
        action mirred egress redirect dev ifb0

Mise en place de la queue htb(hierarchy tocken bucket).

Elle nous permet d'allouer une capacité à certaines ressources du réseau sans toutefois confisquer cette capacité si elle venait à ne pas être utilisée.

tc qdisc add dev ifb0 root handle 1: htb default 50

#vous noterez qu'on ne considère pas toute notre bande passante.
tc class add dev ifb0 parent 1: classid 1:1 htb rate 9882kbit ceil 10000kbit

#la DMZ
tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 512kbit ceil 1000kbit prio 1

#la VOIP
tc class add dev ifb0 parent 1:1 classid 1:11 htb rate 256kbit ceil 512kbit prio 1

#les visios
tc class add dev ifb0 parent 1:1 classid 1:12 htb rate 1000kbit ceil 3500kbit prio 2
#dédiée aux personnels
tc class add dev ifb0 parent 1:1 classid 1:13 htb rate 3000kbit ceil 6000kbit prio 3

#la salle de formation
tc class add dev ifb0 parent 1:1 classid 1:14 htb rate 768kbit ceil 3000kbit prio 4

#la bibliothèque + foad
tc class add dev ifb0 parent 1:1 classid 1:15 htb rate 512kbit ceil 5000kbit prio 5

#le réseau nomade
tc class add dev ifb0 parent 1:1 classid 1:16 htb rate 2000kbit ceil 5000kbit prio 6

#le reste
tc class add dev ifb0 parent 1:1 classid 1:50 htb rate 2500kbit ceil 7000kbit prio 6

Mise en place d'une autre queue : sfq : stochastic fairness queue .

En gros elle permet de gérer chaque paquet de manière équitable après avoir pris en compte les priorités émanant des classes créées plus haut.

C'est pour éviter «le premier arrivé, premier servi» :)

for i in 10 11 12 13 14 15 16 50
do
        tc qdisc add dev ifb0 parent 1:$i handle $i: sfq perturb 10
done

Les filtres permettent de placer les paquets dans la classe qu'on souhaite. Il existe une foule de façons de mettre en place les filtres.

On commence par le traffic voip

tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 \
        match ip protocol 17 0xff \
        match ip sport 4569 0xffff flowid 1:11

tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 \
        match ip protocol 17 0xff \
        match ip dport 4569 0xffff flowid 1:11

#ici les visios doivent être gérées dans la classe 1:12
for visio in 124 125 126
do
        tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 \
                match ip dst 195.24.196.$visio/32 flowid 1:12
done
for serveur in 114 116 118
do
        tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 \
                match ip dst 195.24.196.$serveur/32 flowid 1:10
done

#le personnel dans la classe 1:13
tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 \
        match ip dst $IP_PUB_PERSONNEL/32 flowid 1:13

tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 \
        match ip dst $IP_PUB_FORMATION/32 flowid 1:14

tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 \
        match ip dst $IP_PUB_BIBLIO/32 flowid 1:15

tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 \
        match ip dst $IP_PUB_NOMADE/32 flowid 1:16

{i} Absolument tout ce qui ne sera pas pris en compte dans filtres ira dans la classe par défaut 1:50

{*} pour IPv6 avec le sélecteur u32 vous pouvez identifier les adresses avec  u32 match ip6 dst 2001:4268::/48  par exemple.

Quelques stats obtenues

Avec tc vous avez la possibilité d'afficher des statistiques. Ces captures ont été faites au moment où 1 visio était en marche, la seconde de temps en temps et le reste du réseau était plus ou moins sollicité; principalement par le personnel.

Les queues

Avec la commande tc -s qdisc show . vous avez l'aperçu des queues mises en place

root@fw1:~# tc -s qdisc show
qdisc pfifo_fast 0: dev eth0 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
 Sent 430528564453 bytes 536865188 pkt (dropped 0, overlimits 0 requeues 842150) 
 backlog 0b 0p requeues 842150 
qdisc ingress ffff: dev eth0.2 parent ffff:fff1 ---------------- 
 Sent 12624208066 bytes 10169997 pkt (dropped 43805, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc htb 1: dev ifb0 root refcnt 2 r2q 10 default 50 direct_packets_stat 49
 Sent 12583903992 bytes 10032618 pkt (dropped 43805, overlimits 25488225 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 10: dev ifb0 parent 1:10 limit 127p quantum 1514b divisor 1024 perturb 10sec 
 Sent 106961509 bytes 326835 pkt (dropped 714, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 11: dev ifb0 parent 1:11 limit 127p quantum 1514b divisor 1024 perturb 10sec 
 Sent 41979 bytes 534 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 12: dev ifb0 parent 1:12 limit 127p quantum 1514b divisor 1024 perturb 10sec 
 Sent 693854666 bytes 983256 pkt (dropped 0, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 13: dev ifb0 parent 1:13 limit 127p quantum 1514b divisor 1024 perturb 10sec 
 Sent 2187423008 bytes 1788098 pkt (dropped 33299, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 14: dev ifb0 parent 1:14 limit 127p quantum 1514b divisor 1024 perturb 10sec 
 Sent 421981500 bytes 291303 pkt (dropped 961, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 15: dev ifb0 parent 1:15 limit 127p quantum 1514b divisor 1024 perturb 10sec 
 Sent 3553486110 bytes 2491986 pkt (dropped 20065, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 16: dev ifb0 parent 1:16 limit 127p quantum 1514b divisor 1024 perturb 10sec 
 Sent 2486569112 bytes 1845038 pkt (dropped 5269, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0 
qdisc sfq 50: dev ifb0 parent 1:50 limit 127p quantum 1514b divisor 1024 perturb 10sec 
 Sent 3133490429 bytes 2305499 pkt (dropped 38975, overlimits 0 requeues 0) 
 backlog 0b 0p requeues 0

Les classes

Avec tc -s class show dev ifb0 vous avez un aperçu de l'utilisation des classes. Je trouve que ce sont les informations les plus intéressantes.

Pour chaque classe , à la 3è ligne qui commence par rate cela indique au moment de la capture de ces informations, la capacité qui a été employée par la classe.

class htb 1:11 parent 1:1 leaf 11: prio 1 rate 256000bit ceil 512000bit burst 1600b cburst 1600b
 Sent 41979 bytes 534 pkt (dropped 0, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0
 lended: 534 borrowed: 0 giants: 0
 tokens: 671875 ctokens: 335938

class htb 1:10 parent 1:1 leaf 10: prio 1 rate 512000bit ceil 1000Kbit burst 1600b cburst 1600b
 Sent 100416634 bytes 309979 pkt (dropped 287, overlimits 0 requeues 0)
 rate 24200bit 10pps backlog 0b 0p requeues 0
 lended: 283847 borrowed: 25632 giants: 0
 tokens: 373047 ctokens: 191000

class htb 1:1 root rate 9882Kbit ceil 10000Kbit burst 1598b cburst 1600b
 Sent 11659901009 bytes 9190339 pkt (dropped 0, overlimits 0 requeues 0)
 rate 2590Kbit 374pps backlog 0b 0p requeues 0
 lended: 3948213 borrowed: 0 giants: 0
 tokens: 1016 ctokens: 1000

class htb 1:13 parent 1:1 leaf 13: prio 3 rate 3000Kbit ceil 6000Kbit burst 1599b cburst 1599b
 Sent 2136614462 bytes 1709032 pkt (dropped 13775, overlimits 0 requeues 0)
 rate 279480bit 63pps backlog 0b 0p requeues 0
 lended: 1118583 borrowed: 562495 giants: 0
 tokens: 63656 ctokens: 31828

class htb 1:12 parent 1:1 leaf 12: prio 2 rate 1000Kbit ceil 3500Kbit burst 1600b cburst 1599b
 Sent 510655880 bytes 738852 pkt (dropped 0, overlimits 0 requeues 0)
 rate 796824bit 134pps backlog 0b 0p requeues 0
 lended: 563546 borrowed: 175298 giants: 0
 tokens: 178000 ctokens: 50859

class htb 1:15 parent 1:1 leaf 15: prio 5 rate 512000bit ceil 5000Kbit burst 1600b cburst 1600b
 Sent 3491308313 bytes 2447582 pkt (dropped 11865, overlimits 0 requeues 0)
 rate 9776bit 3pps backlog 0b 0p requeues 0
 lended: 387957 borrowed: 2046414 giants: 0
 tokens: 47966 ctokens: 38204
class htb 1:50 parent 1:1 leaf 50: prio 6 rate 2500Kbit ceil 7000Kbit burst 1600b cburst 1598b
 Sent 2831148481 bytes 2078005 pkt (dropped 14544, overlimits 0 requeues 0)
 rate 38008bit 17pps backlog 0b 0p requeues 0
 lended: 1509598 borrowed: 541986 giants: 0
 tokens: 76407 ctokens: 27281

class htb 1:14 parent 1:1 leaf 14: prio 4 rate 768000bit ceil 3000Kbit burst 1599b cburst 1599b
 Sent 422482671 bytes 291614 pkt (dropped 628, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0
 lended: 98729 borrowed: 192399 giants: 0
 tokens: 250000 ctokens: 64000

class htb 1:16 parent 1:1 leaf 16: prio 6 rate 2000Kbit ceil 5000Kbit burst 1600b cburst 1600b
 Sent 2247777791 bytes 1668344 pkt (dropped 578, overlimits 0 requeues 0)
 rate 1455Kbit 148pps backlog 0b 7p requeues 0
 lended: 1252643 borrowed: 403989 giants: 0
 tokens: -51965 ctokens: -37634

class sfq 16:4f parent 16:
 (dropped 0, overlimits 0 requeues 0)
 backlog 9342b 7p requeues 0
 allot -208

Les filtres

filter parent 1: protocol ip pref 1 u32
filter parent 1: protocol ip pref 1 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:11  (rule hit 9259642 success 533)
  match 00110000/00ff0000 at 8 (success 805373 )
  match 11d90000/ffff0000 at 20 (success 533 )
filter parent 1: protocol ip pref 1 u32 fh 800::801 order 2049 key ht 800 bkt 0 flowid 1:11  (rule hit 9259106 success 1)
  match 00110000/00ff0000 at 8 (success 804840 )
  match 000011d9/0000ffff at 20 (success 1 )
filter parent 1: protocol ip pref 1 u32 fh 800::802 order 2050 key ht 800 bkt 0 flowid 1:12  (rule hit 9259103 success 194)
  match c318c47c/ffffffff at 16 (success 194 )
filter parent 1: protocol ip pref 1 u32 fh 800::803 order 2051 key ht 800 bkt 0 flowid 1:12  (rule hit 9258903 success 676884)
  match c318c47d/ffffffff at 16 (success 676884 )
filter parent 1: protocol ip pref 1 u32 fh 800::804 order 2052 key ht 800 bkt 0 flowid 1:12  (rule hit 8582018 success 62197)
  match c318c47e/ffffffff at 16 (success 62197 )
filter parent 1: protocol ip pref 1 u32 fh 800::805 order 2053 key ht 800 bkt 0 flowid 1:10  (rule hit 8519819 success 111364)
  match c318c472/ffffffff at 16 (success 111364 )
filter parent 1: protocol ip pref 1 u32 fh 800::806 order 2054 key ht 800 bkt 0 flowid 1:10  (rule hit 8408450 success 25826)
  match c318c474/ffffffff at 16 (success 25826 )
filter parent 1: protocol ip pref 1 u32 fh 800::807 order 2055 key ht 800 bkt 0 flowid 1:10  (rule hit 8382624 success 173032)
  match c318c476/ffffffff at 16 (success 173032 )
filter parent 1: protocol ip pref 1 u32 fh 800::808 order 2056 key ht 800 bkt 0 flowid 1:13  (rule hit 8209592 success 1714118)
  match c318c477/ffffffff at 16 (success 1714118 )
filter parent 1: protocol ip pref 1 u32 fh 800::809 order 2057 key ht 800 bkt 0 flowid 1:14  (rule hit 6495469 success 292089)
  match c318c3e6/ffffffff at 16 (success 292089 )
filter parent 1: protocol ip pref 1 u32 fh 800::80a order 2058 key ht 800 bkt 0 flowid 1:15  (rule hit 6203377 success 2454242)
  match c318c3e5/ffffffff at 16 (success 2454242 )
filter parent 1: protocol ip pref 1 u32 fh 800::80b order 2059 key ht 800 bkt 0 flowid 1:16  (rule hit 3749133 success 1658843)
  match c318c47b/ffffffff at 16 (success 1658843 )

Il y a encore des ajustements à faire mais c'est déjà un bon début :) . Il y a tellement de possibilités qui s'offrent à nous avec tc.

Il me reste à parler du cas du NAT :D

Sources


  1. C'est à dire le complémentaire de ce que je n'ai pas pris en compte explicitement ou implicitement; c'est très important :) . Autrement dit, tout ce que vous n'aurez pas pris en compte sera traitée dans la classe par défaut (1)