QoS/Gestion de la bande passante sous Linux
Transcription
QoS/Gestion de la bande passante sous Linux
QoS/Gestion de la bande passante so QoS/Gestion de la bande passante sous Linux par julien Lecubin Introduction Dans cet article, je vais vous expliquer les différentes étapes pour mettre en place la QoS et gérer votre bande passante sous Linux. Pourquoi faire de la QoS ? Retenez que sans la QoS, vous ne pouvez pas gérer correctement les flux qui transitent sur votre réseau. Vous aurez par exemple des problèmes à écouter un flux audio en streaming sachant qu'en même temps, vous êtes en train de faire du ftp. Dans la première partie de cet article, je vais vous montrer comment prioriser les divers flux de votre réseau. Pourquoi gérer la BP de mon réseau ? Une personne qui fait du ftp sur une ligne ADSL de bureau peut monopoliser à elle seule toute la bande passante en sortie de votre réseau. Ce cas ne se limite pas aux réseaux ADSL et peut être aussi constaté sur des réseaux à très haut débit (lignes de type T1/T2). Linux peut apporter une solution efficace face à ce genre de problème en vous offrant la possibilité de gérer intelligemment votre bande passante. Ce sera le sujet de la deuxième partie de ce présent document. Actuellement, sachez que vous pouvez faire de la QoS et de la gestion de bande passante sous les noyaux 2.2 et 2.4. Néamoins, pour une question de facilité, je vous recommande un noyau 2.4 pour effectuer ce qui suit. QoS via iptables Pour faire de la QoS, nous allons modifier la valeur du champs TOS se situant dans l'en tête IP grâce à iptables. Le champ TOS est sur 4 bits : HEXA BINAIRE DECIMAL SIGNIFICATION 0x10 1000 8 Minimize Delay 0x08 0100 4 Maximize throughput 0x04 0010 2 Maximize reliability 0x02 0001 1 Minimize monetary cost 0x00 0000 0 Normal • Minimize−Delay : Améliore la réactivité des connexions en réduisant le délai (ssh, telnet, ftp contrôle, tftp, flux DNS UDP) • Maximize−Throughput : Améliore le débit au prix d'une possible détérioration de l'interactivité de la session. Les temps de latence ne sont pas importants (ftp−data,www, transfert de zone DNS) • Maximum−Reliability : Certitude que les données arrivent sans perte − Améliore la fiabilité (snmp, smtp) • Minimize monetary cost : minimise le délai, meilleure rentabilité (nntp, icmp) L'intêret de la QoS sous Linux est très souvent associé à la priorisation de flux interactifs via iptables. Par exemple, vous ne souhaitez pas que votre session ssh soit interrompue à cause d'un utilisateur qui est en train de monopoliser la bande passante de votre réseau en downloadant une bande annonce sur internet (Il s'agit d'un cas de figure bien plus répandu qu'on ne le pense !). Nous allons ici à titre d'exemple optimiser les trafics courants avec iptables, à savoir le ftp et ssh : # Priorisation des connexions ftp et ssh iptables −A PREROUTING −t mangle −p tcp −−sport ssh −j TOS −−set−tos Minimize−Delay iptables −A PREROUTING −t mangle −p tcp −−sport ftp −j TOS −−set−tos Minimize−Delay # On donne un maximum de débit aux transferts ftp, peu importe la latence iptables −A PREROUTING −t mangle −p tcp −−sport ftp−data −j TOS −−set−tos Maximize−Throughput A vous d'adapter ce script suivant les services de votre réseau que vous souhaitez prioriser. Gestion de la bande passante sous Linux Nous abordons la deuxième partie du document. Linux utilise deux unités du contrôle de trafic pour la gestion de la bande passante : • Les filtres qui placent le trafic dans les files d'attentes (fwmark, u32) • Les files d'attentes qui décident des flux prioritaires (CBQ, HTB, RED, TBF, SFQ...) Gardez en vue que le protocole TCP/IP n'a pas d'aptitude à connaître les performances d'un réseau. Il commence à envoyer des paquets, de plus en plus rapidement et quand des paquets commencent à se perdre, il ralentit. La plupart des files d'attentes fonctionnent selon le modèle suivant : elles recoivent des paquets, les positionnent en file d'attente jusqu'à un certain point, et ensuite, éliminent tout paquet qui arrive dans le cas où la file d'attente est pleine. Si on travaille en UDP, les paquets ne sont plus retransmis, si c'est du TCP, l'émetteur renverra les paquets perdus. Le débit s'en trouve alors ralenti. Compilation du noyau Nous allons compiler le noyau afin que celui−ci sache gérer notre BP ( = Bande Passante). Si vous avez une ditribution récente, il se peut que vous n'ayez pas besoin de le compiler. Lancez un "make xconfig" sous le X dans le répertoire /usr/src/linux. Si cela ne marche pas, installez les sources du noyau (le rpm est du type kernel−src−*.rpm) 1 Les options Les options Dans la partie "Networking Options" −> "QoS and fair queuing" : Option Noyau Sélection à la Compilation QoS &fair queuing oui Netfilter module Network Packet Filtering CBQ packet scheduler module (Classed Based Queue) − file d'attente basée sur des classes. C'est ce type de file d'attente qui sera implémentée dans la suite du présent document HTB packet scheduler module (Hierarchical Token buckets) implémenté dans la suite du présent document − Si vous ne l'avez pas, j'explique plus bas comment avoir cette file d'attente en patchant votre noyau CSZ packet scheduler module (Clark−Shenker−Zhang) − Les flux ne sont pas limités à leur bande passante. Fournit un service garanti The simplest PRIO pseudoscheduler module RED queue module (Random Early Detect) − Anticipe les problèmes de congestion. RED élimine les paquets pour indiquer à TCP/IP de ralentir − Pour de gros débits SFQ queue module (Stochastic Fair Queuing) − Limitation basée sur le taux de transfert utilisé − Consomme peu de CPU/Mem. Rapide, peu précis. Efficace sur de gros débits − Offre un traitement sensiblement équitable de chaque classe Ingress QDisc module (Queuing discipline) − Indispensable lorsque l'on souhaite utiliser les files d'attente QoS support oui Rate estimator oui Packet classifier API oui TC Index classifier module Routing table based classifier module Définition Firewall based classifier module U32 classifier module Special RSVP classifier module Special RSVP classifier module for IPv6 Les files d'attentes les plus importantes sont CBQ et HTB (la suite du document se base sur ces deux files d'attente). Vous n'êtes pas obligé de mettre en module les autres files d'attentes (CSZ, RED, SFQ, TBF, TEQL), cependant, cela reste toujours intéressant de les laisser en tant que module au cas où vous en auriez besoin plus tard. Terminer la compilation Compilez le noyau par : • make dep • make clean • make bzImage • make modules • make modules_install Ensuite : Allez prendre un café Toujours pas fini ? Retournez prendre un café... :) cp /usr/src/linux/arch/i386/boot/bzImage /boot/vmlinuz cp /usr/src/linux/arch/i386/boot/System.map /boot Modifiez /etc/lilo.conf pour prendre en compte le nouveau noyau et lancez la commande "lilo". Assurez−vous enfin que votre station Linux comporte la commande "tc" (un "which tc" vous permettra de voir si "tc" est installé). Si vous ne l'avez pas, elle fait partie du package iproute2 (les sources sont ici et le rpm peut être téléchargé là) Désormais, votre noyau linux implémente la gestion de bande passante. Il ne reste plus qu'à écrire un script propre à votre config, ce qui est décrit dans la suite du document. Scripts de gestion de bande passante CBQ.init, HTB.init et wshaper.htb Si vous souhaitez partager votre bande passante sans trop vous compliquer la vie, sachez que des scripts on été créés afin d'optimiser votre bande passante. Dans la suite du document, je vais vous expliquer comment les mettre en place. Lisez bien la définition de chacun de ces scripts, de manière à définir celui qui vous convient le mieux. 2 CBQ.init CBQ.init : file d'attente CBQ • convient à de petits débits • nécessite de connaître la taille moyenne des paquets et la vitesse maximale de la connexion • utilise le temps d'inactivité de la connexion pour calculer une approximation du débit utilisé. HTB.init : file d'attente HTB • convient à des gros débits • consomme peu de ressources • ne fait pas d'approximation en ce qui concerne le calcul du débit • nécessite de connaitre le débit maximal de votre connexion. Wondershaper : file d'attente HTB • maintient une bonne réactivité pour le traffic interactif (ssh, telnet...) • surfer sans souci lors de gros downloads • s'assure que l'upload ne défavorise pas le download et inversement. Remarque : Sachez que souvent, on préconise l'utilisation de files d'attentes de type HTB plutot que CBQ. Cependant, si votre distribution n'est pas très récente, il y aura pas mal de choses à réaliser pour implémenter les files d'attentes HTB sur votre station (j'explique neanmoins la démarche à suivre si vous êtes dans ce cas). CBQ.init Récupérez le script à l'adresse suivante : https://sourceforge.net/projects/cbqinit Faites un "chmod u+x CBQ.init*" afin de le rendre executable. Copiez le script dans le répertoire /usr/bin : "cp CBQ.init−[VERSION] /usr/bin" Créez le répertoire /etc/sysconfig/cbq qui contiendra les options de gestion de BP sur lequelles se basera le script : "mkdir /etc/sysconfig/cbq" − Si vous souhaitez placer vos fichiers de configurations CBQ ailleurs, modifiez la variable $CBQ_PATH dans le script CBQ.init afin de renseigner le nouveau chemin. Exemples de fichiers de configurations pour le script CBQ.init : Les fichiers de configuration doivent respecter une syntaxe précise de type cbq−CLASS_ID.name où CLASS_ID est compris en hexa entre 0002 et FFFF (pour en savoir plus, editez le script, c'est expliqué en détail). Exemple 1 : $CBQ_PATH/cbq−1280.My_first_shaper − vous avez 2 interfaces (eth0=LAN et eth1=INTERNET) sur votre machine et souhaitez limiter le trafic INTERNET −> LAN à 16 Ko/s DEVICE=eth0,10Mbit,1Mbit # 10 Mbits −> debit max de votre interface eth0 RATE=128Kbit # Exprimez les valeurs en Kbit ou Mbit selon les débits spécifiés WEIGHT=10Kbit # WEIGHT = RATE / 10 PRIO=5 # Va de 1 à 8 , 1 etant le + prioritaire (la valeur 5 est recommandée et suffisante pour prioriser un traffic spécifique) RULE=192.168.1.0/24 Exemple 2 : $CBQ_PATH/cbq−1280.My_second_shaper − vous avez 1 interface sur votre machine (eth0−192.168.1.5) et souhaitez limiter le trafic MACHINE −> INTERNET à 16 Ko/s DEVICE=eth0,10Mbit,1Mbit # La limite du traffic s'effectue sur l'interface 10 Mbits/s eth0 RATE=128Kbit WEIGHT=10Kbit PRIO=5 RULE=192.168.1.5, # Attention à la ',' cela permet de specifier qu'il s'agit d'une d'adresses source ! Ici, la limitation de BP s'applique uniquement à la machine 192.168.1.5 Exemple 3 : $CBQ_PATH/cbq−1280.My_third_shaper − vous souhaitez limiter le traffic de votre serveur web (192.168.1.50) à 8 Ko/s DEVICE=eth0,10Mbit,1Mbit # 10 Mbits −> debit max de l'interface de votre serveur web RATE=64Kbit # Exprimez les valeurs en Kbit ou Mbit selon les débits spécifiés WEIGHT=6Kbit # WEIGHT = RATE / 10 PRIO=5 # Va de 1 à 8 , 1 etant le + prioritaire (la valeur 5 est recommandée et suffisante pour prioriser un traffic spécifique) RULE=192.128.1.50:80, Exemple 4 : $CBQ_PATH/cbq−1280.My_fourth_shaper − vous souhaitez limiter le traffic des gens qui download sur votre serveur ftp (192.168.1.50) à 10 Ko/s DEVICE=eth0,10Mbit,1Mbit # 10 Mbits −> debit max de l'interface de votre serveur ftp RATE=80Kbit # Exprimez les valeurs en Kbit ou Mbit selon les débits spécifiés WEIGHT=8Kbit # WEIGHT = RATE / 10 PRIO=5 # Va de 1 à 8 , 1 etant le + prioritaire (la valeur 5 est recommandée et suffisante pour prioriser un traffic spécifique) 3 HTB.init RULE=192.128.1.50:20/0xfffe # limitation de BP appliquée sur port 20/21 Exemple 5 : $CBQ_PATH/cbq−1280.My_fifth_shaper − vous souhaitez que le traffic LAN −> INTERNET soit limité à 50 Ko/s (400 Kbits/s), et que le traffic INTERNET −> LAN soit limité à 10Ko/s (80 Kbits/s), remplissez CBQ.init de la manière suivante : LAN −−−−− eth0 [LINUX] eth1 −−−−− INTERNET ######################## {{ LAN −> INTERNET }} #################################### DEVICE=eth1,10Mbit,1Mbit RATE=400Kbit WEIGHT=40Kbit # WEIGHT = RATE / 10 PRIO=5 BOUNDED=yes # Pour ne pas aller prendre de la BP aux classes parents ISOLATED=NO # Permet de léguer de la BP aux classes filles si il en reste RULE=192.168.0.0/24 # Le partage de BP concerne le traffic a destination du reseau 192.168.0.0 ############################################################ ############ ######################## {{ INTERNET −> LAN }} #################################### DEVICE=eth0,100Mbit,10Mbit # RATE=80Kbit # On souhaite limiter le traffic entrant à 10 Ko/s (adaptez selon le debit de votre ligne) WEIGHT=8Kbit # WEIGHT = RATE / 10 PRIO=5 BOUNDED=yes ISOLATED=NO RULE=80,192.168.1.10 # Tout le traffic HTTP INTERNET −> 192.168.1.10 limité à 10 Ko/s #################################### #################################### Il ne reste plus qu'à lancer le script CBQ.init à chaque démarrage ; pour cela éditez le /etc/rc.d/rc.local et ajoutez la ligne "CBQ.init−[version] start" où [version] désigne la version de votre script CBQ. Si vous souhaitez obtenir des statistiques CBQ, lancez la commande "CBQ.init−[VERSION] stats". Le script vous sortira des informations qui peuvent s'avérer utile. Voilà, vous êtes désormais un gourou des files d'attentes CBQ :). Passons maintenant à la gestion de la BP avec file d'attentes HTB. HTB.init Récupérez le script HTB.init à l'adresse suivante : http://sourceforge.net/projects/htbinit Notes pour noyau < 2.4.18−3 : pour utiliser des files d'attentes HTB, sachez que vous devez patcher votre noyau si il est inférieur à la version 2.4.18−3 (tapez "uname −a" pour vérifier la version de votre distribution) : http://luxik.cdi.cz/~devik/qos/htb/v2/htb2_2.4.17.diff pour les noyaux 2.4 http://luxik.cdi.cz/~devik/qos/htb/v2/htb2_2.2.17.diff pour les noyaux 2.2 Pour appliquer le patch lancez la commande suivante dans le répertoire /usr/src/linux : "patch −pl −i htb2_2.4.17.diff" Dans /usr/src/linux tapez : "make xconfig" Dans la partie "Networking Options" −> "QoS and fair Queuing", selectionnez HTB packet scheduler en module Recompilez le noyau : "make dep &make clean &make bzImage &make modules &make modules_install" Mettez en place le nouveau noyau qui prend en charge HTB : cp /usr/src/linux/arch/i386/bzImage /boot/vmlinuz cp /usr/src/linux/arch/i386/boot/System.map /boot Vous devez aussi mettre à jour la commande "tc" : http://luxik.cdi.cz/~devik/qos/htb/v2/tc.gz Faites un "chmod u+x HTB.init−[VERSION]" afin de le rendre executable. Copiez le script dans le répertoire /usr/bin : "cp HTB.init−[VERSION] /usr/bin" Créez le répertoire /etc/sysconfig/htb qui contiendra les fichiers de gestion de BP sur lequelles se basera le script : "mkdir /etc/sysconfig/htb" − Si vous souhaitez placer vos fichiers de configurations HTB ailleurs, modifiez la variable $HTB_PATH dans le script HTB.init afin de renseigner le nouveau chemin. Exemples de fichiers de configurations HTB.init : Il n'existe pas un mais plusieurs fichiers de configurations pour HTB.init. Les fichiers doivent obligatoirement avoir une syntaxe précise. Par exemple : eth0−2 −> classe root ID 2, device eth0 eth0−2:3 −> classe fille ID 3, ayant comme parent 2, device eth0 eth0−2:3:4 −> classe fille ID 4, ayant comme parent 3, device eth0 eth1−2.root −> classe root ID 2, device eth1 Remarque : Une autre notation en cas d'erreur lors de la creation de ce type de fichiers : eth0−2\:3 −> Vous placez un "\" avant le ":" Cela peut paraître un peu confu comme syntaxe, cependant, je vais vous donner des exemples. Editez le script si vous souhaitez néanmoins en savoir plus à ce sujet. Avec ce type de files d'attentes, vous ne pouvez realiser un contrôle de flux qu'en sortie de vos interfaces réseaux. Dans le cas d'une station qui fait du routage, configurez les débits sur les sorties des deux interfaces (voir exemple 2). 4 HTB.init Exemple 1 : Imaginons que vous ayez une bande passante sur votre station de 5 Mbits/s (~600Ko/s). Vous souhaitez : 5Mbits/s pour le HTTP, 3Mbits/s pour le SMTP 1Kbit/s pour le traffic divers (qui vous importent peu) Dans le cas où il y a de la bande passante de libre, vous souhaitez la partager entre le SMTP et traffics divers. SMTP pourra utiliser tout le temps au moins 3Mbits/s et pourra monter jusqu'à 5 Mbits/s si il y a de la BP de libre. Le traffic divers pourra utiliser tout le temps au moins 1Kbit/s et pourra monter jusqu'à 5Mbits/s si il y a de la BP de libre. Allez dans le répertoire /etc/sysconfig/htb ($HTB_PATH) et placez−y les lignes suivantes pour chaque fichier : fichier eth0 DEFAULT=30 # ID class default − Le traffic non répertorié utilisera la class ID 30 fichier eth0−2.root RATE=5Mbit # Bande passante allouée a la classe root (ici 5Mbits) BURST=15k fichier eth0−2:10.www RATE=5Mbit BURST=15k LEAF=sfq # Type de file d'attente utilisée par cette classe (ici sfq) RULE=*:80, # Voir les exemples du script CBQ.init − La syntaxe "RULE" est identique fichier eth0−2:20.smtp RATE=3Mbit CEIL=5Mbit # La bande passante max de cette classe peut aller jusqu'a 5 Mbits/s uniquement si il y a de la BP de libre. BURST=15k LEAF=sfq RULE=*:25 fichier eth0−2:30.dfl RATE=1Kbit CEIL=5Mbit BURST=15k LEAF=sfq Exemple 2 : On traite ici le cas d'une personne ayant une connexion ADSL de type 512/128. Sa connexion se fait via une machine−routeur possédant deux interfaces (eth0 et eth1). Elle souhaite limiter l'upload à 90 Kbits/s (11,3 Ko/s) et donner la priorité aux services HTTP, SSH, TELNET, POP3, SMTP et DNS. Une priorité plus petite sera attribuée à tout autre traffic. Côté, download on garde la même idée, cependant, la limite sera fixée à 450 Kbits/s (57 Ko/s). Allez dans le répertoire /etc/sysconfig/htb ($HTB_PATH) et placez−y les lignes suivantes pour chaque fichier : fichier eth1 (Tous fichier de type eth1* −> traffic sortant de l'interface eth1) DEFAULT=30 R2Q=1 fichier eth1−2.root #Classe root pour traffic sortant RATE=90Kbit fichier eth1−2\:10.high # Classe pour traffic sortant de haute priorité RATE=30Kbit CEIL=prate LEAF=sfq #HTTP RULE=*:80 #SSH RULE=*:22 #TELNET RULE=*:23 #SMTP RULE=*:25 #DNS RULE=*:53 #POP3 RULE=*:110 5 wondershaper fichier eth1−2\:20.normal # Classe pour traffic sortant normal RATE=30kbit CEIL=prate LEAF=sfq #IRC RULE=*:6667 fichier eth1−2\:30.low # Classe pour traffic sortant peu important RATE=20Kbit CEIL=prate LEAF=sfq #EMULE RULE=*:3000 RULE=*:3000, RULE=*:3010 RULE=*:3010, RULE=*:4662 RULE=*:4662, fichier eth0 (Tous fichier de type eth0* −> traffic sortant de l'interface eth0) DEFAULT=30 R2Q=10 fichier eth0−2\:10.high # Classe pour traffic sortant de haute priorité RATE=150 Kbit CEIL=prate LEAF=sfq #HTTP RULE=*:80, #SSH RULE=*:22, #TELNET RULE=*:23, #SMTP RULE=*:25, #DNS RULE=*:53, #POP3 RULE=*:110, fichier eth0−2\:20.normal # Classe pour traffic sortant normal RATE=30kbit CEIL=prate LEAF=sfq #IRC RULE=*:6667, fichier eth0−2\:30.low # Classe pour traffic sortant peu important RATE=150Kbit CEIL=prate LEAF=sfq #EMULE RULE=*:3000, RULE=*:3010, RULE=*:4662, RULE=*:3000 RULE=*:3010 RULE=*:4662 RULE=*:4662 RULE=*:4662, Il ne reste plus qu'à lancer le script HTB.init à chaque démarrage ; pour cela éditez le /etc/rc.d/rc.local et ajoutez la ligne "HTB.init−[version] start" où [VERSION] désigne la version de votre script HTB. Si vous souhaitez obtenir des statistiques HTB, lancez la commande "HTB.init−[VERSION] stats". Le script vous sortira des informations qui peuvent s'avérer utile. wondershaper Récupérez wondershaper à l'adresse suivante : 6 wondershaper http://lartc.org/wondershaper Editez le script wshaper et indiquez les débits ; par exemple pour une ligne ADSL 512/128 : DOWNLINK= 500 UPLINK= 100 DEV=ppp0 Désormais, votre machine avec ce script : • maintient une bonne réactivité pour le traffic interactif (ssh, telnet...) • vous pouvez surfer sans soucis lors de gros downloads • l'upload ne défavorise pas le download et inversement. J'ai trouvé sur internet un script dérivé de Wondershaper, il peut s'avérer intéressant de le mettre en oeuvre si vous avez une connexion de type ADSL. En revanche, ce script fait appel à de nombreuses files d'attentes : CBQ, RED, IMQ, HTB et SFQ (Assurez−vous au préalable que votre noyau les prend toutes en compte). #!/bin/bash # # mon_limiteur − Limiteur et classificateur de trafic pour modem Cable ou ADSL. # Inspiré de WonderShaper (www.lartc.org) # # Écrit par Dan Singletary (7/8/02) # # Remarque − ce script suppose que le noyau a été patché avec les files # HTB et IMQ disponibles ici (les noyaux à venir ne demanderont # pas forcément l'application d'un correctif): # http://luxik.cdi.cz/~devik/qos/htb/ # http://luxik.cdi.cz/~patrick/imq/ # # Options de configuration pour mon_limiteur: # DEV − correspond au périphérique ethX connecté au modem # RATEUP − à positionner à une valeur inférieure à la bande # passante montante de la ligne. # Pour ma ligne ADSL en 1500/128, RATEUP=90 convient au rythme # montant de 128 kbps. À vous d'ajuster. # RATEDN − à positionner en dessous de la bande passante descendante de # la ligne. # # # Principe d'utilisation d'imq pour limiter le trafic entrant: # # Il est impossible de limiter directement le rythme auquel les # données vous sont envoyées depuis l'Internet. Afin de limiter le # trafic entrant, on s'appuie sur les mécanismes anti−congestion de # TCP. Ceci signifie que SEUL LE TRAFIC TCP PEUT SE LIMITER. Le # trafic hors TCP est placé dans une queue prioritaire car le jeter # ne conduit vraisemblablement qu'à une retransmission ultérieure # qui accroît la bande passante consommée. # On limite le trafic TCP en jetant les paquets lorsqu'ils débordent # de la file HTB qui les limitera à un certain rythme (RATEDN) # légèrement inférieur à la capacité réelle de la ligne. Jeter ces # paquets revient à en singer la perte par la file d'émission du # côté du FAI. Ceci a l'avantage d'éviter la congestion de la file # d'émission chez le FAI puisque TCP ralentira avant qu'elle ne # se remplisse. L'usage d'une stratégie de mise en attente basée sur # la classification des paquets par priorité permet de ne PAS jeter # certains types de paquets (ssh, telnet, etc). Les paquets ne sont # retirés des files d'attente de faible priorité qu'une fois que # chaque classe a atteint un seuil minimum (1/7 de la bande passante # dans ce script). # # Résumé: # * La perte d'un paquet TCP diminue le rythme de réception de la # connexion associée via les mécanismes de contrôle de congestion. # * Jeter des paquets TCP n'apporte rien. S'ils sont importants, ils # seront retransmis. # * Limiter le rythme des connexions TCP entrantes en dessous de la # capacité de la ligne DEVRAIT éviter la mise en attente des paquets # du côté du FAI (DSLAM, concentrateur de cables, etc). L'expérience # indique que ces files contiennent 4 secondes de trafic à 1500 kbps, # soit 6 Mb de données. À ce niveau, l'absence de mise en attente # diminue la latence. 7 wondershaper # # Avertissements: # * Est−ce que la limitation de bande passante diminue l'efficacité de # transferts TCP massifs ? # − Apparemment non. L'augmentation de priorité des paquets # d'acquittement maximise le débit en évitant de perdre de la bande # passante à retransmettre des paquets déjà reçus. # # NOTE: La configuration ci−dessous fonctionne avec ma connexion ADSL # 1.5M/128K via Pacific Bell Internet (SBC Global Services) DEV=eth0 RATEUP=90 RATEDN=700 # Nettement inférieur à la capacité de la ligne de 1500. # On n'a donc pas à limiter le trafic entrant jusqu'à ce # qu'une meilleure réalisation telle que la modification # de fenêtre TCP soit disponible. # # Fin des options de configuration # if [ "$1" = "status" ] then echo "[qdisc]" tc −s qdisc show dev $DEV tc −s qdisc show dev imq0 echo "[class]" tc −s class show dev $DEV tc −s class show dev imq0 echo "[filter]" tc −s filter show dev $DEV tc −s filter show dev imq0 echo "[iptables]" iptables −t mangle −L MONLIMITEUR−OUT −v −x 2> /dev/null iptables −t mangle −L MONLIMITEUR−IN −v −x 2> /dev/null exit fi # Remise à zéro tc qdisc del dev $DEV root 2> /dev/null > /dev/null tc qdisc del dev imq0 root 2> /dev/null > /dev/null iptables −t mangle −D POSTROUTING −o $DEV −j MONLIMITEUR−OUT 2> /dev/null > /dev/null iptables −t mangle −F MONLIMITEUR−OUT 2> /dev/null > /dev/null iptables −t mangle −X MONLIMITEUR−OUT 2> /dev/null > /dev/null iptables −t mangle −D PREROUTING −i $DEV −j MONLIMITEUR−IN 2> /dev/null > /dev/null iptables −t mangle −F MONLIMITEUR−IN 2> /dev/null > /dev/null iptables −t mangle −X MONLIMITEUR−IN 2> /dev/null > /dev/null ip link set imq0 down 2> /dev/null > /dev/null rmmod imq 2> /dev/null > /dev/null if [ "$1" = "stop" ] then echo "Limitation de débit désactivée sur $DEV." exit fi ########################################################### # # Limitation de trafic sortant (limite supérieure à RATEUP) # positionnement de la taille de la file d'émission pour obtenir # une latence d'environ 2 secondes pour les paquets de la file # de faible priorité. ip link set dev $DEV qlen 30 # modification de MTU du périphérique sortant. # − Diminuer la MTU abaisse la latence mais dégrade le débit en raison de # la surcharge IP et TCP. ip link set dev $DEV mtu 1000 # ajout de la stratégie HTB tc qdisc add dev $DEV root handle 1: htb default 26 8 wondershaper # ajout de la classe de limitation principale tc class add dev $DEV parent 1: classid 1:1 htb rate ${RATEUP}kbit # ajout des classes filles: # − chaque classe dispose AU MOINS de son quota de bande passante. Aucune # classe n'est donc étouffée par les autres. Chaque classe peut également # consommer toute la bande passante si aucune autre classe ne l'emploie. tc class add dev $DEV parent 1:1 classid 1:20 htb rate $[$RATEUP/7]kbit \ ceil ${RATEUP}kbit prio 0 tc class add dev $DEV parent 1:1 classid 1:21 htb rate $[$RATEUP/7]kbit \ ceil ${RATEUP}kbit prio 1 tc class add dev $DEV parent 1:1 classid 1:22 htb rate $[$RATEUP/7]kbit \ ceil ${RATEUP}kbit prio 2 tc class add dev $DEV parent 1:1 classid 1:23 htb rate $[$RATEUP/7]kbit \ ceil ${RATEUP}kbit prio 3 tc class add dev $DEV parent 1:1 classid 1:24 htb rate $[$RATEUP/7]kbit \ ceil ${RATEUP}kbit prio 4 tc class add dev $DEV parent 1:1 classid 1:25 htb rate $[$RATEUP/7]kbit \ ceil ${RATEUP}kbit prio 5 tc class add dev $DEV parent 1:1 classid 1:26 htb rate $[$RATEUP/7]kbit \ ceil ${RATEUP}kbit prio 6 # ajout de la stratégie aux classes filles # − SFQ offre un traitement sensiblement équitable de chaque classe. 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 tc qdisc add dev $DEV parent 1:22 handle 22: sfq perturb 10 tc qdisc add dev $DEV parent 1:23 handle 23: sfq perturb 10 tc qdisc add dev $DEV parent 1:24 handle 24: sfq perturb 10 tc qdisc add dev $DEV parent 1:25 handle 25: sfq perturb 10 tc qdisc add dev $DEV parent 1:26 handle 26: sfq perturb 10 # répartition du trafic en classe via fwmark # − le trafic est réparti en classes de priorité suivant l'indicateur # fwmark des paquets (ceux−ci sont positionnés avec iptables un peu plus # loin). La classe de priorité par défaut a été mise à 1:26 de telle sorte # que les paquets qui ne sont pas marqués se retrouvent dans la classe de # priorité la plus faible. tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20 tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 21 fw flowid 1:21 tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 22 fw flowid 1:22 tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 23 fw flowid 1:23 tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 24 fw flowid 1:24 tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 25 fw flowid 1:25 tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 26 fw flowid 1:26 # ajout de MONLIMITEUR−OUT à la table de modification des paquets d'iptables # − ceci déclare la table employée pour filtrer et classer les paquets iptables −t mangle −N MONLIMITEUR−OUT iptables −t mangle −I POSTROUTING −o $DEV −j MONLIMITEUR−OUT # ajout de fwmark pour classer les différents types de trafic # − fwmark est positionné de 20 à 26 suivant la classe. 20 correspond à la # priorité la plus forte. # Trafic sur les ports bas iptables −t mangle −A MONLIMITEUR−OUT −p tcp −−sport 0:1024 −j MARK −−set−mark 23 # Trafic sur les ports bas iptables −t mangle −A MONLIMITEUR−OUT −p tcp −−dport 0:1024 −j MARK −−set−mark 23 # Port ftp−data, faible priorité iptables −t mangle −A MONLIMITEUR−OUT −p tcp −−dport 20 −j MARK −−set−mark 26 # Messagerie Immédiate AOL iptables −t mangle −A MONLIMITEUR−OUT −p tcp −−dport 5190 −j MARK −−set−mark 23 # ICMP (ping) − forte priorité (impressionnez vos amis) iptables −t mangle −A MONLIMITEUR−OUT −p icmp −j MARK −−set−mark 20 # DNS (petits paquets) iptables −t mangle −A MONLIMITEUR−OUT −p udp −j MARK −−set−mark 21 9 wondershaper # shell sécurisé iptables −t mangle −A MONLIMITEUR−OUT −p tcp −−dport ssh −j MARK −−set−mark 22 # shell sécurisé iptables −t mangle −A MONLIMITEUR−OUT −p tcp −−sport ssh −j MARK −−set−mark 22 # telnet (hum ...) iptables −t mangle −A MONLIMITEUR−OUT −p tcp −−dport telnet −j MARK −−set−mark 22 # telnet (hum ...) iptables −t mangle −A MONLIMITEUR−OUT −p tcp −−sport telnet −j MARK −−set−mark 22 # IPSec − la surcharge n'est pas connue ... iptables −t mangle −A MONLIMITEUR−OUT −p ipv6−crypt −j MARK −−set−mark 24 # Serveur WWW local iptables −t mangle −A MONLIMITEUR−OUT −p tcp −−sport http −j MARK −−set−mark 25 # Petits paquets (des ACK probablement) iptables −t mangle −A MONLIMITEUR−OUT −p tcp −m length −−length :64 −j MARK −−set−mark 21 # Répétition − on marque les paquets restants à 26 (faible priorité) iptables −t mangle −A MONLIMITEUR−OUT −m mark −−mark 0 −j MARK −−set−mark 26 # Fin de la limitation sortante # #################################################### echo "Limitation de trafic sortant activé sur $DEV. Débit: ${RATEUP}kbit/sec." # Décommenter la ligne suivante pour n'avoir que la limitation de trafic montant. # exit #################################################### # # Limitation du trafic entrant (débit maximal de RATEDN) # on force le chargement du module imq modprobe imq numdevs=1 ip link set imq0 up # ajout de la stratégie de mise en file d'attente # − par défaut une classe 1:21 à faible priorité tc qdisc add dev imq0 handle 1: root htb default 21 # ajout de la classe de limitation principale tc class add dev imq0 parent 1: classid 1:1 htb rate ${RATEDN}kbit # ajout des classes filles # − trafic TCP en 21, le reste en 20 # tc class add dev imq0 parent 1:1 classid 1:20 htb rate $[$RATEDN/2]kbit \ ceil ${RATEDN}kbit prio 0 tc class add dev imq0 parent 1:1 classid 1:21 htb rate $[$RATEDN/2]kbit \ ceil ${RATEDN}kbit prio 1 # ajout de la stratégie de limitation aux classes filles # − voir les remarques ci−dessus sur SFQ. tc qdisc add dev imq0 parent 1:20 handle 20: sfq perturb 10 tc qdisc add dev imq0 parent 1:21 handle 21: red limit 1000000 \ min 5000 max 100000 avpkt 1000 burst 50 # répartition du trafic en classe via fwmark # − le trafic est réparti en classes de priorité suivant l'indicateur # fwmark des paquets (ceux−ci sont positionnés avec iptables un peu plus # loin). La classe de priorité par défaut à été mise à 1:26 de telle sorte # que les paquets qui ne sont pas marqués se retrouvent dans la classe de # priorité la plus faible. tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20 tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 21 fw flowid 1:21 10 Script de visualisation des files d'a # ajout de MONLIMITEUR−IN à la table de modification des paquets d'iptables iptables −t mangle −N MONLIMITEUR−IN iptables −t mangle −I PREROUTING −i $DEV −j MONLIMITEUR−IN # ajout de fwmark pour classer les différents types de trafic # − fwmark est positionné de 20 à 21 suivant la classe. 20 correspond à la # priorité la plus forte. # Forte priorité pour les paquets non TCP iptables −t mangle −A MONLIMITEUR−IN −p ! tcp −j MARK −−set−mark 20 # Les petits paquets TCP sont probablement des ACK iptables −t mangle −A MONLIMITEUR−IN −p tcp −m length −−length :64 −j MARK −−set−mark 20 # shell sécurisé iptables −t mangle −A MONLIMITEUR−IN −p tcp −−dport ssh −j MARK −−set−mark 20 # shell sécurisé iptables −t mangle −A MONLIMITEUR−IN −p tcp −−sport ssh −j MARK −−set−mark 20 # telnet (hum ...) iptables −t mangle −A MONLIMITEUR−IN −p tcp −−dport telnet −j MARK −−set−mark 20 # telnet (hum ...) iptables −t mangle −A MONLIMITEUR−IN −p tcp −−sport telnet −j MARK −−set−mark 20 # Répétition − les paquets sans marque sont positionnés à 21 (faible priorité) iptables −t mangle −A MONLIMITEUR−IN −m mark −−mark 0 −j MARK −−set−mark 21 # on envoie les paquets précédents à l'interface imq0. iptables −t mangle −A MONLIMITEUR−IN −j IMQ # Fin de la limitation de trafic entrant. # #################################################### echo "Limitation de trafic entrant activée sur $DEV. Débit: ${RATEDN}kbit/sec." Script de visualisation des files d'attentes Le script suivant visualise les files d'attentes : #!/bin/bash echo 'Qdisc' tc −s qdisc show dev eth0 echo 'Classes' tc −s class show dev eth0 echo 'Filter' tc −s filter show dev eth0 Conclusion J'ai essayé à travers cet article de vous ammener un maximum de renseignements, cependant, je n'ai pas la prétention d'en faire un document référence (il y a l'excellent HOWTO QoS pour cela). Toutes les remarques sont les bienvenues, il serait intéressant de faire évoluer ce présent document avec les commentaires que vous y apporterez. Si vous avez des scripts HTB.init, ou CBQ.init perso, n'hesitez pas à me les envoyer, je les rajouterai dans cet article. Pour me contacter : [email protected] 11 Script de visualisation des files d'attentes 12