« La QoS, c'est le machin qui sert à rien, c'est ça ? »

Jean-Marc, ingénieur chez Cisco.

aintenant que je t'ai bien mis l'eau à la bouche en te promettant monts et merveilles pour ton auto-hébergement personnalisé à toi, on va passer aux choses sérieuses.

Et comment donc ? Ben, on va commencer par évaluer le traffic sortant puis faire du marquage DSCP sur les paquets IP qui viennent de ton réseau et qui vont sur l'Interwebz.

T'as des baskets, tu sors pas…

Tout bon plan de Qualité de Service doit commencer par une question simple : qu'est-ce qui est prioritaire et qu'est-ce qui ne l'est pas ? Va donc falloir te retrousser les manches et voir quels services sont exposés depuis chez toi vers Internet.

Il est important de distinguer dans un premier temps les services prioritaires, des services moins prioritaires. Il va falloir en fait, faire la différence de manière stricte entre ce qui est important, ce qui est interactif et ce qui consomme de la bande passante. Il est évident qu'une connexion SSH doit être transportée en priorité du fait de son interactivité, mais elle ne consomme que peu de bande passante. Inversement, une visite sur ton site consomme un peu plus de bande passante, mais n'est peut-être pas aussi prioritaire que ta messagerie instantanée.

Pour te donner un exemple concret, on pourrait considérer les services suivants en sortie de ta connexion Internet, par ordre d'importance :

  • Upload de vidéos vers Youporn
  • Bittorrent
  • Emule
  • Limewire
  • VoIP (Skype, SIP, etc…)
  • Ton serveur SMTP
  • Ton serveur Jabber
  • Les galeries de Photos de tes nains de jardin
  • Le wiki sur la vie sexuelle de ton poisson rouge
  • Et très très loin derrière, le blog de ta petite sœur

Les 4 premiers services sont très prioritaires et ne doivent pas être coupés. Cependant, le premier n'étant pas utilisé en continue (quoique…), on peut considérer qu'il doit avoir une priorité un peu plus haute que les autres, histoire de leur marcher dessus en cas de congestion. Pour ce qui est de la bande passante, on pourra considérer qu'il lui faut un minimum (sinon ce sera simplement insupportable d'uploader une vidéo !) et un maximum (histoire de pas casser les couilles à tout le monde à la maison chaque fois que tu uploades du pr0n). Un bon candidat pour un AF41. Le P2P pourrait être classé en AF42/AF43.

La voix sur IP consommant une bande passante simplement OLOLZ, on peut la mettre en EF, tu ne verras probablement pas la différence en temps normal de toutes manières.

Les serveurs de type SMTP et Jabber fonctionnent différemment : on peut tolérer quelques secondes de latence dans un cas comme dans l'autre, mais on peut carrément jeter ce qui concerne le SMTP (si l'envoi échoue, il sera repris plus tard). Même s'ils sont importants, leur fonctionnement permet une certaine souplesse. On peut donc partir sur AF31 pour le serveur Jabber et AF21 pour le serveur SMTP.

Pour les trois derniers points, on va se heurter à un gros problème : si tu as un seul serveur Web qui dessert sous forme de VirtualHost tous ces services, comment faire pour les différencier ? Et bien, c'est simple, on peut pas… À moins de faire de l'IPv6 avec une adresse différente pour chaque site Web ou d'avoir autant de redirection de ports que de sites Web, tu n'arriveras à rien… Il va donc falloir se résoudre à classer tout ce qui est Web dans la même classe de service (style AF22/AF23) avec un minimum/maximum de bande passante.

Marquage-culotte :guyroux:

Et comment on va faire ce marquage ? En utilisant la chaîne PREROUTING de la table mangle d'iptables. Et là, normalement tu dois saigner du nez « KÔA ? La table mangle ?!? Ce machin immonde que personne sait à quoi ça sert !! ». Parfaitement jeune chimpanzé, et pour une raison bien simple : c'est la toute première chaîne traversée dans iptables (tu peux d'ailleurs t'en convaincre ici).

arquer un paquet est donc d'une simplicité crasse :

iptables -t mangle -A PREROUTING -s <l'IP côté LAN de ton serveur Jabber> \
 -i <Interface LAN> -p tcp --sport 5269 -j DSCP --set-dscp 0x1a

Tous les paquets entrants sur l'interface LAN de ton routeur, en provenance de ton serveur Jabber et à destination du port S2S XMPP seront marqués AF31 (== 0x1a en hexadécimal). Comment vérifier que le marquage est bien effectif ? Tout simplement en capturant les paquets, toujours via iptables sur l'interface WAN du routeur avec quelque chose comme ça :

iptables -I FORWARD -p tcp --sport 5269 -j LOG

Avant le marquage, on obtient des choses de ce type, avec les champs TOS=0x00 et PREC=0x00 :

Apr 20 14:31:56 monzob kernel: [2655643.233769] IN=eth1 OUT=eth0 \
 SRC=<LAN serveur Jabber> DST=<Autre serveur Jabber> LEN=52 \
 TOS=0x00 PREC=0x00 TTL=63 ID=65024 DF PROTO=TCP SPT=5269 \
 DPT=51779 WINDOW=2003 RES=0x00 ACK URGP=0

Et après le marquage :

Apr 20 14:36:55 monzob kernel: [2655941.626164] IN=eth1 OUT=eth0 \
 SRC=<LAN serveur Jabber> DST=<Autre serveur Jabber> LEN=52 \
 TOS=0x08 PREC=0x60 TTL=63 ID=65036 DF PROTO=TCP SPT=5269 \
 DPT=51779 WINDOW=2003 RES=0x00 ACK URGP=0

Petit calcul rapide pour vérifier qu'on ne s'est pas complètement planté :

>>> hex((0x08+0x60)/4)
'0x1a'

Que j'explique sinon tu vas aller te jeter sous un bus : La précédence (PREC) et le type de service (TOS) sont les deux éléments clés de la précédente norme et forme un ensemble sur 8 bits (le premier étant les 3 premiers bits, le second les 4 suivants et le dernier est toujours à 0). AF31 est en binaire 011010 multiplié par 4 pour le mettre sur 8 bits, soit 01101000. En hexadécimal, cela donne donc 68, soit 60 + 8 toujours en hexadécimal. Pour obtenir les 6 premier bits, il faut décaler 2 fois à droite, soit l'équivalent d'une division par 4. D'où la valeur DSCP.

Je te laisse te faire des nœuds au cerveau pour tout capter, je te retrouve la semaine prochaine pour mettre en place des files avec des priorités.