Router et partager équitablement une connexion ADSL avec un serveur Linux
Mon domicile est connecté à internet en ADSL avec des débits corrects (14Mbit/s descendant, 1Mbit/s remontant). Mais cela ne suffit pas à éviter d’avoir une liaison saturée lorsque l’un de mes adolescents décide de télécharger un nouveau jeu. Résultat : plus d’accès à internet, débranchement sauvage dudit PC et le ton qui monte…
Une solution plus intelligente était à trouver, d’autant que j’ai un serveur qui fait office de passerelle avec la box adsl. Ce serveur doit donc être capable d’optimiser les transferts et surtout de les partager équitablement, c’est ce qu’on appelle de la mise en forme de trafic, ou « Traffic shaping« .
Regardons tout d’abord la configuration des ports réseau de mon serveur :
root@hpserv:~# iface out0 inet static address 192.168.cc.dd netmask 255.255.255.0 gateway 192.168.cc.dd pre-up iptables-restore < /etc/iptables.up.rules dns-nameservers 212.27.40.240 212.27.40.241 8.8.8.8 8.8.4.4 iface br0 inet static address 192.168.cc.dd netmask 255.255.255.0 post-up iptables-restore < /etc/iptables.up.rules
J’ai donc 2 interfaces réseau : out0 connecte le serveur à la box adsl, br0 connecte le serveur au switch gigabit du réseau local
Le noyau linux intègre nativement la gestion avancée des flux de donnée réseau ( netfilter ), et les outils nécessaires pour les gérer sont installés nativement sur ubuntu server ( iptables et tc ).
Petite subtilité dans mon cas, j’ai également Webmin qui est installé. Cet outil me permet de faire l’administration du serveur pour les tâches simples, je vais donc modifier le fichier iptables utilisé par webmin pour réaliser les modification (/etc/iptables.up.rules)
Première étape de la configuration : mettre des règles de priorisation des flux, sachant que ceux-ci ne peuvent être appliqués que sur des flux sortant (sur le principe que seul celui qui envoie est capable de moduler finement le débit). Voici le script qui me permet de régler ces paramètres :
#!/bin/bash # Inspiré de ces pages : # http://wiki.linuxwall.info/doku.php/fr:ressources:dossiers:networking:qos_traffic_control # https://bbs.archlinux.org/viewtopic.php?id=153418 # https://wiki.gentoo.org/wiki/Traffic_shaping # https://connect.ed-diamond.com/GNU-Linux-Magazine/GLMF-127/QoS-et-gestion-du-trafic-avec-Traffic-Control tc qdisc del dev br0 root tc qdisc del dev out0 root # paramétrage de l'interface réseau local, flux descendant tc qdisc add dev br0 root handle 1: htb default 23 tc class add dev br0 parent 1:0 classid 1:10 htb rate 13mbit ceil 13mbit tc class add dev br0 parent 1:0 classid 1:20 htb rate 1gbit ceil 1gbit tc class add dev br0 parent 1:10 classid 1:11 htb rate 7mbit ceil 13mbit prio 1 burst 10kbit tc qdisc add dev br0 parent 1:11 handle 111: sfq perturb 10 tc class add dev br0 parent 1:10 classid 1:12 htb rate 3mbit ceil 13mbit prio 2 burst 10kbit tc qdisc add dev br0 parent 1:12 handle 112: sfq perturb 10 tc class add dev br0 parent 1:10 classid 1:13 htb rate 3mbit ceil 13mbit prio 3 burst 10kbit tc qdisc add dev br0 parent 1:13 handle 113: sfq perturb 10 tc class add dev br0 parent 1:20 classid 1:21 htb rate 400mbit ceil 1000mbit prio 4 burst 50kbit tc qdisc add dev br0 parent 1:21 handle 121: sfq perturb 10 tc class add dev br0 parent 1:20 classid 1:22 htb rate 300mbit ceil 1000mbit prio 5 burst 50kbit tc qdisc add dev br0 parent 1:22 handle 122: sfq perturb 10 tc class add dev br0 parent 1:20 classid 1:23 htb rate 300mbit ceil 1000mbit prio 6 burst 50kbit tc qdisc add dev br0 parent 1:23 handle 123: sfq perturb 10 tc filter add dev br0 parent 1:0 protocol ip prio 1 handle 11 fw flowid 1:11 tc filter add dev br0 parent 1:0 protocol ip prio 2 handle 12 fw flowid 1:12 tc filter add dev br0 parent 1:0 protocol ip prio 3 handle 13 fw flowid 1:13 tc filter add dev br0 parent 1:0 protocol ip prio 4 handle 21 fw flowid 1:21 tc filter add dev br0 parent 1:0 protocol ip prio 5 handle 22 fw flowid 1:22 tc filter add dev br0 parent 1:0 protocol ip prio 6 handle 23 fw flowid 1:23 # paramétrage de l'interface ADSL, flux remontant tc qdisc add dev out0 root handle 1: htb default 11 tc class add dev out0 parent 1: classid 1:1 htb rate 950kbit tc class add dev out0 parent 1:1 classid 1:11 htb rate 950kbit prio 1 tc qdisc add dev out0 parent 1:11 fq_codel noecn
Les deux interfaces portent des règles de priorisation :
- br0 : côté réseau local
- la priorisation se fait suivant la méthode HTB (Hierarchical Token Bucket )
Elle consiste, en 2 mots, à ranger les données à envoyer dans des paniers qui sont vidés en fonction de leur priorité - Deux classes principales sont définies
- la 1:10 gère les flux venant d’internet et une limite de vitesse est fixé à 90% de la vitesse maximum de mon adsl
3 paniers y sont créés (1:11, 1:12, 1:13) avec des priorités décroissantes (priorité 1 étant la priorité la plus forte) et des débit assurés (rate) se réduisant - la 1:20 gère les flux locaux avec une limite de vitesse fixée au maximum du réseau (qui ne sature jamais en fait…)
Idem 3 paniers y sont créés (1:21, 1:22, 1:23)
- la 1:10 gère les flux venant d’internet et une limite de vitesse est fixé à 90% de la vitesse maximum de mon adsl
- Enfin des filtres sont rajoutés permettant de ranger les paquets de données tagués dans les bons paniers
Exemple : un panier tagué 11 (handle 11) ira dans le panier 1:11. Autant faire simple …
- la priorisation se fait suivant la méthode HTB (Hierarchical Token Bucket )
- out0 : côté routeur adsl
- Celui-ci est présenté comme utilisant une méthode HTB pour définir le débit de la ligne à 95% de son débit maximum.
- Mais il n’y a en fait qu’un seul panier actif pour le moment (le numéro 1:11), la méthode HTB n’a pas d’effet.
- C’est la dernière ligne qui est importante car elle remet un mode de routage de type fq_codel sur ce panier.
La méthode fq_codel est préconisée dans ce type de liaison à faible débit avec un réseau supportant de multiples flux parallèles. Voir cet article pour plus de détails : What_can_I_do_about_Bufferbloat
Maintenant qu’on a défini les règles de priorisation, il va falloir mettre des marques sur les paquets de données qui vont permettre de les mettre dans les bons paniers. Cela peut se faire en intégrant des règles ipfilter. Voici une partie de celles que j’ai posées dans la table mangle de iptables :
*mangle :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A FORWARD -p tcp -m tcp ! -s 192.168.cc.dd/24 -j MARK --set-mark 12 -A FORWARD -p udp -m udp ! -s 192.168.cc.dd/24 -j MARK --set-mark 12 -A FORWARD -p tcp -m tcp ! -s 192.168.cc.dd/24 -d 192.168.cc.dd -o br0 -j MARK --set-mark 13 -A FORWARD -p udp -m udp ! -s 192.168.cc.dd/24 -d 192.168.cc.dd -o br0 -j MARK --set-mark 13 -A FORWARD -p tcp -m tcp ! -s 192.168.cc.dd/24 -d 192.168.cc.dd -o br0 -j MARK --set-mark 11 -A FORWARD -p udp -m udp ! -s 192.168.cc.dd/24 -d 192.168.cc.dd -o br0 -j MARK --set-mark 11 -A OUTPUT -p tcp -m tcp -s 192.168.cc.dd/24 -d 192.168.cc.dd -o br0 -j MARK --set-mark 21 -A OUTPUT -p udp -m udp -s 192.168.cc.dd/24 -d 192.168.cc.dd -o br0 -j MARK --set-mark 21
Par défaut, tous les paquets tcp ou udp venant de l’extérieur du réseau local (! -s 192.168.cc.dd/24) et forwardés partiront dans le panier 1:12
En fonction de l’adresse IP de destination, par exemple mon PC ou la TV sur IP, ces données iront plutôt dans le panier 11 (+ prioritaire) ou 13 (- prioritaire)
En ce qui concerne les données émises par le serveur sur le réseau local, certains périphériques prioritaires (mon PC) seront priorisés en étant mis dans le panier 21, alors que ces données vont par défaut dans le panier 22
Enfin pour vérifier que tout cela fonctionne, j’ai repris un script (d’ailleurs légèrement corrigé pour fonctionner en gbit et avec fq_codel) que vous pourrez trouver dans le fichier à télécharger ici. Il permet d’afficher les statistiques d’utilisation de ces niveaux de priorisation dans un format tabulaire facile à lire.
root@hpserv:~# ./qosstats br0 br0 Class Paren Prio Rate Ceil Burst Sent Dropped Backlog kbps Pps ============================================================================== 1:10 - - 13 13 1599b 881829 0 0b/0p - - 1:11 1:10 4 7 13 1598b 164414 0 0b/0p - - 1:12 1:10 5 3 13 1599b 10613 0 0b/0p - - 1:13 1:10 6 3 13 1599b 706802 0 0b/0p - - 1:20 - - 0 0 1375b 4815115 0 0b/0p - - 1:21 1:20 1 400 0 1600b 3580763 0 0b/0p - - 1:22 1:20 2 300 0 1537b 1234352 0 0b/0p - - 1:23 1:20 3 300 0 1537b 0 0 0b/0p - -
1 réponse
[…] 6. Router et partager équitablement une connexion ADSL avec … […]