HOWTO du routage avanc* et du contr*le de trafic sous Linux Bert Hubert Netherlabs BV <[1]bert.hubert@netherlabs.nl> Thomas Graf (Auteur d'une section) <[2]tgraf%suug.ch> Gregory Maxwell (Auteur d'une section) Remco van Mook (Auteur d'une section) <[3]remco@virtu.nl> Martijn van Oosterhout (Auteur d'une section) <[4]kleptog@cupid.suninternet.com> Paul B. Schroeder (Auteur d'une section) <[5]paulsch@us.ibm.com> Jasper Spaans (Auteur d'une section) <[6]jasper@spaans.ds9a.nl> Pedro Larroy (Auteur d'une section) <[7]piotr%member.fsf.org> Laurent Foucher Traducteur <[8]foucher@gch.iut-tlse3.fr> Philippe Latu Traducteur/Relecteur <[9]philippe.latu@linux-france.org> Guillaume All*gre Relecteur <[10]Guillaume.Allegre@imag.fr> Une approche pratique d'iproute2, de la mise en forme du trafic et un peu de netfilter. -------------------------------------------------------------------------- Table des mati*res 1. [11]D*dicace 2. [12]Introduction [13]Conditions de distribution et Mise en garde [14]Connaissances pr*alables [15]Ce que Linux peut faire pour vous [16]Notes diverses [17]Acc*s, CVS et propositions de mises * jour [18]Liste de diffusion [19]Plan du document 3. [20]Introduction * iproute2 [21]Pourquoi iproute2 ? [22]Un tour d'horizon d'iproute2 [23]Pr*requis [24]Explorer votre configuration courante [25]ip nous montre nos liens [26]ip nous montre nos adresses IP [27]ip nous montre nos routes [28]ARP 4. [29]R*gles - bases de donn*es des politiques de routage [30]Politique de routage simple par l'adresse source [31]Routage avec plusieurs acc*s Internet/fournisseurs d'acc*s [32]Acc*s s*par* [33]Balance de charge 5. [34]GRE et autres tunnels [35]Quelques remarques g*n*rales * propos des tunnels : [36]IP dans un tunnel IP [37]Le tunnel GRE [38]Le tunnel IPv4 [39]Le tunnel IPv6 [40]Tunnels dans l'espace utilisateur 6. [41]Tunnel IPv6 avec Cisco et/ou une dorsale IPv6 (6bone) [42]Tunnel IPv6 7. [43]IPSEC: IP s*curis* * travers Internet [44]Introduction sur la gestion manuelle des cl*s [45]Gestion automatique des cl*s [46]Th*orie [47]Exemple [48]Gestion automatique des cl*s en utilisant les certificats X.509 [49]tunnels IPSEC [50]Autre logiciel IPSEC [51]Interop*rabilit* d'IPSEC avec d'autres syst*mes [52]Windows [53]Check Point VPN-1 NG 8. [54]Routage multidistribution (multicast) 9. [55]Gestionnaires de mise en file d'attente pour l'administration de la bande passante [56]Explication sur les files d'attente et la gestion de la mise en file d'attente [57]Gestionnaires de mise en file d'attente simples, sans classes [58]pfifo_fast [59]Filtre * seau de jetons (Token Bucket Filter) [60]Mise en file d'attente stochastiquement *quitable (Stochastic Fairness Queueing) [61]Conseils pour le choix de la file d'attente [62]terminologie [63]Gestionnaires de file d'attente bas*s sur les classes [64]Flux * l'int*rieur des gestionnaires bas*s sur des classes & * l'int*rieur des classes [65]La famille des gestionnaires de mise en file d'attente : racines, descripteurs, descendances et parents [66]Le gestionnaire de mise en file d'attente PRIO [67]Le c*l*bre gestionnaire de mise en file d'attente CBQ [68]Seau de jetons * contr*le hi*rarchique (Hierarchical Token Bucket) [69]Classifier des paquets avec des filtres [70]Quelques exemples simples de filtrage [71]Toutes les commandes de filtres dont vous aurez normalement besoin [72]Le p*riph*rique de file d'attente interm*diaire (The Intermediate queueing device (IMQ)) [73]Configuration simple 10. [74]quilibrage de charge sur plusieurs interfaces [75]Avertissement 11. [76]Netfilter et iproute - marquage de paquets 12. [77]Filtres avanc*s pour la (re-)classification des paquets [78]Le classificateur u32 [79]Le s*lecteur U32 [80]S*lecteurs g*n*raux [81]Les s*lecteurs sp*cifiques [82]Le classificateur route [83]Les filtres de r*glementation (Policing filters) [84]Techniques de r*glementation [85]Actions de d*passement de limite (Overlimit actions) [86]Exemples [87]Filtres hach*s pour un filtrage massif tr*s rapide [88]Filtrer le trafic IPv6 [89]Comment se fait-il que ces filtres tc IPv6 ne fonctionnent pas ? [90]Marquer les paquets IPv6 en utilisant ip6tables [91]Utiliser le s*lecteur u32 pour rep*rer le paquet IPv6 13. [92]Param*tres r*seau du noyau [93]Filtrage de Chemin Inverse (Reverse Path Filtering) [94]Configurations obscures [95]ipv4 g*n*rique [96]Configuration des p*riph*riques [97]Politique de voisinage [98]Configuration du routage 14. [99]Gestionnaires de mise en file d'attente avanc*s & moins communs [100]bfifo/pfifo [101]Param*tres & usage [102]Algorithme Clark-Shenker-Zhang (CSZ) [103]DSMARK [104]Introduction [105]A quoi DSMARK est-il reli* ? [106]Guide des services diff*renci*s [107]Travailler avec DSMARK [108]Comment SCH_DSMARK travaille. [109]Le filtre TC_INDEX [110]Gestionnaire de mise en file d'attente d'entr*e (Ingress qdisc) [111]Param*tres & usage [112]Random Early Detection (RED) [113]Generic Random Early Detection [114]Emulation VC/ATM [115]Weighted Round Robin (WRR) 15. [116]Recettes de cuisine [117]Faire tourner plusieurs sites avec diff*rentes SLA (autorisations) [118]Prot*ger votre machine des inondations SYN [119]Limiter le d*bit ICMP pour emp*cher les d*nis de service [120]Donner la priorit* au trafic interactif [121]Cache web transparent utilisant netfilter, iproute2, ipchains et squid [122]Sch*ma du trafic apr*s l'impl*mentation [123]Circonvenir aux probl*mes de la d*couverte du MTU de chemin en configurant un MTU par routes [124]Solution [125]Circonvenir aux probl*mes de la d*couverte du MTU de chemin en imposant le MSS (pour les utilisateurs de l'ADSL, du cble, de PPPoE & PPtP) [126]Le Conditionneur de Trafic Ultime : Faible temps de latence, T*l*chargement vers l'amont et l'aval rapide [127]Pourquoi cela ne marche t-il pas bien par d*faut ? [128]Le script (CBQ) [129]Le script (HTB) [130]Limitation du d*bit pour un h*te ou un masque de sous-r*seau [131]Exemple d'une solution de translation d'adresse avec de la QoS [132]Commen*ons l'optimisation de cette rare bande passante [133]Classification des paquets [134]Am*liorer notre configuration [135]Rendre tout ceci actif au d*marrage 16. [136]Construire des ponts et des pseudo ponts avec du Proxy ARP [137]Etat des ponts et iptables [138]Pont et mise en forme [139]Pseudo-pont avec du Proxy-ARP [140]ARP & Proxy-ARP [141]Impl*mentez-le 17. [142]Routage Dynamique - OSPF et BGP [143]Configurer OSPF avec Zebra [144]Pr*requis [145]Configurer Zebra [146]Ex*cuter Zebra [147]Configurer BGP4 avec Zebra [148]sch*ma r*seau (Exemple) [149]Configuration (Exemple) [150]V*rification de la configuration 18. [151]Autres possibilit*s 19. [152]Lectures suppl*mentaires 20. [153]Remerciements -------------------------------------------------------------------------- Chapitre 1. D*dicace Ce document est d*di* * beaucoup de gens ; dans ma tentative de tous me les rappeler, je peux en citer quelques-uns : * Rusty Russell * Alexey N. Kuznetsov * La fine *quipe de Google * L'*quipe de Casema Internet -------------------------------------------------------------------------- Chapitre 2. Introduction Bienvenue, cher lecteur. Ce document a pour but de vous *clairer sur la mani*re de faire du routage avanc* avec Linux 2.2/2.4. M*connus par les utilisateurs, les outils standard de ces noyaux permettent de faire des choses spectaculaires. Les commandes comme route et ifconfig sont des interfaces vraiment pauvres par rapport * la grande puissance potentielle d'iproute2. J'esp*re que ce HOWTO deviendra aussi lisible que ceux de Rusty Russell, tr*s r*put* (parmi d'autres choses) pour son netfilter. Vous pouvez nous contacter en nous *crivant * [154]l'*quipe HOWTO. Cependant, postez, s'il vous pla*t, vos questions sur la liste de diffusion (voir la section correspondante) pour celles qui ne sont pas directement li*es * ce HOWTO. Avant de vous perdre dans ce HOWTO, si la seule chose que vous souhaitez faire est de la simple mise en forme de trafic, allez directement au chapitre [155]Autres possibilit*s>, et lisez ce qui concerne CBQ.init. -------------------------------------------------------------------------- Conditions de distribution et Mise en garde Ce document est distribu* dans l'espoir qu'il sera utile et utilis*, mais SANS AUCUNE GARANTIE ; sans m*me une garantie implicite de qualit* l*gale et marchande ni aptitude * un quelconque usage. En un mot, si votre dorsale STM-64 est tomb*e ou distribue de la pornographie * vos estim*s clients, cela n'est pas de notre faute. D*sol*. Copyright (c) 2001 par Bert Hubert, Gregory Maxwell et Martijn van Oosterhout, Remco van Mook, Paul B. Schroeder et autres. Ce document ne peut *tre distribu* qu'en respectant les termes et les conditions expos*s dans la Open Publication License, v1.0 ou sup*rieure (la derni*re version est actuellement disponible sur http://www.opencontent.org/openpub/). Copiez et distribuez (vendez ou donnez) librement ce document, dans n'importe quel format. Les demandes de corrections et/ou de commentaires sont * adresser * la personne qui maintient ce document. Il est aussi demand* que, si vous publiez cet HOWTO sur un support papier, vous en envoyiez des exemplaires aux auteurs pour une <<*relecture critique*>> :-) -------------------------------------------------------------------------- Connaissances pr*alables Comme le titre l'implique, ceci est un HOWTO <<*avanc**>>. Bien qu'il ne soit pas besoin d'*tre un expert r*seau, certains pr*-requis sont n*cessaires. Voici d'autres r*f*rences qui pourront vous aider * en apprendre plus : [156]Rusty Russell's networking-concepts-HOWTO Tr*s bonne introduction, expliquant ce qu'est un r*seau, et comment on le connecte * d'autres r*seaux. Linux Networking-HOWTO (ex Net-3 HOWTO) Excellent document, bien que tr*s bavard. Il vous apprendra beaucoup de choses qui sont d*j* configur*es si vous *tes capable de vous connecter * Internet. Il peut *ventuellement *tre situ* * /usr/doc/HOWTO/NET-HOWTO.txt, mais peut *galement *tre trouv* [157]en ligne -------------------------------------------------------------------------- Ce que Linux peut faire pour vous Une petite liste des choses qui sont possibles : * Limiter la bande passante pour certains ordinateurs * Limiter la bande passante VERS certains ordinateurs * Vous aider * partager *quitablement votre bande passante * Prot*ger votre r*seau des attaques de type D*ni de Service * Prot*ger Internet de vos clients * Multiplexer plusieurs serveurs en un seul, pour l'*quilibrage de charge ou une disponibilit* am*lior*e * Restreindre l'acc*s * vos ordinateurs * Limiter l'acc*s de vos utilisateurs vers d'autres h*tes * Faire du routage bas* sur l'ID utilisateur (eh oui !), l'adresse MAC, l'adresse IP source, le port, le type de service, l'heure ou le contenu. Peu de personnes utilisent couramment ces fonctionnalit*s avanc*es. Il y a plusieurs raisons * cela. Bien que la documentation soit fournie, la prise en main est difficile. Les commandes de contr*le du trafic ne sont pratiquement pas document*es. -------------------------------------------------------------------------- Notes diverses Il y a plusieurs choses qui doivent *tre not*es au sujet de ce document. Bien que j'en ai *crit la majeure partie, je ne veux vraiment pas qu'il reste tel quel. Je crois beaucoup * l'Open Source, je vous encourage donc * envoyer des remarques, des mises * jour, des corrections, etc. N'h*sitez pas * m'avertir des coquilles ou d'erreurs pures et simples. Si mon anglais vous para*t parfois peu naturel, ayez en t*te, s'il vous pla*t, que l'anglais n'est pas ma langue natale. N'h*sitez pas * m'envoyer vos suggestions [NdT : en anglais !] Si vous pensez que vous *tes plus qualifi* que moi pour maintenir une section ou si vous pensez que vous pouvez *crire et maintenir de nouvelles sections, vous *tes le bienvenu. La version SGML de ce HOWTO est disponible via CVS. J'envisage que d'autres personnes puissent travailler dessus. Pour vous aider, vous trouverez beaucoup de mentions FIXME (NdT : A CORRIGER). Les corrections sont toujours les bienvenues. Si vous trouvez une mention FIXME, vous saurez que vous *tes en territoire inconnu. Cela ne veut pas dire qu'il n'y a pas d'erreurs ailleurs, faites donc tr*s attention. Si vous avez valid* quelque chose, faites-nous le savoir, ce qui nous permettra de retirer la mention FIXME. Je prendrai quelques libert*s tout au long de cet HOWTO. Par exemple, je pars de l'hypoth*se d'une connexion Internet * 10 Mbits, bien que je sache tr*s bien que cela ne soit pas vraiment courant. -------------------------------------------------------------------------- Acc*s, CVS et propositions de mises * jour L'adresse canonique de cet HOWTO est [158]Ici. Nous avons maintenant un CVS en acc*s anonyme disponible depuis le monde entier. Cela est int*ressant pour plusieurs raisons. Vous pouvez facilement t*l*charger les nouvelles versions de ce HOWTO et soumettre des mises * jour. En outre, cela permet aux auteurs de travailler sur la source de fa*on ind*pendante, ce qui est une bonne chose aussi. $ export CVSROOT=:pserver:anon@outpost.ds9a.nl:/var/cvsroot $ cvs login CVS password: [enter 'cvs' (sans les caract*res ')] $ cvs co 2.4routing cvs server: Updating 2.4routing U 2.4routing/lartc.db Si vous avez fait des changements et que vous vouliez contribuer au HOWTO, ex*cutez cvs -z3 diff -uBb, et envoyez-nous le r*sultat par courrier *lectronique de fa*on * pouvoir facilement int*grer les modifications. Merci ! Au fait, soyez s*r que vous avez *dit* le fichier .db, les autres documents *tant g*n*r*s * partir de celui-ci. Un fichier Makefile est fourni pour vous aider * cr*er des fichiers PostScript, dvi, pdf, html et texte. Vous pouvez avoir * installer les docbook, docbook-utils, ghostscript et tetex pour obtenir tous les formats de sortie. Faites attention de ne pas *diter le fichier 2.4routing.sgml ! Il contient une ancienne version du HOWTO. Le bon fichier est lartc.db. -------------------------------------------------------------------------- Liste de diffusion Les auteurs re*oivent de plus en plus de courriers *lectroniques * propos de cet HOWTO. Vu l'int*r*t de la communaut*, il a *t* d*cid* la mise en place d'une liste de diffusion o* les personnes pourront discuter du routage avanc* et du contr*le de trafic. Vous pouvez vous abonner * la liste [159]ici. Il devra *tre not* que les auteurs sont tr*s h*sitants * r*pondre * des questions qui n'ont pas *t* pos*es sur la liste. Nous aimerions que la liste devienne une sorte de base de connaissance. Si vous avez une question, recherchez, s'il vous pla*t, d'abord dans l'archive, et ensuite postez-l* dans la liste de diffusion. -------------------------------------------------------------------------- Plan du document Nous allons essayer de faire des manipulations int*ressantes d*s le d*but, ce qui veut dire que tout ne sera pas expliqu* en d*tail tout de suite. Veuillez passer sur ces d*tails, et accepter de consid*rer qu'ils deviendront clairs par la suite. Le routage et le filtrage sont deux choses distinctes. Le filtrage est tr*s bien document* dans le HOWTO de Rusty, disponible ici : * [160]Rusty's Remarkably Unreliable Guides Nous nous focaliserons principalement sur ce qu'il est possible de faire en combinant netfilter et iproute2. -------------------------------------------------------------------------- Chapitre 3. Introduction * iproute2 Pourquoi iproute2 ? La plupart des distributions Linux et des UNIX utilisent couramment les v*n*rables commandes arp, ifconfig et route. Bien que ces outils fonctionnent, ils montrent quelques comportements inattendus avec les noyaux Linux des s*ries 2.2 et plus. Par exemple, les tunnels GRE font partie int*grante du routage de nos jours, mais ils n*cessitent des outils compl*tement diff*rents. Avec iproute2, les tunnels font partie int*grante des outils. Les noyaux Linux des s*ries 2.2 et plus ont un sous-syst*me r*seau compl*tement r**crit. Ce nouveau codage de la partie r*seau apporte * Linux des performances et des fonctionnalit*s qui n'ont pratiquement pas d'*quivalent parmi les autres syst*mes d'exploitation. En fait, le nouveau logiciel de filtrage, routage et de classification poss*de plus de fonctionnalit*s que les logiciels fournis sur beaucoup de routeurs d*di*s, de pare-feu et de produits de mise en forme (shaping) du trafic. Dans les syst*mes d'exploitation existants, au fur et * mesure que de nouveaux concepts r*seau apparaissaient, les d*veloppeurs sont parvenus * les greffer sur les structures existantes. Ce travail constant d'empilage de couches a conduit * des codes r*seau aux comportements *tranges, un peu comme les langues humaines. Dans le pass*, Linux *mulait le mode de fonctionnement de SunOS, ce qui n'*tait pas l'id*al. La nouvelle structure d'iproute2 a permis de formuler clairement des fonctionnalit*s impossibles * impl*menter dans le sous-syst*me r*seau pr*c*dent. -------------------------------------------------------------------------- Un tour d'horizon d'iproute2 Linux poss*de un syst*me sophistiqu* d'allocation de bande passante appel* Contr*le de trafic (Traffic Control). Ce syst*me supporte diff*rentes m*thodes pour classer, ranger par ordre de priorit*, partager et limiter le trafic entrant et sortant. Nous commencerons par un petit tour d'horizon des possibilit*s d'iproute2. -------------------------------------------------------------------------- Pr*requis Vous devez *tre s*r que vous avez install* les outils utilisateur (NdT : userland tools, par opposition * la partie <<*noyau*>> d'iproute2). Le paquet concern* s'appelle iproute sur RedHat et Debian. Autrement, il peut *tre trouv* * ftp://ftp.inr.ac.ru/ip-routing/iproute2-2.2.4-now-ss??????.tar.gz. Vous pouvez aussi essayer [161]iproute2-current.tar.gz pour la derni*re version. Certains *l*ments d'iproute vous imposent l'activation de certaines options du noyau. Il devra *galement *tre not* que toutes les versions de RedHat jusqu'* la version 6.2 incluse n'ont pas les fonctionnalit*s du contr*le de trafic activ*es dans le noyau fourni par d*faut. RedHat 7.2 contient tous les *l*ments par d*faut. Soyez *galement s*r que vous avez le support netlink, m*me si vous devez choisir de compiler votre propre noyau ; iproute2 en a besoin. -------------------------------------------------------------------------- Explorer votre configuration courante Cela peut vous para*tre surprenant, mais iproute2 est d*j* configur* ! Les commandes courantes ifconfig et route utilisent d*j* les appels syst*me avanc*s d'iproute2, mais essentiellement avec les options par d*faut (c'est-*-dire ennuyeuses). L'outil ip est central, et nous allons lui demander de nous montrer les interfaces. -------------------------------------------------------------------------- ip nous montre nos liens [ahu@home ahu]$ ip link list 1: lo: mtu 3924 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: dummy: mtu 1500 qdisc noop link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff 3: eth0: mtu 1400 qdisc pfifo_fast qlen 100 link/ether 48:54:e8:2a:47:16 brd ff:ff:ff:ff:ff:ff 4: eth1: mtu 1500 qdisc pfifo_fast qlen 100 link/ether 00:e0:4c:39:24:78 brd ff:ff:ff:ff:ff:ff 3764: ppp0: mtu 1492 qdisc pfifo_fast qlen 10 link/ppp La sortie peut varier, mais voici ce qui est affich* pour mon routeur NAT (NdT : translation d'adresse) chez moi. J'expliquerai seulement une partie de la sortie, dans la mesure o* tout n'est pas directement pertinent. La premi*re interface que nous voyons est l'interface loopback. Bien que votre ordinateur puisse fonctionner sans, je vous le d*conseille. La taille de MTU (unit* maximum de transmission) est de 3924 octets, et loopback n'est pas suppos* *tre mis en file d'attente, ce qui prend tout son sens dans la mesure o* cette interface est le fruit de l'imagination de votre noyau. Je vais passer sur l'interface dummy pour l'instant, et il se peut qu'elle ne soit pas pr*sente sur votre ordinateur. Il y a ensuite mes deux interfaces physiques, l'une du c*t* de mon modem cble, l'autre servant mon segment ethernet * la maison. De plus, nous voyons une interface ppp0. Notons l'absence d'adresses IP. Iproute d*connecte les concepts de <<*liens*>> et <<*d'adresses IP*>>. Avec l'IP aliasing, le concept de l'adresse IP canonique est devenu, de toute fa*on, sans signification. ip nous montre bien, cependant, l'adresse MAC, l'identifiant mat*riel de nos interfaces ethernet. -------------------------------------------------------------------------- ip nous montre nos adresses IP [ahu@home ahu]$ ip address show 1: lo: mtu 3924 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 brd 127.255.255.255 scope host lo 2: dummy: mtu 1500 qdisc noop link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff 3: eth0: mtu 1400 qdisc pfifo_fast qlen 100 link/ether 48:54:e8:2a:47:16 brd ff:ff:ff:ff:ff:ff inet 10.0.0.1/8 brd 10.255.255.255 scope global eth0 4: eth1: mtu 1500 qdisc pfifo_fast qlen 100 link/ether 00:e0:4c:39:24:78 brd ff:ff:ff:ff:ff:ff 3764: ppp0: mtu 1492 qdisc pfifo_fast qlen 10 link/ppp inet 212.64.94.251 peer 212.64.94.1/32 scope global ppp0 Cela contient plus d'informations : ip montre toutes nos adresses, et * quelles cartes elles appartiennent. inet signifie Internet (IPv4). Il y a beaucoup d'autres familles d'adresses, mais elles ne nous concernent pas pour le moment. Examinons l'interface eth0 de plus pr*s. Il est dit qu'elle est reli*e * l'adresse internet 10.0.0.1/8. Qu'est-ce que cela signifie ? Le /8 d*signe le nombre de bits r*serv*s * l'adresse r*seau. Il y a 32 bits, donc il reste 24 bits pour d*signer une partie de notre r*seau. Les 8 premiers bits de 10.0.0.1 correspondent * 10.0.0.0, notre adresse r*seau, et notre masque de sous-r*seau est 255.0.0.0. Les autres bits rep*rent des machines directement connect*es * cette interface. Donc, 10.250.3.13 est directement disponible sur eth0, comme l'est 10.0.0.1 dans notre exemple. Avec ppp0, le m*me concept existe, bien que les nombres soient diff*rents. Son adresse est 212.64.94.251, sans masque de sous-r*seau. Cela signifie que vous avez une liaison point * point et que toutes les adresses, * l'exception de 212.64.94.251, sont distantes. Il y a cependant plus d'informations. En effet, on nous dit que de l'autre c*t* du lien, il n'y a encore qu'une seule adresse, 212.64.94.1. Le /32 nous pr*cise qu'il n'y a pas de <<*bits r*seau*>>. Il est absolument vital que vous compreniez ces concepts. R*f*rez-vous * la documentation mentionn*e au d*but de ce HOWTO si vous avez des doutes. Vous pouvez aussi noter qdisc, qui d*signe la gestion de la mise en file d'attente (Queueing Discipline). Cela deviendra vital plus tard. -------------------------------------------------------------------------- ip nous montre nos routes Nous savons maintenant comment trouver les adresses 10.x.y.z, et nous sommes capables d'atteindre 212.64.94.1. Cela n'est cependant pas suffisant, et nous avons besoin d'instructions pour atteindre le monde. L'Internet est disponible via notre connexion PPP, et il se trouve que 212.64.94.1 est pr*t * propager nos paquets * travers le monde, et * nous renvoyer le r*sultat. [ahu@home ahu]$ ip route show 212.64.94.1 dev ppp0 proto kernel scope link src 212.64.94.251 10.0.0.0/8 dev eth0 proto kernel scope link src 10.0.0.1 127.0.0.0/8 dev lo scope link default via 212.64.94.1 dev ppp0 Cela se comprend de soi-m*me. Les 4 premi*res lignes donnent explicitement ce qui *tait sous-entendu par ip address show, la derni*re ligne nous indiquant que le reste du monde peut *tre trouv* via 212.64.94.1, notre passerelle par d*faut. Nous pouvons voir que c'est une passerelle * cause du mot <<*via*>>, qui nous indique que nous avons besoin d'envoyer les paquets vers 212.64.94.1, et que c'est elle qui se chargera de tout. En r*f*rence, voici ce que l'ancien utilitaire route nous propose : [ahu@home ahu]$ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 212.64.94.1 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0 10.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 eth0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 0.0.0.0 212.64.94.1 0.0.0.0 UG 0 0 0 ppp0 -------------------------------------------------------------------------- ARP ARP est le Protocole de R*solution d'Adresse (Address Resolution Protocol). Il est d*crit dans le [162]RFC 826. ARP est utilis* par une machine d'un r*seau local pour retrouver l'adresse mat*rielle (la localisation) d'une autre machine sur le m*me r*seau. Les machines sur Internet sont g*n*ralement connues par leur nom auquel correspond une adresse IP. C'est ainsi qu'une machine sur le r*seau foo.com est capable de communiquer avec une autre machine qui est sur le r*seau bar.net. Une adresse IP, cependant, ne peut pas vous indiquer la localisation physique de la machine. C'est ici que le protocole ARP entre en jeu. Prenons un exemple tr*s simple. Supposons que j'aie un r*seau compos* de plusieurs machines, dont la machine foo d'adresse IP 10.0.0.1 et la machine bar qui a l'adresse IP 10.0.0.2. Maintenant, foo veut envoyer un ping vers bar pour voir s'il est actif, mais foo n'a aucune indication sur la localisation de bar. Donc, si foo d*cide d'envoyer un ping vers bar, il a besoin d'envoyer une requ*te ARP. Cette requ*te ARP est une fa*on pour foo de crier sur le r*seau <<*Bar (10.0.0.2) ! O* es-tu ?*>>. Par cons*quent, toutes les machines sur le r*seau entendront foo crier, mais seul bar (10.0.0.2) r*pondra. Bar enverra une r*ponse ARP directement * foo ; ce qui revient * dire : <<*Foo (10.0.0.1) ! je suis ici, * l'adresse 00:60:94:E:08:12*>>. Apr*s cette simple transaction utilis*e pour localiser son ami sur le r*seau, foo est capable de communiquer avec bar jusqu'* ce qu'il (le cache ARP de foo) oublie o* bar est situ* (typiquement au bout de 15 minutes sur Unix). Maintenant, voyons comment cela fonctionne. Vous pouvez consulter votre cache (table) ARP (neighbor) comme ceci : [root@espa041 /home/src/iputils]# ip neigh show 9.3.76.42 dev eth0 lladdr 00:60:08:3f:e9:f9 nud reachable 9.3.76.1 dev eth0 lladdr 00:06:29:21:73:c8 nud reachable Comme vous pouvez le voir, ma machine espa041 (9.3.76.41) sait o* trouver espa042 (9.3.76.42) et espagate (9.3.76.1). Maintenant, ajoutons une autre machine dans le cache ARP. [root@espa041 /home/paulsch/.gnome-desktop]# ping -c 1 espa043 PING espa043.austin.ibm.com (9.3.76.43) from 9.3.76.41 : 56(84) bytes of data. 64 bytes from 9.3.76.43: icmp_seq=0 ttl=255 time=0.9 ms 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.9/0.9/0.9 ms [root@espa041 /home/src/iputils]# ip neigh show 9.3.76.43 dev eth0 lladdr 00:06:29:21:80:20 nud reachable 9.3.76.42 dev eth0 lladdr 00:60:08:3f:e9:f9 nud reachable 9.3.76.1 dev eth0 lladdr 00:06:29:21:73:c8 nud reachable Par cons*quent, lorsque espa041 a essay* de contacter espa043, l'adresse mat*rielle de espa043 (sa localisation) a alors *t* ajout*e dans le cache ARP. Donc, tant que la dur*e de vie de l'entr*e correspondant * espa043 dans le cache ARP n'est pas d*pass*e, espa041 sait localiser espa043 et n'a plus besoin d'envoyer de requ*te ARP. Maintenant, effa*ons espa043 de notre cache ARP. [root@espa041 /home/src/iputils]# ip neigh delete 9.3.76.43 dev eth0 [root@espa041 /home/src/iputils]# ip neigh show 9.3.76.43 dev eth0 nud failed 9.3.76.42 dev eth0 lladdr 00:60:08:3f:e9:f9 nud reachable 9.3.76.1 dev eth0 lladdr 00:06:29:21:73:c8 nud stale Maintenant, espa041 a * nouveau oubli* la localisation d'espa043 et aura besoin d'envoyer une autre requ*te ARP la prochaine fois qu'il voudra communiquer avec lui. Vous pouvez aussi voir ci-dessus que l'*tat d'espagate (9.3.76.1) est pass* en stale. Cela signifie que la localisation connue est encore valide, mais qu'elle devra *tre confirm*e * la premi*re transaction avec cette machine. -------------------------------------------------------------------------- Chapitre 4. R*gles - bases de donn*es des politiques de routage Si vous avez un routeur important, il se peut que vous vouliez satisfaire les besoins de diff*rentes personnes, qui peuvent *tre trait*es diff*remment. Les bases de donn*es des politiques de routage vous aident * faire cela, en g*rant plusieurs ensembles de tables de routage. Si vous voulez utiliser cette fonctionnalit*, assurez-vous que le noyau est compil* avec les options IP : Advanced router et IP : policy routing. Quand le noyau doit prendre une d*cision de routage, il recherche quelle table consulter. Par d*faut, il y a trois tables. L'ancien outil route modifie les tables principale (main) et locale (local), comme le fait l'outil ip (par d*faut). Les r*gles par d*faut : [ahu@home ahu]$ ip rule list 0: from all lookup local 32766: from all lookup main 32767: from all lookup default Ceci liste la priorit* de toutes les r*gles. Nous voyons que toutes les r*gles sont appliqu*es * tous les paquets (from all). Nous avons vu la table main pr*c*demment, sa sortie s'effectuant avec ip route ls, mais les tables local et default sont nouvelles. Si nous voulons faire des choses fantaisistes, nous pouvons cr*er des r*gles qui pointent vers des tables diff*rentes et qui nous permettent de red*finir les r*gles de routage du syst*me. Pour savoir exactement ce que fait le noyau en pr*sence d'un assortiment de r*gles plus complet, r*f*rez-vous * la documentation ip-cref d'Alexey [NdT : dans le paquetage iproute2 de votre distribution]. -------------------------------------------------------------------------- Politique de routage simple par l'adresse source Prenons encore une fois un exemple r*el. J'ai 2 modems cble, connect*s * un routeur Linux NAT (masquerading). Les personnes habitant avec moi me paient pour avoir acc*s * Internet. Supposons qu'un de mes co-locataires consulte seulement hotmail et veuille payer moins. C'est d'accord pour moi, mais il utilisera le modem le plus lent. Le modem cble <<*rapide*>> est connu sous 212.64.94.251 et est en liaison PPP avec 212.64.94.1. Le modem cble <<*lent*>> est connu sous diverses adresses IP : 212.64.78.148 dans notre exemple avec un lien vers 195.96.98.253. La table locale : [ahu@home ahu]$ ip route list table local broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1 local 10.0.0.1 dev eth0 proto kernel scope host src 10.0.0.1 broadcast 10.0.0.0 dev eth0 proto kernel scope link src 10.0.0.1 local 212.64.94.251 dev ppp0 proto kernel scope host src 212.64.94.251 broadcast 10.255.255.255 dev eth0 proto kernel scope link src 10.0.0.1 broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1 local 212.64.78.148 dev ppp2 proto kernel scope host src 212.64.78.148 local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1 local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1 Il y a beaucoup de choses *videntes, mais aussi des choses qui ont besoin d'*tre pr*cis*es quelque peu, ce que nous allons faire. La table de routage par d*faut est vide. Regardons la table principale (main) : [ahu@home ahu]$ ip route list table main 195.96.98.253 dev ppp2 proto kernel scope link src 212.64.78.148 212.64.94.1 dev ppp0 proto kernel scope link src 212.64.94.251 10.0.0.0/8 dev eth0 proto kernel scope link src 10.0.0.1 127.0.0.0/8 dev lo scope link default via 212.64.94.1 dev ppp0 Maintenant, nous g*n*rons une nouvelle r*gle que nous appellerons John, pour notre hypoth*tique co-locataire. Bien que nous puissions travailler avec des nombres IP purs, il est plus facile d'ajouter notre table dans le fichier /etc/iproute2/rt_tables. # echo 200 John >> /etc/iproute2/rt_tables # ip rule add from 10.0.0.10 table John # ip rule ls 0: from all lookup local 32765: from 10.0.0.10 lookup John 32766: from all lookup main 32767: from all lookup default Maintenant, tout ce qu'il reste * faire est de g*n*rer la table John, et de vider le cache des routes : # ip route add default via 195.96.98.253 dev ppp2 table John # ip route flush cache Et voil* qui est fait. Il ne reste plus, comme exercice laiss* au lecteur, qu'* impl*menter cela dans ip-up. -------------------------------------------------------------------------- Routage avec plusieurs acc*s Internet/fournisseurs d'acc*s Une configuration classique est la suivante, o* deux fournisseurs d'acc*s permettent la connexion d'un r*seau local (ou m*me d'une simple machine) * Internet. ________ +--------------+ / | | | +-------------+ Fournisseur 1+------- __ | | | / ___/ \_ +------+-------+ +--------------+ | _/ \__ | if1 | / / \ | | | | R*seau Local -----+ Routeur Linux| | Internet \_ __/ | | | \__ __/ | if2 | \ \___/ +------+-------+ +--------------+ | | | | \ +-------------+ Fournisseur 2+------- | | | +--------------+ \________ Il y a g*n*ralement deux questions * se poser pour cette configuration. -------------------------------------------------------------------------- Acc*s s*par* La premi*re est de savoir comment router les r*ponses aux paquets entrants par un fournisseur particulier, disons le Fournisseur 1, vers ce m*me fournisseur. Commen*ons par d*finir quelques symboles. $IF1 sera le nom de la premi*re interface (if1 sur la figure au-dessus) et $IF2 le nom de la deuxi*me interface. $IP1 sera alors l'adresse IP associ*e * $IF1 et $IP2 sera l'adresse IP associ*e * $IF2. $P1 sera l'adresse IP de la passerelle du fournisseur d'acc*s 1 et $P2 sera l'adresse IP de la passerelle du fournisseur d'acc*s 2. Enfin, $P1_NET sera l'adresse r*seau * l'int*rieur duquel se situe $P1 et $P2_NET sera l'adresse r*seau * l'int*rieur duquel se situe $P2. Deux tables de routage suppl*mentaires sont cr**es, par exemple T1 et T2. Celles-ci sont ajout*es dans /etc/iproute2/rt_tables. La configuration du routage dans ces tables s'effectue de la fa*on suivante : ip route add $P1_NET dev $IF1 src $IP1 table T1 ip route add default via $P1 table T1 ip route add $P2_NET dev $IF2 src $IP2 table T2 ip route add default via $P2 table T2 Rien de vraiment spectaculaire. Une route est simplement positionn*e vers la passerelle et une route par d*faut via cette passerelle est mise en place, comme nous le ferions dans le cas d'un seul fournisseur d'acc*s. Ici, les routes sont plac*es dans des tables s*par*es, une par fournisseur d'acc*s. Il est * noter que la route vers le r*seau suffit, dans la mesure o* elle indique comment trouver n'importe quel h*te dans ce r*seau, ce qui inclut la passerelle. La table de routage principale est maintenant configur*e. C'est une bonne id*e de router les *l*ments * destination d'un voisin direct * travers l'interface connect*e * ce voisin. Notez les arguments "src" qui assurent que la bonne adresse IP source sera choisie. ip route add $P1_NET dev $IF1 src $IP1 ip route add $P2_NET dev $IF2 src $IP2 Indiquez maintenant votre pr*f*rence pour votre route par d*faut : ip route add default via $P1 Vous configurez ensuite les r*gles de routage. Celles-ci d*finissent la table qui sera vraiment choisie pour le routage. Il faut s'assurer que le routage s'effectue * travers une interface donn*e si vous avez l'adresse source correspondante : ip rule add from $IP1 table T1 ip rule add from $IP2 table T2 Cet ensemble de commandes vous assure que toutes les r*ponses au trafic entrant sur une interface particuli*re seront envoy*es par cette interface. +---------------------------------------------------------------------------------+ | Avertissement | |---------------------------------------------------------------------------------| |Notes d'un lecteur : si $P0_NET est le r*seau local et $IF0 est son interface, | |alors les entr*es suivantes sont d*sirables : | | | | ip route add $P0_NET dev $IF0 table T1 | | ip route add $P2_NET dev $IF2 table T1 | | ip route add 127.0.0.0/8 dev lo table T1 | | ip route add $P0_NET dev $IF0 table T2 | | ip route add $P1_NET dev $IF1 table T2 | | ip route add 127.0.0.0/8 dev lo table T2 | | | | | |' | +---------------------------------------------------------------------------------+ Nous avons maintenant une configuration tr*s basique. Elle marchera pour tous les processus ex*cut*s sur le routeur lui-m*me, ainsi que pour le r*seau local si celui-ci est masqu*. Si ce n'est pas le cas, soit vous avez une plage d'adresses IP pour chaque fournisseur d'acc*s, soit vous masquez vers l'un des deux fournisseurs d'acc*s. Dans les deux cas, vous ajouterez des r*gles indiquant, en fonction de l'adresse IP de la machine du r*seau local, vers quel fournisseur vous allez router. -------------------------------------------------------------------------- Balance de charge La seconde question concerne la balance de charge du trafic sortant vers les deux fournisseurs d'acc*s. Ceci n'est pas vraiment tr*s dur si vous avez d*j* configur* l'acc*s s*par* comme d*crit ci-dessus. Au lieu de choisir l'un des deux fournisseurs d'acc*s comme route par d*faut, celle-ci peut *tre une route multi-chemin. Par d*faut, le noyau r*partira les routes vers les deux fournisseurs d'acc*s. Ceci est r*alis* de la fa*on suivante (construit *galement sur l'exemple de la section de l'acc*s s*par*) : ip route add default scope global nexthop via $P1 dev $IF1 weight 1 \ nexthop via $P2 dev $IF2 weight 1 Ceci r*alisera la balance des routes vers les deux fournisseurs. Les param*tres weight peuvent permettre de favoriser un fournisseur par rapport * un autre. Il est * noter que la balance de charge ne sera pas parfaite dans la mesure o* elle est bas*e sur les routes et que celles-ci sont mises dans des caches. Ceci signifie que les routes vers les sites les plus souvent utilis*s passeront toujours par le m*me fournisseur d'acc*s. De plus, si vous voulez vraiment mettre en oeuvre ceci, vous devriez *galement aller consulter les mises * jour de Julien Anastasov * [163]http://www.ssi.bg/~ja/#routes Elles rendront le travail plus facile. -------------------------------------------------------------------------- Chapitre 5. GRE et autres tunnels Il y a trois sortes de tunnels sous Linux : l'IP dans un tunnel IP, le tunnel GRE et les tunnels qui existent en dehors du noyau (comme PPTP, par exemple). -------------------------------------------------------------------------- Quelques remarques g*n*rales * propos des tunnels : Les tunnels peuvent faire des choses tr*s inhabituelles et vraiment sympas. Ils peuvent aussi absolument tout d*traquer si vous ne les avez pas configur*s correctement. Ne d*finissez pas votre route par d*faut sur un tunnel, * moins que vous ne sachiez EXACTEMENT ce que vous faites. De plus, le passage par un tunnel augmente le poids des en-t*tes (overhead), puisqu'un en-t*te IP suppl*mentaire est n*cessaire. Typiquement, ce surco*t est de 20 octets par paquet. Donc, si la taille maximum de votre paquet sur votre r*seau (MTU) est de 1500 octets, un paquet qui est envoy* * travers un tunnel sera limit* * une taille de 1480 octets. Ce n'est pas n*cessairement un probl*me, mais soyez s*r d'avoir bien *tudi* la fragmentation et le r*assemblage des paquets IP quand vous pr*voyez de relier des r*seaux de grande taille par des tunnels. Et bien s*r, la mani*re la plus rapide de creuser un tunnel est de creuser des deux c*t*s. -------------------------------------------------------------------------- IP dans un tunnel IP Ce type de tunnel est disponible dans Linux depuis un long moment. Il n*cessite deux modules, ipip.o et new_tunnel.o. Disons que vous avez trois r*seaux : 2 r*seaux internes A et B, et un r*seau interm*diaire C (ou disons Internet). Les caract*ristiques du r*seau A sont : r*seau 10.0.1.0 masque de sous-r*seau 255.255.255.0 routeur 10.0.1.1 Le routeur a l'adresse 172.16.17.18 sur le r*seau C. et le r*seau B : r*seau 10.0.2.0 masque de sous-r*seau 255.255.255.0 routeur 10.0.2.1 Le routeur a l'adresse 172.19.20.21 sur le r*seau C. En ce qui concerne le r*seau C, nous supposerons qu'il transmettra n'importe quel paquet de A vers B et vice-versa. Il est *galement possible d'utiliser l'Internet pour cela. Voici ce qu'il faut faire : Premi*rement, assurez-vous que les modules soient install*s : insmod ipip.o insmod new_tunnel.o Ensuite, sur le routeur du r*seau A, faites la chose suivante : ifconfig tunl0 10.0.1.1 pointopoint 172.19.20.21 route add -net 10.0.2.0 netmask 255.255.255.0 dev tunl0 et sur le routeur du r*seau B : ifconfig tunl0 10.0.2.1 pointopoint 172.16.17.18 route add -net 10.0.1.0 netmask 255.255.255.0 dev tunl0 Et quand vous aurez termin* avec votre tunnel : ifconfig tunl0 down Vite fait, bien fait. Vous ne pouvez pas transmettre les paquets de diffusion (broadcast), ni le trafic IPv6 * travers un tunnel IP-IP. Vous ne pouvez connecter que deux r*seaux IPv4 qui, normalement, ne seraient pas capables de se <<*parler*>>, c'est tout. Dans la mesure o* la compatibilit* a *t* conserv*e, ce code tourne depuis un bon moment, et il reste compatible depuis les noyaux 1.3. Le tunnel Linux IP dans IP ne fonctionne pas avec d'autres syst*mes d'exploitation ou routeurs, pour autant que je sache. C'est simple, *a marche. Utilisez-le si vous le pouvez, autrement utilisez GRE. -------------------------------------------------------------------------- Le tunnel GRE GRE est un protocole de tunnel qui a *t* * l'origine d*velopp* par Cisco, et qui peut r*aliser plus de choses que le tunnel IP dans IP. Par exemple, vous pouvez aussi transporter du trafic multi-diffusion (multicast) et de l'IPv6 * travers un tunnel GRE. Dans Linux, vous aurez besoin du module ip_gre.o. -------------------------------------------------------------------------- Le tunnel IPv4 Dans un premier temps, int*ressons-nous au tunnel IPv4 : Disons que vous avez trois r*seaux : 2 r*seaux internes A et B, et un r*seau interm*diaire C (ou disons internet). Les caract*ristiques du r*seau A sont : r*seau 10.0.1.0 masque de sous-r*seau 255.255.255.0 routeur 10.0.1.1 Le routeur a l'adresse 172.16.17.18 sur le r*seau C. Appelons ce r*seau neta. Et pour le r*seau B : r*seau 10.0.2.0 masque de sous-r*seau 255.255.255.0 routeur 10.0.2.1 Le routeur a l'adresse 172.19.20.21 sur le r*seau C. Appelons ce r*seau netb. En ce qui concerne le r*seau C, nous supposerons qu'il transmettra n'importe quels paquets de A vers B et vice-versa. Comment et pourquoi, on s'en moque. Sur le routeur du r*seau A, nous faisons la chose suivante : ip tunnel add netb mode gre remote 172.19.20.21 local 172.16.17.18 ttl 255 ip link set netb up ip addr add 10.0.1.1 dev netb ip route add 10.0.2.0/24 dev netb Discutons un peu de cela. Sur la ligne 1, nous avons ajout* un p*riph*rique tunnel, que nous avons appel* netb (ce qui est *vident, dans la mesure o* c'est l* que nous voulons aller). De plus, nous lui avons dit d'utiliser le protocole GRE (mode gre), que l'adresse distante est 172.19.20.21 (le routeur de l'autre c*t*), que nos paquets <<*tunnel*s*>> devront *tre g*n*r*s * partir de 172.16.17.18 (ce qui autorise votre serveur * avoir plusieurs adresses IP sur le r*seau C et ainsi vous permet de choisir laquelle sera utilis*e pour votre tunnel) et que le champ TTL de vos paquets sera fix* * 255 (ttl 255). La deuxi*me ligne active le p*riph*rique. Sur la troisi*me ligne, nous avons donn* * cette nouvelle interface l'adresse 10.0.1.1. C'est bon pour de petits r*seaux, mais quand vous commencez une exploitation mini*re (BEAUCOUP de tunnels !), vous pouvez utiliser une autre gamme d'adresses IP pour vos interfaces <<*tunnel*>> (dans cet exemple, vous pourriez utiliser 10.0.3.0). Sur la quatri*me ligne, nous positionnons une route pour le r*seau B. Notez la notation diff*rente pour le masque de sous-r*seau. Si vous n'*tes pas familiaris* avec cette notation, voici comment *a marche : vous *crivez le masque de sous-r*seau sous sa forme binaire, et vous comptez tous les 1. Si vous ne savez pas comment faire cela, rappelez-vous juste que 255.0.0.0 est /8, 255.255.0.0 est /16 et 255.255.255.0 est /24. Et 255.255.254.0 est /23, au cas o* *a vous int*resserait. Mais arr*tons ici, et continuons avec le routeur du r*seau B. ip tunnel add neta mode gre remote 172.16.17.18 local 172.19.20.21 ttl 255 ip link set neta up ip addr add 10.0.2.1 dev neta ip route add 10.0.1.0/24 dev neta Et quand vous voudrez retirer le tunnel sur le routeur A : ip link set netb down ip tunnel del netb Bien s*r, vous pouvez remplacer netb par neta pour le routeur B. -------------------------------------------------------------------------- Le tunnel IPv6 Voir la section 6 pour une courte description des adresses IPv6. * propos des tunnels. Supposons que vous ayez le r*seau IPv6 suivant, et que vous vouliez le connecter * une dorsale IPv6 (6bone) ou * un ami. R*seau 3ffe:406:5:1:5:a:2:1/96 Votre adresse IPv4 est 172.16.17.18, et le routeur 6bone a une adresse IPv4 172.22.23.24. ip tunnel add sixbone mode sit remote 172.22.23.24 local 172.16.17.18 ttl 255 ip link set sixbone up ip addr add 3ffe:406:5:1:5:a:2:1/96 dev sixbone ip route add 3ffe::/15 dev sixbone Voyons cela de plus pr*s. Sur la premi*re ligne, nous avons cr** un p*riph*rique tunnel appel* sixbone. Nous lui avons affect* le mode sit (qui est le tunnel IPv6 sur IPv4) et lui avons dit o* l'on va (remote) et d'o* l'on vient (local). TTL est configur* * son maximum : 255. Ensuite, nous avons rendu le p*riph*rique actif (up). Puis, nous avons ajout* notre propre adresse r*seau et configur* une route pour 3ffe::/15 * travers le tunnel. Les tunnels GRE constituent actuellement le type de tunnel pr*f*r*. C'est un standard qui est largement adopt*, m*me * l'ext*rieur de la communaut* Linux, ce qui constitue une bonne raison de l'utiliser. -------------------------------------------------------------------------- Tunnels dans l'espace utilisateur Il y a des dizaines d'impl*mentations de tunnels * l'ext*rieur du noyau. Les plus connues sont bien s*r PPP et PPTP, mais il y en a bien plus (certaines propri*taires, certaines s*curis*s, d'autres qui n'utilisent pas IP), qui d*passent le cadre de ce HOWTO. -------------------------------------------------------------------------- Chapitre 6. Tunnel IPv6 avec Cisco et/ou une dorsale IPv6 (6bone) Par Marco Davids NOTE au mainteneur : En ce qui me concerne, ce tunnel IPv6-IPv4 n'est pas, par d*finition, un tunnel GRE. Vous pouvez r*aliser un tunnel IPv6 sur IPv4 au moyen des p*riph*riques tunnels GRE (tunnels GRE N'IMPORTE QUOI vers IPv4), mais le p*riph*rique utilis* ici (sit) ne permet que des tunnels IPv6 sur IPv4, ce qui est quelque chose de diff*rent. -------------------------------------------------------------------------- Tunnel IPv6 Voici une autre application des possibilit*s de tunnels de Linux. Celle-ci est populaire parmi les premiers adeptes d'IPv6 ou les pionniers si vous pr*f*rez. L'exemple pratique d*crit ci-dessous n'est certainement pas la seule mani*re de r*aliser un tunnel IPv6. Cependant, c'est la m*thode qui est souvent utilis*e pour r*aliser un tunnel entre Linux et un routeur Cisco IPv6 et l'exp*rience m'a appris que c'est ce type d'*quipement que beaucoup de personnes ont. Dix contre un que ceci s'appliquera aussi pour vous ;-). De petites choses * propos des adresses IPv6 : Les adresses IPv6 sont, en comparaison avec les adresses IPv4, vraiment grandes : 128 bits contre 32 bits. Et ceci nous fournit la chose dont nous avons besoin : beaucoup, beaucoup d'adresses IP : 340,282,266,920,938,463,463,374,607,431,768,211,465 pour *tre pr*cis. A part ceci, IPv6 (ou IPng g*n*ration suivante (Next Generation)) est suppos* fournir des tables de routage plus petites sur les routeurs des dorsales Internet, une configuration plus simple des *quipements, une meilleure s*curit* au niveau IP et un meilleur support pour la Qualit* de Service (QoS). Un exemple : 2002:836b:9820:0000:0000:0000:836b:9886 Ecrire les adresses IPv6 peut *tre un peu lourd. Il existe donc des r*gles qui rendent la vie plus facile : * Ne pas utiliser les z*ros de t*te, comme dans IPv4 ; * Utiliser des double-points de s*paration tous les 16 bits ou 2 octets ; * Quand vous avez beaucoup de z*ros cons*cutifs, vous pouvez *crire ::. Vous ne pouvez, cependant, faire cela qu'une seule fois par adresse et seulement pour une longueur de 16 bits. L'adresse 2002:836b:9820:0000:0000:0000:836b:9886 peut *tre *crite 2002:836b:9820::836b:9886, ce qui est plus amical. Un autre exemple : l'adresse 3ffe:0000:0000:0000:0000:0000:34A1:F32C peut *tre *crite 3ffe::20:34A1:F32C, ce qui est beaucoup plus court. IPv6 a pour but d'*tre le successeur de l'actuel IPv4. Dans la mesure o* cette technologie est relativement r*cente, il n'y a pas encore de r*seau natif IPv6 * l'*chelle mondiale. Pour permettre un d*veloppement rapide, la dorsale IPv6 (6bone) a *t* introduite. Les r*seaux natifs IPv6 sont interconnect*s grce * l'encapsulation du protocole IPv6 dans des paquets IPv4, qui sont envoy*s * travers l'infrastructure IPv4 existante, d'un site IPv6 * un autre. C'est dans cette situation que l'on monte un tunnel. Pour *tre capable d'utiliser IPv6, vous devrez avoir un noyau qui le supporte. Il y a beaucoup de bons documents qui expliquent la mani*re de r*aliser cela. Mais, tout se r*sume * quelques *tapes : * R*cup*rer une distribution Linux r*cente, avec une glibc convenable. * R*cup*rer alors les sources * jour du noyau. Si tout cela est fait, vous pouvez alors poursuivre en compilant un noyau supportant l'IPv6 : * Aller dans /usr/src/linux et tapez : * make menuconfig * Choisir Networking Options * S*lectionner The IPv6 protocol, IPv6: enable EUI-64 token format, IPv6: disable provider based addresses ASTUCE :Ne compiler pas ces options en tant que module. Ceci ne marchera souvent pas bien. En d'autres termes, compilez IPv6 directement dans votre noyau. Vous pouvez alors sauvegarder votre configuration comme d'habitude et entreprendre la compilation de votre noyau. ASTUCE: Avant de faire cela, modifier votre Makefile comme suit : EXTRAVERSION = -x ; --> ; EXTRAVERSION = -x-IPv6 Il y a beaucoup de bonnes documentations sur la compilation et l'installation d'un noyau. Cependant, ce document ne traite pas de ce sujet. Si vous rencontrez des probl*mes * ce niveau, allez et recherchez dans la documentation des renseignements sur la compilation du noyau Linux correspondant * vos propres sp*cifications. Le fichier /usr/src/linux/README peut constituer un bon d*part. Apr*s avoir r*alis* tout ceci, et red*marr* avec votre nouveau noyau flambant neuf, vous pouvez lancer la commande /sbin/ifconfig -a et noter un nouveau p*riph*rique sit0. SIT signifie Transition Simple d'Internet (Simple Internet Transition). Vous pouvez vous auto complimenter : vous avez maintenant franchi une *tape importante vers IP, la prochaine g*n*ration ;-) Passons maintenant * l'*tape suivante. Vous voulez connecter votre h*te ou peut-*tre m*me tout votre r*seau LAN * d'autres r*seaux IPv6. Cela pourrait *tre la dorsale IPv6 <<*6bone*>> qui a *t* sp*cialement mise en place dans ce but particulier. Supposons que vous avez le r*seau IPv6 suivant : 3ffe:604:6:8::/64 et que vous vouliez le connecter * une dorsale IPv6 ou * un ami. Notez, s'il vous pla*t, que la notation sous-r*seau /64 est similaire * celle des adresses IPv4. Votre adresse IPv4 est 145.100.24.181 et le routeur 6bone a l'adresse IPv4 145.100.1.5. # ip tunnel add sixbone mode sit remote 145.100.1.5 [local 145.100.24.181 ttl 225] # ip link set sixbone up # ip addr add 3FFE:604:6:7::2/96 dev sixbone # ip route add 3ffe::0/15 dev sixbone Discutons de ceci. Dans la premi*re ligne, nous avons cr** un p*riph*rique appel* sixbone. Nous lui avons donn* l'attribut sit (mode sit) (qui est le tunnel IPv6 dans IPv4) et nous lui avons dit o* aller (remote) et d'o* nous venions (local). TTL est configur* * son maximum, 255. Ensuite, nous avons rendu le p*riph*rique actif (up). Apr*s cela, nous avons ajout* notre propre adresse r*seau et configur* une route pour 3ffe::/15 (qui est actuellement la totalit* du 6bone) * travers le tunnel. Si la machine sur laquelle vous mettez en place tout ceci est votre passerelle IPv6, ajoutez alors les lignes suivantes : # echo 1 >/proc/sys/net/ipv6/conf/all/forwarding # /usr/local/sbin/radvd En derni*re instruction, radvd est un d*mon d'annonce comme zebra qui permet de supporter les fonctionnalit*s d'autoconfiguration d'IPv6. Recherchez le avec votre moteur de recherche favori. Vous pouvez v*rifier les choses comme ceci : # /sbin/ip -f inet6 addr Si vous arrivez * avoir radvd tournant sur votre passerelle IPv6 et que vous d*marrez une machine avec IPv6 sur votre r*seau local, vous serez ravi de voir les b*n*fices de l'autoconfiguration IPv6 : # /sbin/ip -f inet6 addr 1: lo: mtu 3924 qdisc noqueue inet6 ::1/128 scope host 3: eth0: mtu 1500 qdisc pfifo_fast qlen 100 inet6 3ffe:604:6:8:5054:4cff:fe01:e3d6/64 scope global dynamic valid_lft forever preferred_lft 604646sec inet6 fe80::5054:4cff:fe01:e3d6/10 scope link Vous pouvez maintenant configurer votre serveur de noms pour les adresses IPv6. Le type A a un *quivalent pour IPv6 : AAAA. L'*quivalent de in-addr.arpa est : ip6.int. Il y a beaucoup d'informations disponibles sur ce sujet. Il y a un nombre croissant d'applications IPv6 disponibles, comme le shell s*curis*, telnet, inetd, le navigateur Mozilla, le serveur web Apache et beaucoup d'autres. Mais ceci est en dehors du sujet de ce document de routage ;-). Du c*t* Cisco, la configuration ressemblera * ceci : ! interface Tunnel1 description IPv6 tunnel no ip address no ip directed-broadcast ipv6 address 3FFE:604:6:7::1/96 tunnel source Serial0 tunnel destination 145.100.24.181 tunnel mode ipv6ip ! ipv6 route 3FFE:604:6:8::/64 Tunnel1 Si vous n'avez pas un Cisco * votre disposition, essayez un des prestataires de tunnel IPv6 disponible sur Internet. Ils sont pr*ts * configurer leur Cisco avec un tunnel suppl*mentaire pour vous, le plus souvent au moyen d'une agr*able interface web. Cherchez ipv6 tunnel broker avec votre moteur de recherche favori. -------------------------------------------------------------------------- Chapitre 7. IPSEC: IP s*curis* * travers Internet A ce jour, deux versions d'IPSEC sont disponibles pour Linux. FreeS/WAN, qui f*t la premi*re impl*mentation majeure, existe pour les noyaux Linux 2.2 et 2.4. Ce projet a [164]un site officiel et *galement [165]un site non officiel, qui est bien maintenu. FreeS/WAN n'a jamais *t* int*gr* dans le noyau pour un certain nombre de raisons. Celle qui est la plus souvent mentionn*e concerne un probl*me "politique" avec les am*ricains travaillant sur la cryptographie qui freinent son exportabilit*. De plus, la mise en place de FreeS/WAN dans le noyau Linux est d*licate, ce qui n'en fait pas un bon candidat pour une r*elle int*gration. De plus, [166]des personnes [167]se sont inqui*t*es de la qualit* du code. Pour configurer FreeS/WAN, de nombreuses [168]documentations sont [169]disponibles. Une impl*mentation native d'IPSEC est pr*sente dans le noyau * partir de la version Linux 2.5.47. Elle a *t* *crite par Alexey Kuznetsov et Dave Miller, qui se sont inspir*s des travaux du groupe USAGI IPv6. Avec cette fusion, les CryptoAPI de James Morris deviennent *galement une partie du noyau, qui fait ainsi vraiment du cryptage. Ce HOWTO ne documente que la version 2.5 d'IPSEC. FreeS/WAN est recommand* pour l'instant pour les utilisateurs de Linux 2.4. Fa*tes cependant attention, dans la mesure o* sa configuration est diff*rente de l'IPSEC natif. Il y a maintenant une [170]mise * jour qui permet au code FreeS/WAN de l'espace utilisateur de fonctionner avec l'IPSEC natif de Linux. A partir du noyau 2.5.49, IPSEC fonctionne sans l'ajout de mises * jour suppl*mentaires. Note*: Les outils de l'espace utilisateur sont disponibles [171]ici. Il y a plusieurs programmes disponibles ; celui qui est propos* dans le lien est bas* sur Racoon. Lors de la compilation du noyau, soyez s*r d'activer 'PF_KEY', 'AH' et tous les *l*ments de CryptoAPI ! +------------------------------------------------------------------------+ | Avertissement | |------------------------------------------------------------------------| | L'auteur de ce chapitre est un complet nigaud en ce qui concerne | | IPSEC ! Si vous trouvez les in*vitables erreurs, envoyez un courrier | | *lectronique * Bert Hubert <[172]ahu@ds9a.nl>. | +------------------------------------------------------------------------+ Tout d'abord, nous montrerons comment configurer manuellement une communication s*curis*e entre deux h*tes. Une grande partie de ce processus peut *tre automatis*e, mais nous le ferons ici * la main afin de comprendre ce qui se passe "sous le capot". Passez * la section suivante si la seule gestion automatique des cl*s vous int*resse. Soyez cependant conscient que la compr*hension de la gestion manuelle des cl*s est utile. -------------------------------------------------------------------------- Introduction sur la gestion manuelle des cl*s IPSEC est un sujet compliqu*. De nombreuses informations sont disponibles en ligne. Ce HOWTO se concentrera sur la mise en place et * l'explication des principes de base. Tous les exemples sont bas*s sur Racoon dont le lien est donn* au-dessus. Note*: Certaines configurations iptables rejettent les paquets IPSEC ! Pour transmettre IPSEC, utilisez : iptables -A xxx -p 50 -j ACCEPT et 'iptables -A xxx -p 51 -j ACCEPT. IPSEC offre une version s*curis*e de la couche IP (Internet Protocol). La s*curit* dans ce contexte prend deux formes : l'encryptage et l'authentification. Une vision nave de la s*curit* ne propose que le cryptage. On peut cependant montrer facilement que c'est insuffisant : il se peut que vous ayez une communication crypt*e, mais vous n'avez aucune garantie que l'h*te distant est bien celui auquel vous pensez. IPSEC supporte 'Encapsulated Security Payload' (Encapsulation S*curis*e de la Charge utile) (ESP) pour le cryptage et 'Authentication Header' (Ent*te d'Authentification) (AH) pour authentifier le partenaire distant. Vous pouvez configurer les deux, ou d*cider de ne faire que l'un des deux. ESP et AH s'appuient tous les deux sur des Associations de S*curit* (Security Associations (SA)). Une Association de S*curit* (SA) consiste en une source, une destination et une instruction. Un exemple simple d'Association de S*curit* (SA) pour l'authentification peut ressembler * ceci : add 10.0.0.11 10.0.0.216 ah 15700 -A hmac-md5 "1234567890123456"; Ceci indique que le trafic allant de 10.0.0.11 vers 10.0.0.216 a besoin d'un En-t*te d'Authentification (AH) qui peut *tre sign* en utilisant HMAC-MD et le secret 1234567890123456. Cette instruction est rep*r*e par l'identificateur SPI (Security Parameter Index) 15700, dont nous parlerons plus par la suite. Le point int*ressant * propos des Associations de S*curit* (SA) est qu'elles sont sym*triques. Les deux cot*s de la conversation partagent exactement la m*me Association de S*curit* (SA), qui n'est pas recopi*e sur l'h*te distant. Notez cependant qu'il n'y a pas de r*gles "d'inversion automatique". Cette Association de S*curit* (SA) d*crit une authentification possible de 10.0.0.11 vers 10.0.0.216. Pour un trafic bidirectionnel, deux Associations de S*curit* (SA) sont n*cessaires. Un exemple d'Association de S*curit* (SA) pour le cryptage ESP : add 10.0.0.11 10.0.0.216 esp 15701 -E 3des-cbc "123456789012123456789012"; Ceci signifie que le trafic allant de 10.0.0.11 vers 10.0.0.216 est chiffr* en utilisant 3des-cbc avec la cl* 123456789012123456789012. L'identificateur SPI est 15701. Jusqu'ici, nous avons vu que les Associations de S*curit* (SA) d*crivent les instructions possibles, mais pas la politique qui indique quand ces SA doivent *tre utilis*es. En fait, il pourrait y avoir un nombre arbitraire de SA presques identiques ne se diff*renciant que par les identificateurs SPI. Entre parenth*ses, SPI signifie Security Parameter Index, ou Index du Param*tre de S*curit* en fran*ais. Pour faire vraiment du cryptage, nous devons d*crire une politique. Cette politique peut inclure des choses comme "utiliser ipsec s'il est disponible" ou "rejeter le trafic * moins que vous ayez ipsec". Une "Politique de S*curit*" (Security Policy (SP)) typique ressemble * ceci : spdadd 10.0.0.216 10.0.0.11 any -P out ipsec esp/transport//require ah/transport//require; Si cette configuration est appliqu*e sur l'h*te 10.0.0.216, cela signifie que tout le trafic allant vers 10.0.0.11 doit *tre encrypt* et encapsul* dans un en-t*te d'authentification AH. Notez que ceci ne d*crit pas quelle SA sera utilis*e. Cette d*termination est un exercice laiss* * la charge du noyau. En d'autres termes, une Politique de S*curit* sp*cifie CE QUE nous voulons ; une Association de S*curit* d*crit COMMENT nous le voulons. Les paquets sortants sont *tiquet*s avec le SPI SA ('le comment') que le noyau utilise pour l'encryptage et l'authentification et l'h*te distant peut consulter les instructions de v*rification et de d*cryptage correspondantes. Ce qui suit est une configuration tr*s simple permettant le dialogue de l'h*te 10.0.0.216 vers l'h*te 10.0.0.11 en utilisant l'encryptage et l'authentification. Notez que le trafic de retour de cette premi*re version est en clair et que cette configuration ne doit pas *tre d*ploy*e. Sur l'h*te 10.0.0.216 : #!/sbin/setkey -f add 10.0.0.216 10.0.0.11 ah 24500 -A hmac-md5 "1234567890123456"; add 10.0.0.216 10.0.0.11 esp 24501 -E 3des-cbc "123456789012123456789012"; spdadd 10.0.0.216 10.0.0.11 any -P out ipsec esp/transport//require ah/transport//require; Sur l'h*te 10.0.0.11, nous donnons les m*mes Associations de S*curit* (SA). Nous ne donnons pas de Politique de S*curit* : #!/sbin/setkey -f add 10.0.0.216 10.0.0.11 ah 24500 -A hmac-md5 "1234567890123456"; add 10.0.0.216 10.0.0.11 esp 24501 -E 3des-cbc "123456789012123456789012"; Avec la mise en place de la configuration ci-dessus (ces fichiers peuvent *tre ex*cut*s si 'setkey' est install* dans /sbin), la commande ping 10.0.0.11 ex*cut*e sur 10.0.0.216 va donner la sortie suivante avec tcpdump : 22:37:52 10.0.0.216 > 10.0.0.11: AH(spi=0x00005fb4,seq=0xa): ESP(spi=0x00005fb5,seq=0xa) (DF) 22:37:52 10.0.0.11 > 10.0.0.216: icmp: echo reply Notez que le paquet de retour provenant de 10.0.0.11 est en effet compl*tement visible. Le paquet ping *mis par 10.0.0.216 ne peut *videmment pas *tre lu par tcpdump, mais celui-ci montre l'Index du Param*tre de S*curit* (SPI) de l'AH, ainsi que l'ESP, qui indique * 10.0.0.11 comment v*rifier l'authenticit* de notre paquet et comment le d*crypter. Quelques *l*ments doivent *tre mentionn*s. La configuration ci-dessus est propos*e dans de nombreux exemples d'IPSEC, mais elle est tr*s dangereuse. Le probl*me est qu'elle contient la politique indiquant * 10.0.0.216 comment traiter les paquets allant vers 10.0.0.11 et comment 10.0.0.11 doit traiter ces paquets, mais ceci n'INDIQUE pas * 10.0.0.11 de rejeter le trafic non authentifi* et non encrypt* ! N'importe qui peut maintenant ins*rer des donn*es "spoof*es" (NdT : usurp*es) et enti*rement non crypt*es que 10.0.0.1 acceptera. Pour rem*dier * ceci, nous devons avoir sur 10.0.0.11 une Politique de S*curit* pour le trafic entrant : #!/sbin/setkey -f spdadd 10.0.0.216 10.0.0.11 any -P IN ipsec esp/transport//require ah/transport//require; Ceci indique * 10.0.0.11 que tout le trafic venant de 10.0.0.216 n*cessite d'avoir un ESP et AH valide. Maintenant, pour compl*ter cette configuration, nous devons *galement renvoyer un trafic encrypt* et authentifi*. La configuration compl*te sur 10.0.0.216 est la suivante : #!/sbin/setkey -f flush; spdflush; # AH add 10.0.0.11 10.0.0.216 ah 15700 -A hmac-md5 "1234567890123456"; add 10.0.0.216 10.0.0.11 ah 24500 -A hmac-md5 "1234567890123456"; # ESP add 10.0.0.11 10.0.0.216 esp 15701 -E 3des-cbc "123456789012123456789012"; add 10.0.0.216 10.0.0.11 esp 24501 -E 3des-cbc "123456789012123456789012"; spdadd 10.0.0.216 10.0.0.11 any -P out ipsec esp/transport//require ah/transport//require; spdadd 10.0.0.11 10.0.0.216 any -P in ipsec esp/transport//require ah/transport//require; Et sur 10.0.0.11 : #!/sbin/setkey -f flush; spdflush; # AH add 10.0.0.11 10.0.0.216 ah 15700 -A hmac-md5 "1234567890123456"; add 10.0.0.216 10.0.0.11 ah 24500 -A hmac-md5 "1234567890123456"; # ESP add 10.0.0.11 10.0.0.216 esp 15701 -E 3des-cbc "123456789012123456789012"; add 10.0.0.216 10.0.0.11 esp 24501 -E 3des-cbc "123456789012123456789012"; spdadd 10.0.0.11 10.0.0.216 any -P out ipsec esp/transport//require ah/transport//require; spdadd 10.0.0.216 10.0.0.11 any -P in ipsec esp/transport//require ah/transport//require; Notez que, dans cet exemple, nous avons utilis* des cl*s identiques pour les deux directions du trafic. Ceci n'est cependant en aucun cas exig*. Pour examiner la configuration que nous venons de cr*er, ex*cuter setkey -D, qui montre les SA ou setkey -DP qui montre les politiques configur*es. -------------------------------------------------------------------------- Gestion automatique des cl*s Dans la section pr*c*dente, l'encryptage *tait configur* pour utiliser simplement le partage de secrets. En d'autres termes, pour rester s*curis*, nous devons transf*rer la configuration de notre encryptage * travers un tunnel s*curis*. Si nous avons configur* l'h*te distant par telnet, n'importe quel tiers pourrait avoir pris connaissance de notre secret partag* et, ainsi, notre configuration ne serait plus s*re. De plus, puisque le secret est partag*, ce n'est pas un secret. L'h*te distant ne peut pas en faire grand chose, mais nous devons *tre s*rs d'utiliser un secret diff*rent pour les communications avec tous nos partenaires. Ceci n*cessite un grand nombre de cl*s. Pour 10 partenaires, nous devrions avoir au moins 50 secrets diff*rents. En plus du probl*me des cl*s sym*triques, le renouvellement des cl*s est *galement n*cessaire. Si un tiers *coute suffisamment le trafic, il peut *tre en position de retrouver la cl* par r*tro ing*nierie. On peut s'en pr*munir en modifiant la cl* de temps en temps, mais ce processus a besoin d'*tre automatis*. Un autre probl*me est que la gestion manuelle des cl*s d*crite au-dessus impose de d*finir pr*cis*ment les algorithmes et les longueurs de cl*s utilis*es, ce qui n*cessite une grande coordination avec l'h*te distant. Il serait pr*f*rable d'avoir la capacit* * d*crire une politique des cl*s plus large comme par exemple "Nous pouvons faire du 3DES et du Blowfish avec les longueurs de cl*s suivantes". Pour r*soudre ces probl*mes, IPSEC fournit l'Echange de Cl* sur Internet (Internet Key Echange (IKE)) permettant d'automatiser l'*change de cl*s g*n*r*es al*atoirement. Ces cl*s sont transmises en utilisant une technologie d'encryptage asym*trique n*goci*e. L'impl*mentation IPSEC de Linux 2.5 fonctionne avec le d*mon IKE "KAME racoon". Depuis le 9 novembre, la version de racoon pr*sente la distribution iptools d'Alexey peut *tre compil*e en supprimant, au pr*alable #include dans deux fichiers. Je fournis une [173]version pr*compil*e. Note*: L'Echange de Cl* sur Internet (IKE) doit avoir acc*s au port UDP 500. Soyez s*r que iptables ne le bloque pas. -------------------------------------------------------------------------- Th*orie Comme expliqu* avant, la gestion automatique des cl*s r*alise beaucoup d'op*rations pour nous. Sp*cifiquement, il cr*e * la vol*e les Associations de S*curit*. Il ne configure cependant pas la politique pour nous, ce qui est le fonctionnement attendu. Donc, pour b*n*ficier de IKE, configurez une politique, mais ne fournissez aucune Association de S*curit*. Si le noyau d*couvre qu'il y a une politique IPSEC, mais pas d'Association de S*curit*, il va le notifier au d*mon IKE qui va chercher * en n*gocier une. De nouveau, rappelons que la Politique de S*curit* sp*cifie CE QUE nous voulons tandis que l'Association de S*curit* d*crit COMMENT nous le voulons. L'utilisation de la gestion automatique des cl*s nous permet de ne sp*cifier que ce que nous voulons. -------------------------------------------------------------------------- Exemple Kame racoon poss*de un grand nombre d'options dont la plupart des valeurs par d*faut sont corrects ; nous n'avons donc pas besoin de les modifier. Comme nous l'avons dit auparavant, l'op*rateur doit d*finir une Politique de S*curit*, mais pas d'Associations de S*curit*. Nous laissons cette n*gociation au d*mon IKE. Dans cet exemple, 10.0.0.1 et 10.0.0.216 sont encore une fois sur le point d'*tablir des communications s*curis*es mais, cette fois, avec l'aide du d*mon racoon. Par soucis de simplification, cette configuration utilisera des cl*s pr*-partag*es, les redout*s 'secrets partag*s'. Nous discuterons des certificats X.509 dans une section * part. Voir [174]la section intitul*e Gestion automatique des cl*s en utilisant les certificats X.509>. Nous allons * peu pr*s rester fid*le * la configuration par d*faut, qui est identique sur les deux h*tes : path pre_shared_key "/usr/local/etc/racoon/psk.txt"; remote anonymous { exchange_mode aggressive,main; doi ipsec_doi; situation identity_only; my_identifier address; lifetime time 2 min; # sec,min,hour initial_contact on; proposal_check obey; # obey, strict or claim proposal { encryption_algorithm 3des; hash_algorithm sha1; authentication_method pre_shared_key; dh_group 2 ; } } sainfo anonymous { pfs_group 1; lifetime time 2 min; encryption_algorithm 3des ; authentication_algorithm hmac_sha1; compression_algorithm deflate ; } Beaucoup de param*tres. Je pense que l'on peut encore en supprimer pour se rapprocher de la configuration par d*faut. Remarquons ici quelques *l*ments notables. Nous avons configur* deux sections "anonymous", ce qui convient pour tous les h*tes distants. Ceci va ainsi faciliter les configurations suppl*mentaires. Il n'est pas n*cessaire d'avoir de sections sp*cifiques * une machine particuli*re, * moins que vous ne le vouliez vraiment. De plus, la configuration pr*cise que nous nous identifions grce * notre adresse IP ('my_identifier address') et que nous pouvons faire du 3des, sha1 et que nous utiliserons une cl* "pr*-partag*e" se trouvant dans psk.txt. Dans le fichier psk.txt, nous avons configur* deux entr*es qui sont diff*rentes suivant les h*tes. Sur 10.0.0.11 : 10.0.0.216 password2 Sur 10.0.0.216 : 10.0.0.11 password2 Soyez s*r que ces fichiers sont la propri*t* de root, et qu'ils ont le mode 0600. Dans le cas contraire, racoon ne pourra faire confiance * leur contenu. Notez que ces fichiers sont sym*triques l'un de l'autre. Nous sommes maintenant pr*t * configurer notre politique qui est assez simple. Sur l'h*te 10.0.0.216 : #!/sbin/setkey -f flush; spdflush; spdadd 10.0.0.216 10.0.0.11 any -P out ipsec esp/transport//require; spdadd 10.0.0.11 10.0.0.216 any -P in ipsec esp/transport//require; Et sur 10.0.0.11 : #!/sbin/setkey -f flush; spdflush; spdadd 10.0.0.11 10.0.0.216 any -P out ipsec esp/transport//require; spdadd 10.0.0.216 10.0.0.11 any -P in ipsec esp/transport//require; Noter que ces politiques sont encore une fois sym*triques. Nous sommes maintenant pr*t * lancer racoon ! Une fois lanc*, au moment o* nous essayons une connexion un telnet depuis 10.0.0.11 vers 10.0.0.216, ou l'inverse, racoon aura d*marr* la n*gociation : 12:18:44: INFO: isakmp.c:1689:isakmp_post_acquire(): IPsec-SA request for 10.0.0.11 queued due to no phase1 found. 12:18:44: INFO: isakmp.c:794:isakmp_ph1begin_i(): initiate new phase 1 negotiation: 10.0.0.216[500]<=>10.0.0.11[500] 12:18:44: INFO: isakmp.c:799:isakmp_ph1begin_i(): begin Aggressive mode. 12:18:44: INFO: vendorid.c:128:check_vendorid(): received Vendor ID: KAME/racoon 12:18:44: NOTIFY: oakley.c:2037:oakley_skeyid(): couldn't find the proper pskey, try to get one by the peer's address. 12:18:44: INFO: isakmp.c:2417:log_ph1established(): ISAKMP-SA established 10.0.0.216[500]-10.0.0.11[500] spi:044d25dede78a4d1:ff01e5b4804f0680 12:18:45: INFO: isakmp.c:938:isakmp_ph2begin_i(): initiate new phase 2 negotiation: 10.0.0.216[0]<=>10.0.0.11[0] 12:18:45: INFO: pfkey.c:1106:pk_recvupdate(): IPsec-SA established: ESP/Transport 10.0.0.11->10.0.0.216 spi=44556347(0x2a7e03b) 12:18:45: INFO: pfkey.c:1318:pk_recvadd(): IPsec-SA established: ESP/Transport 10.0.0.216->10.0.0.11 spi=15863890(0xf21052) L'ex*cution de la commande setkey -D, qui nous montre les Associations de S*curit*, nous indique qu'elles sont en effet pr*sentes : 10.0.0.216 10.0.0.11 esp mode=transport spi=224162611(0x0d5c7333) reqid=0(0x00000000) E: 3des-cbc 5d421c1b d33b2a9f 4e9055e3 857db9fc 211d9c95 ebaead04 A: hmac-sha1 c5537d66 f3c5d869 bd736ae2 08d22133 27f7aa99 seq=0x00000000 replay=4 flags=0x00000000 state=mature created: Nov 11 12:28:45 2002 current: Nov 11 12:29:16 2002 diff: 31(s) hard: 600(s) soft: 480(s) last: Nov 11 12:29:12 2002 hard: 0(s) soft: 0(s) current: 304(bytes) hard: 0(bytes) soft: 0(bytes) allocated: 3 hard: 0 soft: 0 sadb_seq=1 pid=17112 refcnt=0 10.0.0.11 10.0.0.216 esp mode=transport spi=165123736(0x09d79698) reqid=0(0x00000000) E: 3des-cbc d7af8466 acd4f14c 872c5443 ec45a719 d4b3fde1 8d239d6a A: hmac-sha1 41ccc388 4568ac49 19e4e024 628e240c 141ffe2f seq=0x00000000 replay=4 flags=0x00000000 state=mature created: Nov 11 12:28:45 2002 current: Nov 11 12:29:16 2002 diff: 31(s) hard: 600(s) soft: 480(s) last: hard: 0(s) soft: 0(s) current: 231(bytes) hard: 0(bytes) soft: 0(bytes) allocated: 2 hard: 0 soft: 0 sadb_seq=0 pid=17112 refcnt=0 Nous avons les Politiques de S*curit* que nous avons nous-m*me configur*es : 10.0.0.11[any] 10.0.0.216[any] tcp in ipsec esp/transport//require created:Nov 11 12:28:28 2002 lastused:Nov 11 12:29:12 2002 lifetime:0(s) validtime:0(s) spid=3616 seq=5 pid=17134 refcnt=3 10.0.0.216[any] 10.0.0.11[any] tcp out ipsec esp/transport//require created:Nov 11 12:28:28 2002 lastused:Nov 11 12:28:44 2002 lifetime:0(s) validtime:0(s) spid=3609 seq=4 pid=17134 refcnt=3 -------------------------------------------------------------------------- Probl*mes et d*fauts connus Si cela ne marche pas, v*rifiez que tous les fichiers de configuration sont la propri*t* de root et qu'ils ne peuvent *tre lus que par celui-ci. Pour d*marrer racoon en avant-plan, utilisez '-F'. Pour le forcer * lire un fichier de configuration * la place de celui pr*cis* lors de la compilation, utilisez '-f'. Pour obtenir de nombreux d*tails, ajouter l'option 'log debug' dans le fichier racoon.conf. -------------------------------------------------------------------------- Gestion automatique des cl*s en utilisant les certificats X.509 Comme nous l'avons dit avant, l'utilisation de secrets partag*s est compliqu*e car ils ne peuvent pas *tre facilement partag*s et, une fois qu'ils le sont, ils ne sont plus secrets. Heureusement, nous avons la technologie d'encryptage asymm*trique pour nous aider * r*soudre ce probl*me. Si chaque participant d'une liaison IPSEC cr*e une cl* publique et priv*e, des communications s*curis*es peuvent *tre mises en place par les deux parties en publiant leur cl* publique et en configurant leur politique. Cr*er une cl* est relativement facile, bien que cela exige un peu de travail. Ce qui suit est bas* sur l'outil 'openssl'. -------------------------------------------------------------------------- Construire un certificat X.509 pour votre h*te OpenSSL dispose d'une importante infrastructure de gestions des clefs, capable de g*rer des clefs sign*es ou non par une autorit* de certification. Pour l'instant, nous avons besoin de court-circuiter toute cette infrastructure et de mettre en place une s*curit* de charlatan, et de travailler sans autorit* de certification. Nous allons tout d'abord cr*er une requ*te de certificat (certificate request) pour notre h*te, appel* 'laptop' : $ openssl req -new -nodes -newkey rsa:1024 -sha1 -keyform PEM -keyout \ laptop.private -outform PEM -out request.pem Des questions nous sont pos*es : Country Name (2 letter code) [AU]:NL State or Province Name (full name) [Some-State]:. Locality Name (eg, city) []:Delft Organization Name (eg, company) [Internet Widgits Pty Ltd]:Linux Advanced Routing & Traffic Control Organizational Unit Name (eg, section) []:laptop Common Name (eg, YOUR name) []:bert hubert Email Address []:ahu@ds9a.nl Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Vous avez toute libert* quant aux r*ponses. Vous pouvez ou non mettre le nom d'h*te, en fonction de vos besoins de s*curit*. C'est ce que nous avons fait dans cet exemple. Nous allons maintenant "auto signer" cette requ*te : $ openssl x509 -req -in request.pem -signkey laptop.private -out \ laptop.public Signature ok subject=/C=NL/L=Delft/O=Linux Advanced Routing & Traffic \ Control/OU=laptop/CN=bert hubert/Email=ahu@ds9a.nl Getting Private key Le fichier "request.pem" peut maintenant *tre *limin*. R*p*tez cette proc*dure pour tous les h*tes qui ont besoin d'une cl*. Vous pouvez distribuer le fichier '.public' en toute impunit*, mais garder le fichier '.private' priv* ! -------------------------------------------------------------------------- Configuration et lancement Une fois que nous avons les cl*s publiques et priv*es pour nos h*tes, nous pouvons indiquer * racoon de les utiliser. Reprenons notre configuration pr*c*dente et les deux h*tes 10.0.0.11 ('upstairs') et 10.0.0.216 ('laptop'). Dans le fichier racoon.conf pr*sent sur 10.0.0.11, nous ajoutons : path certificate "/usr/local/etc/racoon/certs"; remote 10.0.0.216 { exchange_mode aggressive,main; my_identifier asn1dn; peers_identifier asn1dn; certificate_type x509 "upstairs.public" "upstairs.private"; peers_certfile "laptop.public"; proposal { encryption_algorithm 3des; hash_algorithm sha1; authentication_method rsasig; dh_group 2 ; } } Ceci indique * racoon que les certificats se trouvent dans /usr/local/etc/racoon/certs/. De plus, il contient des *l*ments sp*cifiques pour l'h*te distant 10.0.0.216. La ligne 'asn1dn' indique * racoon que l'identification pour l'h*te local et distant doit *tre extraite des cl*s publiques. Ceci correspond * la ligne 'subject=/C=NL/L=Delft/O=Linux Advanced Routing & Traffic Control/OU=laptop/CN=bert hubert/Email=ahu@ds9a.nl' donn* au-dessus. La ligne certificate_type pr*cise l'emplacement des cl*s publiques et priv*es locales. La d*claration peers_certfile pr*cise * racoon que la cl* publique de l'h*te distant se trouve dans le fichier laptop.public. La section proposal reste inchang*e par rapport * ce que nous avons vu plus t*t, * l'exception de authentification_method qui est maintenant rsasig, ce qui indique l'utilisation de cl* RSA publique/priv*e pour l'authentification. La configuration ajout*e sur 10.0.0.216 est presque identique, exception faite de l'habituelle sym*trie : path certificate "/usr/local/etc/racoon/certs"; remote 10.0.0.11 { exchange_mode aggressive,main; my_identifier asn1dn; peers_identifier asn1dn; certificate_type x509 "laptop.public" "laptop.private"; peers_certfile "upstairs.public"; proposal { encryption_algorithm 3des; hash_algorithm sha1; authentication_method rsasig; dh_group 2 ; } } Maintenant que nous avons ajout* ces *l*ments sur les deux h*tes, la seule chose qui reste * faire est de mettre en place les fichiers contenant les cl*s. La machine 'upstairs' doit avoir les fichiers upstairs.private, upstairs.public, et laptop.public plac*s dans /usr/local/etc/racoon/certs. Soyez s*r que le r*pertoire est la propri*t* de root et qu'il poss*de les droits 0700. Dans le cas contraire, racoon pourrait refuser de lire le contenu de ce r*pertoire. La machine 'laptop' doit avoir les fichiers upstairs.private, upstairs.public, et laptop.public plac*s dans /usr/local/etc/racoon/certs. Autrement dit, chaque h*te doit avoir ses propres cl*s publique et priv*e et, de plus, la cl* publique de l'h*te distant. V*rifiez que la Politique de S*curit* est en place (ex*cutez la commande 'spdadd' vue dans [175]la section intitul*e Exemple>). Lancez alors racoon et tout devrait fonctionner. -------------------------------------------------------------------------- Comment configurer des tunnels s*curis*s Pour configurer des communications s*curis*es avec un h*te distant, nous devons *changer des cl*s publiques. Bien qu'il ne soit pas n*cessaire que la cl* publique reste secr*te, il est important d'*tre s*r que cette cl* n'a pas *t* modifi*e. En d'autres termes, vous devez *tre certain qu'il n'y a pas de 'man in the middle'. [NdT : 'man in the middle' est le nom d'une attaque qui consiste * se placer entre l'h*te *metteur et l'h*te de destination] Pour faciliter ceci, OpenSSL propose la commande 'digest' : $ openssl dgst upstairs.public MD5(upstairs.public)= 78a3bddafb4d681c1ca8ed4d23da4ff1 La seule chose que nous devons faire est de v*rifier que notre partenaire distant voit la m*me empreinte. Ceci peut *tre effectu* en se rencontrant physiquement, ou par t*l*phone, en s'assurant que le num*ro de t*l*phone de l'h*te distant n'a pas *t* envoy* dans le m*me courrier *lectronique que celui qui contenait la cl* ! Une autre mani*re de faire ceci est d'utiliser un tiers de confiance qui ex*cute le service d'autorit* de certification (Certificate Authority). Cette autorit* de certification (CA) peut alors signer votre cl* ; celle que nous avons nous-m*me cr** au-dessus. -------------------------------------------------------------------------- tunnels IPSEC Jusqu'ici, nous n'avons seulement consid*r* IPSEC dans le mode appel* 'transport' o* les points terminaux comprennent directement IPSEC. Comme ceci n'est pas souvent le cas, il peut *tre n*cessaire d'avoir des routeurs qui, eux seuls, comprennent IPSEC et qui r*alisent le travail pour les h*tes se trouvant derri*re eux. Ceci est appel* le mode tunnel. Configurer ceci est tr*s rapide. Pour tunneler tout le trafic vers 130.161.0.0/16 * partir de 10.0.0.216 via 10.0.0.11, nous *ditons ce qui suit sur 10.0.0.216 : #!/sbin/setkey -f flush; spdflush; add 10.0.0.216 10.0.0.11 esp 34501 -m tunnel -E 3des-cbc "123456789012123456789012"; spdadd 10.0.0.0/24 130.161.0.0/16 any -P out ipsec esp/tunnel/10.0.0.216-10.0.0.11/require; Notez que l'option '-m tunnel' est vitale ! Ceci configure tout d'abord une Association de S*curit* ESP entre les points terminaux de notre tunnel, * savoir 10.0.0.216 et 10.0.0.11. Nous allons ensuite r*ellement configurer le tunnel. On doit indiquer au noyau d'encrypter tout le trafic de 10.0.0.0/24 vers 130.161.0.0. De plus, ce trafic doit *tre envoy* vers 10.0.0.11. 10.0.0.11 a *galement besoin d'*tre configur* : #!/sbin/setkey -f flush; spdflush; add 10.0.0.216 10.0.0.11 esp 34501 -m tunnel -E 3des-cbc "123456789012123456789012"; spdadd 10.0.0.0/24 130.161.0.0/16 any -P in ipsec esp/tunnel/10.0.0.216-10.0.0.11/require; Notez que ceci est exactement identique, * l'exception du changement de '-P out' en '-P in'. Les exemples pr*c*dents n'ont configur* le trafic que dans un seul sens. Il est laiss* comme exercice au lecteur le soin de compl*ter l'autre moiti* du tunnel. Le nom de 'proxy ESP' est *galement donn* pour cette configuration, ce qui est un peu plus clair. Note*: Le tunnel IPSEC a besoin d'avoir la transmission IP activ*e dans le noyau ! -------------------------------------------------------------------------- Autre logiciel IPSEC Thomas Walpuski pr*cise qu'il a *crit une mise * jour pour que OpenBSD isakpmd puisse fonctionner avec Linux 2.5 IPSEC. De plus, la repository principale CVS de isakpmd contient maintenant le code ! Des notes sont disponibles [176]sur cette page. isakpmd est diff*rent de racoon mentionn* au-dessus, mais de nombreuses personnes l'appr*cient. Il peut *tre trouv* [177]ici. D'autres *l*ments de lecture sur le CVS d'OpenBSD [178]ici. Thomas a *galement cr** un [179]tarball pour ceux qui ne sont pas habitu*s * CVS ou patch. De plus, des mises * jour sont disponibles pour permettre aux outils FreeS/WAN de l'espace utilisateur de fonctionner avec l'IPSEC natif de Linux 2.5. Vous pourrez les trouver [180]ici. -------------------------------------------------------------------------- Interop*rabilit* d'IPSEC avec d'autres syst*mes FIXME: Ecrire ceci -------------------------------------------------------------------------- Windows Andreas Jellinghaus rapporte : "win2k: cela marche. pr*-partage de cl* et l'adresse ip pour l'authentification (je ne pense pas que windows supporte fdqn ou userfdqn). Les certificats devraient *galement marcher, mais cela n'a pas *t* essay*. -------------------------------------------------------------------------- Check Point VPN-1 NG Peter Bieringer rapporte : Voici des r*sultats (seul le mode tunnel a *t* test*, auth=SHA1) : DES: ok 3DES: ok AES-128: ok AES-192: non support* par CP VPN-1 AES-256: ok CAST* : non support* par le noyau Linux utilis* Version Test*e : FP4 aka R54 aka w/AI Plus d'informations [181]ici. -------------------------------------------------------------------------- Chapitre 8. Routage multidistribution (multicast) FIXME: Pas de r*dacteur ! Le Multicast-HOWTO est (relativement) ancien. De ce fait, il peut *tre impr*cis ou induire en erreur * certains endroits. Avant que vous ne puissiez faire du routage multidistribution, le noyau Linux a besoin d'*tre configur* pour supporter le type de routage multidistribution que vous voulez faire. Ceci, * son tour, exige une d*cision quant au choix du protocole de routage multidistribution que vous vous pr*parez * utiliser. Il y a essentiellement quatre types <<*communs*>> de protocoles : DVMRP (la version multidistribution du protocole RIP unicast), MOSPF (la m*me chose, mais pour OSPF), PIM-SM (Protocol Independant Multicasting - Sparse Mode) qui suppose que les utilisateurs de n'importe quel groupe de multidistribution sont dispers*s plut*t que regroup*s) et PIM-DM (le m*me, mais Dense Mode) qui suppose qu'il y aura un regroupement significatif des utilisateurs d'un m*me groupe de multidistribution. On pourra noter que ces options n'apparaissent pas dans le noyau Linux. Ceci s'explique par le fait que le protocole lui-m*me est g*r* par une application de routage, comme Zebra, mrouted ou pind. Cependant, vous devez avoir une bonne id*e de ce que vous allez utiliser, de mani*re * s*lectionner les bonnes options dans le noyau. Pour tout routage multidistribution, vous avez forc*ment besoin de s*lectionner les options multicasting et multicasting routing. Ceci est suffisant pour DVMRP et MOSPF. Dans le cas de PIM, vous devez *galement valider les options PIMv1 ou PIMv2 suivant que le r*seau que vous connectez utilise la version 1 ou 2 du protocole PIM. Une fois que tout cela a *t* r*alis*, et que votre nouveau noyau a *t* compil*, vous verrez au d*marrage que IGMP est inclus dans la liste des protocoles IP. Celui-ci est un protocole permettant de g*rer les groupes multidistribution. Au moment de la r*daction, Linux ne supportait que les versions 1 et 2 de IGMP, bien que la version 3 existe et ait *t* document*e. Ceci ne va pas vraiment nous affecter dans la mesure o* IGMPv3 est encore trop r*cent pour que ses fonctionnalit*s suppl*mentaires soient largement utilis*es. Puisque IGMP s'occupe des groupes, seules les fonctionnalit*s pr*sentes dans la plus simple version de IGMP g*rant un groupe entier seront utilis*es. IGMPv2 sera utilis* dans la plupart des cas, bien que IGMPv1 puisse encore *tre rencontr*. Jusque-l*, c'est bon. Nous avons activ* la multidistribution. Nous devons dire au noyau de l'utiliser concr*tement. Nous allons donc d*marrer le routage. Ceci signifie que nous ajoutons un r*seau virtuel de multidistribution * la table du routeur : ip route add 224.0.0.0/4 dev eth0 (En supposant bien s*r, que vous diffusez * travers eth0 ! Remplacez-le par le p*riph*rique de votre choix, si n*cessaire.) Maintenant, dire * Linux de transmettre les paquets... echo 1 > /proc/sys/net/ipv4/ip_forward Arriv* ici, il se peut que vous vous demandiez si ceci va faire quelque chose. Donc, pour tester notre connexion, nous pinguons le groupe par d*faut, 224.0.0.1, pour voir si des machines sont pr*sentes. Toutes les machines du r*seau local avec la multidistribution activ*e DEVRAIENT r*pondre, et aucune autre. Vous remarquerez qu'aucune des machines qui r*pondent ne le fait avec l'adresse IP 224.0.0.1. Quelle surprise ! :) Ceci est une adresse de groupe (une <<*diffusion*>> pour les abonn*s) et tous les membres du groupe r*pondront avec leur propre adresse, et non celle du groupe. ping -c 2 224.0.0.1 Maintenant, vous *tes pr*t * faire du vrai routage multidistribution. Bien, en supposant que vous ayez deux r*seaux * router l'un vers l'autre. (A continuer !) -------------------------------------------------------------------------- Chapitre 9. Gestionnaires de mise en file d'attente pour l'administration de la bande passante Quand je l'ai d*couvert, cela m'a VRAIMENT souffl*. Linux 2.2 contient toutes les fonctionnalit*s pour la gestion de la bande passante, de mani*re comparable * un syst*me d*di* de haut niveau. Linux d*passe m*me ce que l'ATM et le Frame peuvent fournir. Afin d'*viter toute confusion, voici les r*gles utilis*es par tc pour la sp*cification de la bande passante : mbps = 1024 kbps = 1024 * 1024 bps => byte/s (octets/s) mbit = 1024 kbit => kilo bit/s. mb = 1024 kb = 1024 * 1024 b => byte (octet) mbit = 1024 kbit => kilo bit. En interne, les nombres sont stock*s en bps (octet/s) et b (octet). Mais tc utilise l'unit* suivante lors de l'affichage des d*bits : 1Mbit = 1024 Kbit = 1024 * 1024 bps => octets/s -------------------------------------------------------------------------- Explication sur les files d'attente et la gestion de la mise en file d'attente Avec la mise en file d'attente, nous d*terminons la mani*re dont les donn*es sont ENVOYEES. Il est important de comprendre que nous ne pouvons mettre en forme que les donn*es que nous transmettons. Avec la mani*re dont Internet travaille, nous n'avons pas de contr*le direct sur ce que les personnes nous envoient. C'est un peu comme votre bo*te aux lettres (physique !) chez vous. Il n'y a pas de fa*on d'influencer le nombre de lettres que vous recevez, * moins de contacter tout le monde. Cependant, l'Internet est principalement bas* sur TCP/IP qui poss*de quelques fonctionnalit*s qui vont pouvoir nous aider. TCP/IP n'a pas d'aptitude * conna*tre les performances d'un r*seau entre deux h*tes. Il envoie donc simplement des paquets de plus en plus rapidement (<<*slow start*>>) et quand des paquets commencent * se perdre, il ralentit car il n'a plus la possibilit* de les envoyer. En fait, c'est un peu plus *l*gant que cela, mais nous en dirons plus par la suite. C'est comme si vous ne lisiez que la moiti* de votre courrier en esp*rant que vos correspondants arr*teront de vous en envoyer. * la diff*rence que *a marche sur Internet :-) Si vous avez un routeur et que vous souhaitez *viter que certains h*tes de votre r*seau aient des vitesses de t*l*chargement trop grandes, vous aurez besoin de mettre en place de la mise en forme de trafic sur l'interface INTERNE de votre routeur, celle qui envoie les donn*es vers vos propres ordinateurs. Vous devez *galement *tre s*r que vous contr*lez le goulot d'*tranglement de la liaison. Si vous avez une carte r*seau * 100Mbit et un routeur avec un lien * 256kbit, vous devez vous assurer que vous n'envoyez pas plus de donn*es que ce que le routeur peut manipuler. Autrement, ce sera le routeur qui contr*lera le lien et qui mettra en forme la bande passante disponible. Nous devons pour ainsi dire <<**tre le propri*taire de la file d'attente*>> et *tre le lien le plus lent de la cha*ne. Heureusement, c'est facilement r*alisable. -------------------------------------------------------------------------- Gestionnaires de mise en file d'attente simples, sans classes Comme nous l'avons d*j* dit, la gestion de mise en file d'attente permet de modifier la fa*on dont les donn*es sont envoy*es. Les gestionnaires de mise en file d'attente sans classes sont ceux qui, en gros, acceptent les donn*es et qui ne font que les r*ordonner, les retarder ou les jeter. Ils peuvent *tre utilis*s pour mettre en forme le trafic d'une interface sans aucune subdivision. Il est primordial que vous compreniez cet aspect de la mise en file d'attente avant de continuer sur les gestionnaires de mise en files d'attente bas*s sur des classes contenant d'autres gestionnaires de mise en file d'attente. Le gestionnaire le plus largement utilis* est de loin pfifo_fast, qui est celui par d*faut. Ceci explique aussi pourquoi ces fonctionnalit*s avanc*es sont si robustes. Elles ne sont rien de plus <<*qu'une autre file d'attente*>>. Chacune de ces files d'attente a ses forces et ses faiblesses. Toutes n'ont peut-*tre pas *t* bien test*es. -------------------------------------------------------------------------- pfifo_fast Cette file d'attente, comme son nom l'indique : premier entr*, premier sorti (First In First Out), signifie que les paquets ne subissent pas de traitements sp*ciaux. En fait, ce n'est pas tout * fait vrai. Cette file d'attente a trois <<*bandes*>>. A l'int*rieur de chacune de ces bandes, des r*gles FIFO s'appliquent. Cependant, tant qu'il y a un paquet en attente dans la bande 0, la bande 1 ne sera pas trait*e. Il en va de m*me pour la bande 1 et la bande 2. Le noyau prend en compte la valeur du champ Type de Service des paquets et prend soin d'ins*rer dans la bande 0 les paquets ayant le bit <<*d*lai minimum*>> activ*. Ne pas confondre ce gestionnaire de mise en file d'attente sans classes avec celui bas* sur des classes PRIO ! Bien qu'ils aient des comportements similaires, pfifo_fast ne poss*de pas de classes et vous ne pourrez pas y ajouter de nouveaux gestionnaires avec la commande tc. -------------------------------------------------------------------------- Param*tres & usage Vous ne pouvez pas configurer le gestionnaire pfifo_fast, dans la mesure o* c'est celui par d*faut. Voici sa configuration par d*faut : priomap D*termine comment les priorit*s des paquets sont reli*es aux bandes, telles que d*finies par le noyau. La relation est *tablie en se basant sur l'octet TOS du paquet, qui ressemble * ceci : 0 1 2 3 4 5 6 7 +-----+-----+-----+-----+-----+-----+-----+-----+ | | | | | PRECEDENCE | TOS | MBZ | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ Les quatre bits TOS (le champ TOS) sont d*finis comme suit : Binaire D*cimal Signification ----------------------------------------- 1000 8 Minimise le D*lai (Minimize delay) (md) 0100 4 Maximalise le D*bit (Maximize throughput) (mt) 0010 2 Maximalise la Fiabilit* (Maximize reliability) (mr) 0001 1 Minimalise le Co*t Mon*taire (Minimize monetary cost) (mmc) 0000 0 Service Normal Comme il y a 1 bit sur la droite de ces quatre bits, la valeur r*elle du champ TOS est le double de la valeur des bits TOS. tcpdump -v -v fournit la valeur de tout le champ TOS, et non pas seulement la valeur des quatre bits. C'est la valeur que l'on peut voir dans la premi*re colonne du tableau suivant : TOS Bits Signification Priorit* Linux Bande ------------------------------------------------------------------------ 0x0 0 Service Normal 0 Best Effort 1 0x2 1 Minimise le Co*t Mon*taire (mmc) 1 Filler 2 0x4 2 Maximalise la Fiabilit* (mr) 0 Best Effort 1 0x6 3 mmc+mr 0 Best Effort 1 0x8 4 Maximalise le D*bit (mt) 2 Masse 2 0xa 5 mmc+mt 2 Masse 2 0xc 6 mr+mt 2 Masse 2 0xe 7 mmc+mr+mt 2 Masse 2 0x10 8 Minimise le D*lai (md) 6 Interactive 0 0x12 9 mmc+md 6 Interactive 0 0x14 10 mr+md 6 Interactive 0 0x16 11 mmc+mr+md 6 Interactive 0 0x18 12 mt+md 4 Int. Masse 1 0x1a 13 mmc+mt+md 4 Int. Masse 1 0x1c 14 mr+mt+md 4 Int. Masse 1 0x1e 15 mmc+mr+mt+md 4 Int. Masse 1 [NdT : par flux de masse (bulk flow), il faut entendre <<*gros flot de donn*es transmises en continu*>> comme un transfert FTP. A l'oppos*, un flux interactif (interactive flow), correspond * celui g*n*r* par des requ*tes SSH]. Beaucoup de nombres. La seconde colonne contient la valeur correspondante des quatre bits TOS, suivi de leur signification. Par exemple, 15 repr*sente un paquet voulant un co*t mon*taire minimal, une fiabilit* maximum, un d*bit maximum ET un d*lai minimum. J'appellerai ceci un <<*paquet Hollandais*>>. La quatri*me colonne liste la mani*re dont le noyau Linux interpr*te les bits TOS, en indiquant * quelle priorit* ils sont reli*s. La derni*re colonne montre la carte des priorit*s par d*faut. Sur la ligne de commande, la carte des priorit*s ressemble * ceci : 1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1 Ceci signifie , par exemple, que la priorit* 4 sera reli*e * la bande num*ro 1. La carte des priorit*s vous permet *galement de lister des priorit*s plus grandes (> 7) qui ne correspondent pas * une relation avec le champ TOS, mais qui sont configur*es par d'autres moyens. Le tableau suivant provenant de la RFC 1349 (* lire pour plus de d*tails) indique comment les applications devraient configurer leurs bits TOS pour fonctionner correctement : TELNET 1000 (minimise le d*lai) FTP Contr*le 1000 (minimise le d*lai) Donn*es 0100 (maximalise le d*bit) TFTP 1000 (minimise le d*lai) SMTP phase de commande 1000 (minimise le d*lai) phase DATA 0100 (maximalise le d*bit) Domain Name Service requ*te UDP 1000 (minimise le d*lai) requ*te TCP 0000 Transfert de Zone 0100 (maximalise le d*bit) NNTP 0001 (minimise le co*t mon*taire) ICMP Erreurs 0000 Requ*tes 0000 (presque) R*ponses (presque) txqueuelen La longueur de cette file d'attente est fournie par la configuration de l'interface, que vous pouvez voir et configurer avec ifconfig et ip. Pour configurer la longueur de la file d'attente * 10, ex*cuter : ifconfig eth0 txqueuelen 10 Vous ne pouvez pas configurer ce param*tre avec tc ! -------------------------------------------------------------------------- Filtre * seau de jetons (Token Bucket Filter) Le Token Bucket Filter (TBF) est un gestionnaire de mise en file d'attente simple. Il ne fait que laisser passer les paquets entrants avec un d*bit n'exc*dant pas une limite fix*e administrativement. L'envoi de courtes rafales de donn*es avec un d*bit d*passant cette limite est cependant possible. TBF est tr*s pr*cis, et peu gourmand du point de vue r*seau et processeur. Consid*rez-le en premier si vous voulez simplement ralentir une interface ! L'impl*mentation TBF consiste en un tampon (seau), constamment rempli par des *l*ments virtuels d'information appel*s jetons, avec un d*bit sp*cifique (d*bit de jeton). Le param*tre le plus important du tampon est sa taille, qui correspond au nombre de jetons qu'il peut stocker. Chaque jeton entrant laisse sortir un paquet de donn*es de la file d'attente de donn*es et ce jeton est alors supprim* du seau. L'association de cet algorithme avec les deux flux de jetons et de donn*es, nous conduit * trois sc*narios possibles : * Les donn*es arrivent dans TBF avec un d*bit EGAL au d*bit des jetons entrants. Dans ce cas, chaque paquet entrant a son jeton correspondant et passe la file d'attente sans d*lai. * Les donn*es arrivent dans TBF avec un d*bit PLUS PETIT que le d*bit des jetons. Seule une partie des jetons est supprim*e au moment o* les paquets de donn*es sortent de la file d'attente, de sorte que les jetons s'accumulent jusqu'* atteindre la taille du tampon. Les jetons libres peuvent *tre utilis*s pour envoyer des donn*es avec un d*bit sup*rieur au d*bit des jetons standard, si de courtes rafales de donn*es arrivent. * Les donn*es arrivent dans TBF avec un d*bit PLUS GRAND que le d*bit des jetons. Ceci signifie que le seau sera bient*t d*pourvu de jetons, ce qui provoque l'arr*t de TBF pendant un moment. Ceci s'appelle <<*une situation de d*passement de limite*>> (overlimit situation). Si les paquets continuent * arriver, ils commenceront * *tre *limin*s. Le dernier sc*nario est tr*s important, car il autorise la mise en forme administrative de la bande passante disponible pour les donn*es traversant le filtre. L'accumulation de jetons autorise l'*mission de courtes rafales de donn*es sans perte en situation de d*passement de limite, mais toute surcharge prolong*e causera syst*matiquement le retard des paquets, puis leur rejet. Notez que, dans l'impl*mentation r*elle, les jetons correspondent * des octets, et non des paquets. -------------------------------------------------------------------------- Param*tres & usage M*me si vous n'aurez probablement pas besoin de les changer, TBF a des param*tres. D'abord, ceux toujours disponibles sont : limit or latency Limit est le nombre d'octets qui peuvent *tre mis en file d'attente en attendant la disponibilit* de jetons. Vous pouvez *galement indiquer ceci d'une autre mani*re en configurant le param*tre latency, qui sp*cifie le temps maximal pendant lequel un paquet peut rester dans TBF. Ce dernier param*tre prend en compte la taille du seau, le d*bit, et s'il est configur*, le d*bit de cr*te (peakrate). burst/buffer/maxburst Taille du seau, en octets. C'est la quantit* maximale, en octets, de jetons dont on disposera simultan*ment. En g*n*ral, plus les d*bits de mise en forme sont importants, plus le tampon doit *tre grand. Pour 10 Mbit/s sur plateforme Intel, vous avez besoin d'un tampon d'au moins 10 kilo-octets si vous voulez atteindre la limitation configur*e ! Si votre tampon est trop petit, les paquets pourront *tre rejet*s car il arrive plus de jetons par top d'horloge que ne peut en contenir le tampon. mpu Un paquet de taille nulle n'utilise pas une bande passante nulle. Pour ethernet, la taille minimale d'un paquet est de 64 octets. L'Unit* Minimale de Paquet (Minimun Packet Unit) d*termine le nombre minimal de jetons * utiliser pour un paquet. rate Le param*tre de la vitesse. Voir les remarques au-dessus * propos des limites ! Si le seau contient des jetons et qu'il est autoris* * se vider, alors il le fait par d*faut avec une vitesse infinie. Si ceci vous semble inacceptable, utilisez les param*tres suivants : peakrate Si des jetons sont disponibles et que des paquets arrivent, ils sont imm*diatement envoy*s par d*faut ; et pour ainsi dire * <<*la vitesse de la lumi*re*>>. Cela peut ne pas vous convenir, sp*cialement si vous avez un grand seau. Le d*bit de cr*te (peak rate) peut *tre utilis* pour sp*cifier la vitesse * laquelle le seau est autoris* * se vider. Si tout se passe comme *crit dans les livres, ceci est r*alis* en lib*rant un paquet, puis en attendant suffisamment longtemps, pour lib*rer le paquet suivant. Le temps d'attente est calcul* de mani*re * obtenir un d*bit *gal au d*bit de cr*te. Cependant, *tant donn* que la r*solution du minuteur (timer) d'UNIX est de 10 ms et que les paquets ont une taille moyenne de 10 000 bits, nous sommes limit*s * un d*bit de cr*te de 1mbit/s ! mtu/minburst Le d*bit de cr*te de 1Mb/s ne sert pas * grand chose si votre d*bit habituel est sup*rieur * cette valeur. Un d*bit de cr*te plus *lev* peut *tre atteint en *mettant davantage de paquets par top du minuteur, ce qui a pour effet de cr*er un second seau. Ce second bucket ne prend par d*faut qu'un seul paquet, et n'est donc en aucun cas un seau. Pour calculer le d*bit de cr*te maximum, multipliez le mtu que vous avez configur* par 100 (ou plus exactement par HZ, qui est *gal * 100 sur Intel et * 1024 sur Alpha). -------------------------------------------------------------------------- Configuration simple Voici une configuration simple, mais tr*s utile : # tc qdisc add dev ppp0 root tbf rate 220kbit latency 50ms burst 1540 Pourquoi est-ce utile ? Si vous avez un p*riph*rique r*seau avec une grande file d'attente, comme un modem DSL ou un modem cble, et que le dialogue se fasse * travers une interface rapide, comme une interface ethernet, vous observerez que t*l*charger vers l'amont (uploading) d*grade compl*tement l'interactivit*. [NdT : uploading d*signe une op*ration qui consiste * transf*rer des donn*es ou des programmes stock*s dans un ordinateur local vers un ordinateur distant * travers un r*seau. La traduction officielle pour ce terme est <<*t*l*chargement vers l'amont*>>. On parle alors de voie montante. Le downloading d*signe l'op*ration inverse (transfert d'un h*te distant vers l'ordinateur local) et est traduit par <<*t*l*chargement*>> ou <<*t*l*chargement vers l'aval*>>. On parle alors de la voie descendante.] Le t*l*chargement vers l'amont va en effet remplir la file d'attente du modem. Celle-ci est probablement ENORME car cela aide vraiment * obtenir de bon d*bit de t*l*chargement vers l'amont. Cependant, ceci n'est pas forc*ment ce que voulez. Vous ne voulez pas forc*ment avoir une file d'attente importante de mani*re * garder l'interactivit* et pouvoir encore faire des choses pendant que vous envoyez des donn*es. La ligne de commande au-dessus ralentit l'envoi de donn*es * un d*bit qui ne conduit pas * une mise en file d'attente dans le modem. La file d'attente r*side dans le noyau Linux, o* nous pouvons lui imposer une taille limite. Modifier la valeur 220kbit avec votre vitesse de lien REELLE moins un petit pourcentage. Si vous avez un modem vraiment rapide, augmenter un peu le param*tre burst. -------------------------------------------------------------------------- Mise en file d'attente stochastiquement *quitable (Stochastic Fairness Queueing) Stochastic Fairness Queueing (SFQ) est une impl*mentation simple de la famille des algorithmes de mise en file d'attente *quitable. Cette impl*mentation est moins pr*cise que les autres, mais elle n*cessite aussi moins de calculs tout en *tant presque parfaitement *quitable. Le mot cl* dans SFQ est conversation (ou flux), qui correspond principalement * une session TCP ou un flux UDP. Le trafic est alors divis* en un grand nombre de jolies files d'attente FIFO : une par conversation. Le trafic est alors envoy* dans un tourniquet, donnant une chance * chaque session d'envoyer leurs donn*es tour * tour. Ceci conduit * un comportement tr*s *quitable et emp*che qu'une seule conversation *touffe les autres. SFQ est appel* <<*Stochastic*>> car il n'alloue pas vraiment une file d'attente par session, mais a un algorithme qui divise le trafic * travers un nombre limit* de files d'attente en utilisant un algorithme de hachage. A cause de ce hachage, plusieurs sessions peuvent finir dans le m*me seau, ce qui peut r*duire de moiti* les chances d'une session d'envoyer un paquet et donc r*duire de moiti* la vitesse effective disponible. Pour emp*cher que cette situation ne devienne importante, SFQ change tr*s souvent son algorithme de hachage pour que deux sessions entrantes en collision ne le fassent que pendant un nombre r*duit de secondes. Il est important de noter que SFQ n'est seulement utile que dans le cas o* votre interface de sortie est vraiment satur*e ! Si ce n'est pas le cas, il n'y aura pas de files d'attente sur votre machine Linux et donc, pas d'effets. Plus tard, nous d*crirons comment combiner SFQ avec d'autres gestionnaires de mise en files d'attente pour obtenir le meilleur des deux mondes. Configurer sp*cialement SFQ sur l'interface ethernet qui est en relation avec votre modem cble ou votre routeur DSL est vain sans d'autres mises en forme du trafic ! -------------------------------------------------------------------------- Param*tres & usage SFQ est presque configur* de base : perturb Reconfigure le hachage une fois toutes les pertub secondes. S'il n'est pas indiqu*, le hachage se sera jamais reconfigur*. Ce n'est pas recommand*. 10 secondes est probablement une bonne valeur. quantum Nombre d'octets qu'un flux est autoris* * retirer de la file d'attente avant que la prochaine file d'attente ne prenne son tour. Par d*faut, *gal * la taille maximum d'un paquet (MTU). Ne le configurez pas en dessous du MTU ! -------------------------------------------------------------------------- Configuration simple Si vous avez un p*riph*rique qui a une vitesse identique * celle du lien et un d*bit r*el disponible, comme un modem t*l*phonique, cette configuration aidera * promouvoir l'*quit* : # tc qdisc add dev ppp0 root sfq perturb 10 # tc -s -d qdisc ls qdisc sfq 800c: dev ppp0 quantum 1514b limit 128p flows 128/1024 perturb 10sec Sent 4812 bytes 62 pkts (dropped 0, overlimits 0) Le nombre 800c est un descripteur (handle) automatiquement assign* et limit signifie que 128 paquets peuvent attendre dans la file d'attente. Il y a 1024 <<*seaux de hachage*>> disponibles pour la comptabilit*, 128 pouvant *tre actifs * la fois (pas plus de paquets ne conviennent dans la file d'attente). Le hachage est reconfigur* toutes les 10 secondes. -------------------------------------------------------------------------- Conseils pour le choix de la file d'attente Pour r*sumer, ces files d'attente simples g*rent le trafic en r*ordonnant, en ralentissant ou en supprimant les paquets. Les astuces suivantes peuvent vous aider * choisir la file d'attente * utiliser. Elles mentionnent certaines files d'attente d*crites dans le chapitre [182]Gestionnaires de mise en file d'attente avanc*s>. * Pour simplement ralentir le trafic sortant, utilisez le Token Bucket Filter. Il convient bien pour les *normes bandes passantes, si vous param*trez en cons*quence le seau. * Si votre lien est vraiment satur* et que vous voulez *tre s*r qu'aucune session ne va accaparer la bande passante vers l'ext*rieur, utilisez le Stochastical Fairness Queueing. * Si vous avez une grande dorsale et que vous voulez savoir ce que vous faites, consid*rez Random Early Drop (voir le chapitre [183]Gestionnaires de mise en file d'attente avanc*s>). * Pour <<*mettre en forme*>> le trafic entrant qui n'est pas transmis, utilisez la r*glementation Ingress (Ingress Policier). La mise en forme du flux entrant est appel*e <<*r*glementation*>> (policing) et non <<*mise en forme*>> (shaping). * Si vous transmettez le trafic, utilisez TBF sur l'interface vers laquelle vous transmettez les donn*es. Si vous voulez mettre en forme un trafic pouvant sortir par plusieurs interfaces, alors le seul facteur commun est l'interface entrante. Dans ce cas, utilisez la r*glementation Ingress. * Si vous ne voulez pas mettre en forme le trafic, mais que vous vouliez voir si votre interface est tellement charg*e qu'elle a d* mettre en file d'attente les donn*es, utilisez la file d'attente pfifo (pas pfifo_fast). Elle n'a pas de bandes internes, mais assure le comptage de la taille de son accumulateur. * Finalement, vous pouvez aussi faire de la <<*mise en forme sociale*>>. La technologie n'est pas toujours capable de r*aliser ce que vous voulez. Les utilisateurs sont hostiles aux contraintes techniques. Un mot aimable peut *galement vous aider * avoir votre bande passante correctement divis*e ! -------------------------------------------------------------------------- terminologie Pour comprendre correctement des configurations plus compliqu*es, il est d'abord n*cessaire d'expliquer quelques concepts. A cause de la complexit* et de la relative jeunesse du sujet, beaucoup de mots diff*rents sont utilis*s par les personnes mais ils signifient en fait la m*me chose. Ce qui suit est lchement inspir* du texte draft-ietf-diffserv-model-06.txt, An Informal Management Model for Diffserv Routers. Il peut *tre trouv* * l'adresse [184]http://www.ietf.org/internet-drafts/draft-ietf-diffserv-model-04.txt. Lisez-le pour les d*finitions strictes des termes utilis*s. Gestionnaire de mise en file d'attente (qdisc) (Queueing Discipline) Un algorithme qui g*re la file d'attente d'un p*riph*rique, soit pour les donn*es entrantes (ingress), soit pour les donn*es sortantes (egress). Gestionnaire de mise en file d'attente sans classes (Classless qdisc) Un gestionnaire de mise en file d'attente qui n'a pas de subdivisions internes configurables. Gestionnaire de mise en file d'attente bas* sur des classes (Classful qdisc) Un gestionnaire de mise en file d'attente bas* sur des classes contient de multiples classes. Certaines de ces classes contiennent un gestionnaire de mise en file d'attente suppl*mentaire, qui peut encore *tre bas* sur des classes, mais ce n'est pas obligatoire. Si l'on s'en tient * la d*finition stricte, pfifo_fast EST bas* sur des classes, dans la mesure o* il contient trois bandes, qui sont en fait des classes. Cependant, d'un point de vue des perspectives de configuration pour l'utilisateur, il est sans classes dans la mesure o* ces classes ne peuvent *tre modifi*es avec l'outil tc. Classes Un gestionnaire de mise en file d'attente bas* sur les classes peut avoir beaucoup de classes, chacune d'elles *tant internes au gestionnaire. Une classe peut * son tour se voir ajouter plusieurs classes. Une classe peut donc avoir comme parent soit un gestionnaire de mise en file d'attente, soit une autre classe. Une classe terminale est une classe qui ne poss*de de classes enfants. Seul 1 gestionnaire de mise en file d'attente est attach* * cette classe. Ce gestionnaire est responsable de l'envoi des donn*es de cette classe. Quand vous cr*ez une classe, un gestionnaire de mise en file d'attente fifo est cr**. Quand vous ajoutez une classe enfant, ce gestionnaire est supprim*. Le gestionnaire fifo d'une classe terminale peut *tre remplac* par un autre gestionnaire plus adapt*. Vous pouvez m*me remplacer ce gestionnaire fifo par un gestionnaire de mise en file d'attente bas* sur des classes de sorte que vous pourrez rajouter des classes suppl*mentaires. Classificateur (Classifier) Chaque gestionnaire de mise en file d'attente bas* sur des classes a besoin de d*terminer vers quelles classes il doit envoyer un paquet. Ceci est r*alis* en utilisant le classificateur. Filtre (Filter) La classification peut *tre r*alis*e en utilisant des filtres. Un filtre est compos* d'un certain nombre de conditions qui, si elles sont toutes v*rifi*es, satisfait le filtre. Ordonnancement (Scheduling) Un gestionnaire de mise en file d'attente peut, avec l'aide d'un classificateur, d*cider que des paquets doivent sortir plus t*t que d'autres. Ce processus est appel* ordonnancement (scheduling), et est r*alis* par exemple par le gestionnaire pfifo_fast mentionn* plus t*t. L'ordonnancement est aussi appel* <<*reclassement*>> (reordering), ce qui peut pr*ter * confusion. Mise en forme (Shaping) Le processus qui consiste * retarder l'*mission des paquets sortants pour avoir un trafic conforme * un d*bit maximum configur*. La mise en forme est r*alis*e sur egress. Famili*rement, rejeter des paquets pour ralentir le trafic est *galement souvent appel* Mise en forme. R*glementation (Policing) Retarder ou jeter des paquets dans le but d'avoir un trafic restant en dessous d'une bande passante configur*e. Dans Linux, la r*glementation ne peut que jeter un paquet, et non le retarder dans la mesure o* il n'y a pas de <<*file d'attente d'entr*e*>> (ingress queue). Work-Conserving Un gestionnaire de mise en file d'attente work-conserving d*livre toujours un paquet s'il y en a un de disponible. En d'autres termes, il ne retarde jamais un paquet si l'adaptateur r*seau est pr*t * l'envoyer (dans le cas du gestionnaire egress). non-Work-Conserving Quelques gestionnaire de mise en files d'attente, comme par exemple le Token Bucket Filter, peuvent avoir besoin de maintenir un paquet pendant un certain temps pour limiter la bande passante. Ceci signifie qu'ils refusent parfois de lib*rer un paquet, bien qu'ils en aient un de disponible. Maintenant que nous avons d*fini notre terminologie, voyons o* tous ces *l*ments sont situ*s. Programmes Utilisateurs ^ | +---------------+-------------------------------------------+ | Y | | -------> Pile IP | | | | | | | Y | | | Y | | ^ | | | | / ----------> Transmission -> | | ^ / | | | |/ Y | | | | | | ^ Y /-qdisc1-\ | | | Classificateur /--qdisc2--\ | --->->Gestionnaire de mise de sortie ---qdisc3---- | -> | en file d'attente (Egress) \__qdisc4__/ | | d'entr*e (Ingress) \-qdiscN_/ | | | +-----------------------------------------------------------+ Merci * Jamal Hadi Salim pour cette repr*sentation ASCII. Le grand rectangle repr*sente le noyau. La fl*che la plus * gauche repr*sente le trafic du r*seau entrant dans votre machine. Celui-ci alimente alors le gestionnaire de mise en file d'attente Ingress qui peut appliquer des filtres * un paquet, et d*cider de le supprimer. Ceci est appel* <<*r*glementation*>> (Policing). Ce processus a lieu tr*s t*t, avant d'avoir beaucoup parcouru le noyau. C'est par cons*quent un tr*s bon endroit pour rejeter au plus t*t du trafic, sans pour autant consommer beaucoup de ressources CPU. Si le paquet est autoris* * continuer, il peut *tre destin* * une application locale et, dans ce cas, il entre dans la couche IP pour *tre trait* et d*livr* * un programme utilisateur. Le paquet peut *galement *tre transmis sans entrer dans une application et dans ce cas, *tre destin* * egress. Les programmes utilisateurs peuvent *galement d*livrer des donn*es, qui sont alors transmises et examin*es par le classificateur Egress. L*, il est examin* et mis en file d'attente vers un certain nombre de gestionnaire de mise en file d'attente. Par d*faut, il n'y a qu'un seul gestionnaire egress install*, pfifo_fast, qui re*oit tous les paquets. Ceci correspond * <<*la mise en file d'attente*>> (enqueueing). Le paquet r*side maintenant dans le gestionnaire de mise en file d'attente, attendant que le noyau le r*clame pour le transmettre * travers l'interface r*seau. Ceci correspond au <<*retrait de la file d'attente*>> (dequeueing). Le sch*ma ne montre que le cas d'un seul adaptateur r*seau. Les fl*ches entrantes et sortantes du noyau ne doivent pas *tre trop prises au pied de la lettre. Chaque adaptateur r*seau a un gestionnaire d'entr*e et de sortie. -------------------------------------------------------------------------- Gestionnaires de file d'attente bas*s sur les classes Les gestionnaires de mise en file d'attente bas*s sur des classes sont tr*s utiles si vous avez diff*rentes sortes de trafic qui doivent *tre trait*s diff*remment. L'un d'entre eux est appel* CBQ, pour Class Based Queueing. Il est si souvent mentionn* que les personnes identifient les gestionnaires de mise en file d'attente bas*s sur des classes uniquement * CBQ, ce qui n'est pas le cas. CBQ est le m*canisme le plus ancien, ainsi que le plus compliqu*. Il n'aura pas forc*ment les effets que vous recherchez. Ceci surprendra peut-*tre ceux qui sont sous l'emprise de <<*l'effet Sendmail*>>, qui nous enseigne qu'une technologie complexe, non document*e est forc*ment meilleure que toute autre. Nous *voquerons bient*t, plus * propos, CBQ et ses alternatives. -------------------------------------------------------------------------- Flux * l'int*rieur des gestionnaires bas*s sur des classes & * l'int*rieur des classes Quand le trafic entre dans un gestionnaire de mise en file d'attente bas* sur des classes, il doit *tre envoy* vers l'une de ses classes ; il doit *tre <<*classifi**>>. Pour d*terminer que faire d'un paquet, les *l*ments appel*s <<*filtres*>> sont consult*s. Il est important de savoir que les filtres sont appel*s de l'int*rieur d'un gestionnaire, et pas autrement ! Les filtres attach*s * ce gestionnaire renvoient alors une d*cision que le gestionnaire utilise pour mettre en file d'attente le paquet vers l'une des classes. Chaque sous-classe peut essayer d'autres filtres pour voir si de nouvelles instructions s'appliquent. Si ce n'est pas le cas, la classe met le paquet en file d'attente dans le gestionnaire de mise en file d'attente qu'elle contient. En plus de contenir d'autres gestionnaires, la plupart des gestionnaires de mise en file d'attente bas*s sur des classes r*alisent *galement de la mise en forme. Ceci est utile pour r*aliser * la fois l'ordonnancement (avec SFQ, par exemple) et le contr*le de d*bit. Vous avez besoin de ceci dans les cas o* vous avez une interface * haut d*bit (ethernet, par exemple) connect*e * un p*riph*rique plus lent (un modem cble). Si vous n'utilisez que SFQ, rien ne devait se passer, dans la mesure o* les paquets entrent et sortent du routeur sans d*lai : l'interface de sortie est de loin beaucoup plus rapide que la vitesse r*elle de votre liaison ; il n'y a alors pas de files d'attente * r*ordonnancer. -------------------------------------------------------------------------- La famille des gestionnaires de mise en file d'attente : racines, descripteurs, descendances et parents Chaque interface * <<*un gestionnaire de mise en file d'attente racine*>> de sortie (egress root qdisc). Par d*faut, le gestionnaire de mise en file d'attente sans classes mentionn* plus t*t pfifo_fast. Chaque gestionnaire et classe est rep*r* par un descripteur (handle), qui pourra *tre utilis* par les prochaines d*clarations de configuration pour se r*f*rer * ce gestionnaire. En plus du gestionnaire de sortie, une interface peut *galement avoir un gestionnaire d'entr*e (ingress), qui r*glemente le trafic entrant. Ces descripteurs sont constitu*s de deux parties : un nombre majeur et un nombre mineur : :. Il est habituel de nommer le gestionnaire racine 1:, ce qui est *quivalent * 1:0. Le nombre mineur d'un gestionnaire de mise en file d'attente est toujours 0. Les classes doivent avoir le m*me nombre majeur que leur parent. Le nombre majeur doit *tre unique * l'int*rieur d'une configuration egress ou ingress. Le nombre mineur doit *tre unique * l'int*rieur d'un gestionnaire de mise en file d'attente et de ses classes. -------------------------------------------------------------------------- Comment les filtres sont utilis*s pour classifier le trafic Pour r*capituler, une hi*rarchie typique pourrait ressembler * ceci : 1: Gestionnaire de mise en file d'attente racine | 1:1 classe enfant / | \ / | \ / | \ / | \ 1:10 1:11 1:12 classes enfants | | | | 11: | classe terminale | | 10: 12: Gestionnaire de mise en file d'attente / \ / \ 10:1 10:2 12:1 12:2 classes terminales Mais ne laissez pas cet arbre vous abuser ! Vous ne devriez pas imaginer le noyau *tre au sommet de l'arbre et le r*seau en dessous, ce qui n'est justement pas le cas. Les paquets sont mis et retir*s de la file d'attente * la racine du gestionnaire, qui est le seul *l*ment avec lequel le noyau dialogue. Un paquet pourrait *tre classifi* * travers une cha*ne suivante : 1: -> 1:1 -> 12: -> 12:2 Le paquet r*side maintenant dans la file d'attente du gestionnaire attach* * la classe 12:2. Dans cet exemple, un filtre a *t* attach* * chaque noeud de l'arbre, chacun choisissant la prochaine branche * prendre. Cela est r*alisable. Cependant, ceci est *galement possible : 1: -> 12:2 Dans ce cas, un filtre attach* * la racine a d*cid* d'envoyer le paquet directement * 12:2. -------------------------------------------------------------------------- Comment les paquets sont retir*s de la file d'attente et envoy*s vers le mat*riel Quand le noyau d*cide qu'il doit extraire des paquets pour les envoyer vers l'interface, le gestionnaire racine 1: re*oit une requ*te dequeue, qui est transmise * 1:1 et qui, * son tour, est pass*e * 10:, 11: et 12:, chacune interrogeant leurs descendances qui essaient de retirer les paquets de leur file d'attente. Dans ce cas, le noyau doit parcourir l'ensemble de l'arbre, car seul 12:2 contient un paquet. En r*sum*, les classes <<*embo*t*es*>> parlent uniquement * leur gestionnaire de mise en file d'attente parent ; jamais * une interface. Seul la file d'attente du gestionnaire racine est vid*e par le noyau ! Ceci a pour r*sultat que les classes ne retirent jamais les paquets d'une file d'attente plus vite que ce que leur parent autorise. Et c'est exactement ce que nous voulons : de cette mani*re, nous pouvons avoir SFQ dans une classe interne qui ne fait pas de mise en forme, mais seulement de l'ordonnancement, et avoir un gestionnaire de mise en file d'attente ext*rieur qui met en forme le trafic. -------------------------------------------------------------------------- Le gestionnaire de mise en file d'attente PRIO Le gestionnaire de mise en file d'attente ne met pas vraiment en forme le trafic ; il ne fait que le subdiviser en se basant sur la mani*re dont vous avez configur* vos filtres. Vous pouvez consid*rer les gestionnaires PRIO comme une sorte de super pfifo_fast dop*, o* chaque bande est une classe s*par*e au lieu d'une simple FIFO. Quand un paquet est mis en file d'attente dans le gestionnaire PRIO, une classe est choisie en fonction des filtres que vous avez donn*s. Par d*faut, trois classes sont cr**es. Ces classes contiennent par d*faut de purs gestionnaires de mise en file d'attente FIFO sans structure interne, mais vous pouvez les remplacer par n'importe quels gestionnaires disponibles. Chaque fois qu'un paquet doit *tre retir* d'une file d'attente, la classe :1 est d'abord test*e. Les classes plus *lev*es ne sont utilis*es que si aucune des bandes plus faibles n'a pas fourni de paquets. Cette file d'attente est tr*s utile dans le cas o* vous voulez donner la priorit* * certains trafics en utilisant toute la puissance des filtres tc et en ne se limitant pas seulement aux options du champ TOS. Vous pouvez *galement ajouter un autre gestionnaire de mise en file d'attente aux trois classes pr*d*finies, tandis que pfifo_fast est limit* aux simples gestionnaires FIFO. Puisqu'il ne met pas vraiment en forme, on applique le m*me avertissement que pour SFQ. Utilisez PRIO seulement si votre lien physique est vraiment satur* ou int*grez-le * l'int*rieur d'un gestionnaire de mise en file d'attente bas* sur des classes qui r*alisent la mise en forme. Ce dernier cas est valable pour pratiquement tous les modems-cbles et les p*riph*riques DSL. En termes formels, le gestionnaire de mise en file d'attente PRIO est un ordonnanceur Work-Conserving. -------------------------------------------------------------------------- Param*tres PRIO & usage Les param*tres suivants sont reconnus par tc : bands Nombre de bandes * cr*er. Chaque bande est en fait une classe. Si vous changez ce nombre, vous devez *galement changer : priomap Si vous ne fournissez pas de filtres tc pour classifier le trafic, le gestionnaire PRIO regarde la priorit* TC_PRIO pour d*cider comment mettre en file d'attente le trafic. Ceci fonctionne comme le gestionnaire de mise en file d'attente pfifo_fast mentionn* plus t*t. Voir la section correspondante pour plus de d*tails. Les bandes sont des classes et sont appel*es par d*faut majeur:1 * majeur:3. Donc, si votre gestionnaire de mise en file d'attente est appel* 12:, tc filtre le trafic vers 12:1 pour lui accorder une plus grande priorit*. Par it*ration, la bande 0 correspond au nombre mineur 1, la bande 1 au nombre mineur 2, etc ... -------------------------------------------------------------------------- Configuration simple Nous allons cr*er cet arbre : racine 1: prio 1: Gestionnaire racine / | \ / | \ / | \ 1:1 1:2 1:3 classes | | | 10: 20: 30: gestionnaire gestionnaire sfq tbf sfq bande 0 1 2 Le trafic de masse ira vers 30: tandis que le trafic interactif ira vers 20: ou 10:. Les lignes de commande : # tc qdisc add dev eth0 root handle 1: prio ## Ceci cr*e *instantan*ment* les classes 1:1, 1:2, 1:3 # tc qdisc add dev eth0 parent 1:1 handle 10: sfq # tc qdisc add dev eth0 parent 1:2 handle 20: tbf rate 20kbit buffer 1600 limit 3000 # tc qdisc add dev eth0 parent 1:3 handle 30: sfq Regardons maintenant ce que nous avons cr** : # tc -s qdisc ls dev eth0 qdisc sfq 30: quantum 1514b Sent 0 bytes 0 pkts (dropped 0, overlimits 0) qdisc tbf 20: rate 20Kbit burst 1599b lat 667.6ms Sent 0 bytes 0 pkts (dropped 0, overlimits 0) qdisc sfq 10: quantum 1514b Sent 132 bytes 2 pkts (dropped 0, overlimits 0) qdisc prio 1: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 Sent 174 bytes 3 pkts (dropped 0, overlimits 0) Comme vous pouvez le voir, la bande 0 a d*j* re*u du trafic, et un paquet a *t* envoy* pendant l'ex*cution de cette commande ! Nous allons maintenant g*n*rer du trafic de masse avec un outil qui configure correctement les options TOS, et regarder de nouveau : # scp tc ahu@10.0.0.11:./ ahu@10.0.0.11's password: tc 100% |*****************************| 353 KB 00:00 # tc -s qdisc ls dev eth0 qdisc sfq 30: quantum 1514b Sent 384228 bytes 274 pkts (dropped 0, overlimits 0) qdisc tbf 20: rate 20Kbit burst 1599b lat 667.6ms Sent 2640 bytes 20 pkts (dropped 0, overlimits 0) qdisc sfq 10: quantum 1514b Sent 2230 bytes 31 pkts (dropped 0, overlimits 0) qdisc prio 1: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 Sent 389140 bytes 326 pkts (dropped 0, overlimits 0) Comme vous pouvez le voir, tout le trafic a *t* envoy* comme pr*vu vers le descripteur 30:, qui est la bande de plus faible priorit*. Maintenant, pour v*rifier que le trafic interactif va vers les bandes de plus grande priorit*, nous g*n*rons du trafic interactif : # tc -s qdisc ls dev eth0 qdisc sfq 30: quantum 1514b Sent 384228 bytes 274 pkts (dropped 0, overlimits 0) qdisc tbf 20: rate 20Kbit burst 1599b lat 667.6ms Sent 2640 bytes 20 pkts (dropped 0, overlimits 0) qdisc sfq 10: quantum 1514b Sent 14926 bytes 193 pkts (dropped 0, overlimits 0) qdisc prio 1: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 Sent 401836 bytes 488 pkts (dropped 0, overlimits 0) Ca a march*. Tout le trafic suppl*mentaire a *t* vers 10:, qui est notre gestionnaire de plus grande priorit*. Aucun trafic n'a *t* envoy* vers les priorit*s les plus faibles, qui avaient re*u au pr*alable tout le trafic venant de notre scp. -------------------------------------------------------------------------- Le c*l*bre gestionnaire de mise en file d'attente CBQ Comme dit avant, CBQ est le gestionnaire de mise en file d'attente disponible le plus complexe, celui qui a eu le plus de publicit*, qui est le moins compris et qui est probablement le plus farceur lors de sa mise au point. Ce n'est pas parce que les auteurs sont mauvais ou incomp*tents, loin de l*, mais l'algorithme CBQ n'est pas remarquablement pr*cis et il ne correspond pas vraiment * la fa*on dont Linux fonctionne. En plus d'*tre bas* sur des classes, CBQ sert *galement * la mise en forme de trafic et c'est sur cet aspect qu'il ne fonctionne pas tr*s bien. Il travaille comme ceci : si vous essayez de mettre en forme une connexion de 10mbit/s * 1mbits/s, le lien doit *tre inactif 90% du temps. Si ce n'est pas le cas, nous devons limiter le taux de sorte qu'il soit inactif 90% du temps. Ceci est assez dur * mesurer et c'est pour cette raison que CBQ d*duit le temps d'inactivit* du nombre de microsecondes qui s'*coulent entre les requ*tes de la couche mat*rielle pour avoir plus de donn*es. Cette combinaison peut *tre utilis*e pour *valuer si le lien est charg* ou non. Ceci est plut*t l*ger et l'on arrive pas toujours * des r*sultats convenables. Par exemple, qu'en est-il de la vitesse de liaison r*elle d'une interface qui n'est pas capable de transmettre pleinement les donn*es * 100mbit/s, peut-*tre * cause d'un mauvais pilote de p*riph*rique ? Une carte r*seau PCMCIA ne pourra jamais atteindre 100mbit/s * cause de la conception du bus. De nouveau, comment calculons-nous le temps d'inactivit* ? Cela devient m*me pire quand on consid*re un p*riph*rique r*seau "pas-vraiment-r*el" comme PPP Over Ethernet ou PPTP over TCP/IP. La largeur de bande effective est dans ce cas probablement d*termin*e par l'efficacit* des tubes vers l'espace utilisateur, qui est *norme. Les personnes qui ont effectu* des mesures ont d*couvert que CBQ n'est pas toujours tr*s exact, et parfois m*me, tr*s *loign* de la configuration. Cependant, il marche bien dans de nombreuses circonstances. Avec la documentation fournie ici, vous devriez *tre capable de le configurer pour qu'il fonctionne bien dans la plupart des cas. -------------------------------------------------------------------------- Mise en forme CBQ en d*tail Comme dit pr*c*demment, CBQ fonctionne en s'assurant que le lien est inactif juste assez longtemps pour abaisser la bande passante r*elle au d*bit configur*. Pour r*aliser cela, il calcule le temps qui devrait s'*couler entre des paquets de taille moyennne. En cours de fonctionnement, le temps d'inactivit* effectif (the effective idletime) est mesur* en utilisant l'algorithme EWMA (Exponential Weighted Moving Average), qui consid*re que les paquets r*cents sont exponentiellement plus nombreux que ceux pass*s. La charge moyenne UNIX (UNIX loadaverage) est calcul*e de la m*me mani*re. Le temps d'inactivit* calcul* est soustrait * celui mesur* par EWMA et le nombre r*sultant est appel* avgidle. Un lien parfaitement charg* a un avgidle nul : un paquet arrive * chaque intervalle calcul*. Une liaison surcharg*e a un avgidle n*gatif et s'il devient trop n*gatif, CBQ s'arr*te un moment et se place alors en d*passement de limite (overlimit). Inversement, un lien inutilis* peut accumuler un avgidle *norme, qui autoriserait alors des bandes passantes infinies apr*s quelques heures d'inactivit*. Pour *viter cela, avgidle est born* * maxidle. En situation de d*passement de limite, CBQ peut en th*orie bloquer le d*bit pour une dur*e *quivalente au temps qui doit s'*couler entre deux paquets moyens, puis laisser passer un paquet et bloquer de nouveau le d*bit. Regardez cependant le param*tre minburst ci-dessous. Voici les param*tres que vous pouvez sp*cifier pour configurer la mise en forme : avpkt Taille moyenne d'un paquet mesur*e en octets. N*cessaire pour calculer maxidle, qui d*rive de maxburst, qui est sp*cifi* en paquets. bandwidth La bande passante physique de votre p*riph*rique n*cessaire pour les calculs du temps de non utilisation (idle time). cell La dur*e de transmission d'un paquet n'augmente pas n*cessairement de mani*re lin*aire en fonction de sa taille. Par exemple, un paquet de 800 octets peut *tre transmis en exactement autant de temps qu'un paquet de 806 octets. Ceci d*termine la granularit*. Cette valeur est g*n*ralement positionn*e * 8, et doit *tre une puissance de deux. maxburst Ce nombre de paquets est utilis* pour calculer maxidle de telle sorte que quand avgidle est *gal * maxidle, le nombre de paquets moyens peut *tre envoy* en rafale avant que avgidle ne retombe * 0. Augmentez-le pour *tre plus tol*rant vis * vis des rafales de donn*es. Vous ne pouvez pas configurer maxidle directement, mais seulement via ce param*tre. minburst Comme nous l'avons d*j* indiqu*, CBQ doit bloquer le d*bit dans le cas d'un d*passement de limite. La solution id*ale est de le faire pendant exactement le temps d'inutilisation calcul*, puis de laisser passer un paquet. Cependant, les noyaux UNIX ont g*n*ralement du mal * pr*voir des *v*nements plus courts que 10 ms, il vaut donc mieux limiter le d*bit pendant une p*riode plus longue, puis envoyer minburst paquets d'un seul coup et dormir pendant une dur*e de minburst. Le temps d'attente est appel* offtime. De plus grandes valeurs de minburst m*nent * une mise en forme plus pr*cise dans le long terme, mais provoquent de plus grandes rafales de donn*es pendant des p*riodes de quelques millisecondes. minidle Si avgidle est inf*rieur * 0, nous sommes en d*passement de limite et nous devons attendre jusqu'* ce que avgidle devienne suffisamment important pour envoyer un paquet. Pour *viter qu'une brusque rafale de donn*es n'emp*che le lien de fonctionner pendant une dur*e prolong*e, avgidle est remis * minidle s'il atteint une valeur trop basse. La valeur minidle est sp*cifi*e en microsecondes n*gatives : 10 signifie alors que avgidle est born* * -10µs. mpu Taille minumum d'un paquet. N*cessaire car m*me un paquet de taille nulle est encapsul* par 64 octets sur ethernet et il faut donc un certain temps pour le transmettre. CBQ doit conna*tre ce param*tre pour calculer pr*cis*ment le temps d'inutilisation. rate D*bit du trafic sortant du gestionnaire. Ceci est le <<*param*tre de vitesse*>> ! En interne, CBQ est finement optimis*. Par exemple, les classes qui sont connues pour ne pas avoir de donn*es pr*sentes dans leur file d'attente ne sont pas interrog*es. Les classes en situation de d*passement de limite sont p*nalis*es par la diminution de leur priorit* effective. Tout ceci est tr*s habile et compliqu*. -------------------------------------------------------------------------- Le comportement CBQ classful En plus de la mise en forme, en utilisant les approximations idletime mentionn*es ci-dessus, CBQ peut *galement agir comme une file d'attente PRIO dans le sens o* les classes peuvent avoir diff*rentes priorit*s. Les priorit*s de plus faible valeur seront examin*es avant celles de valeurs plus *lev*es. Chaque fois qu'un paquet est demand* par la couche mat*rielle pour *tre envoy* sur le r*seau, un processus weighted round robin (WRR) d*marre en commen*ant par les classes de plus faibles num*ros. Celles-ci sont regroup*es et interrog*es si elles ont des donn*es disponibles. Apr*s qu'une classe ait *t* autoris*e * retirer de la file d'attente un nombre d'octets, la classe de priorit* suivante est consult*e. Les param*tres suivants contr*lent le processus WRR : allot Quand le CBQ racine re*oit une demande d'envoi de paquets sur une interface, il va essayer tous les gestionnaires internes (dans les classes) tour * tour suivant l'ordre du param*tre priority. A chaque passage, une classe ne peut envoyer qu'une quantit* limit*e de donn*es. Le param*tre allot est l'unit* de base de cette quantit*. Voir le param*tre weight pour plus d'informations. prio CBQ peut *galement agir comme un p*riph*rique PRIO. Les classes internes avec les priorit*s les plus *lev*es sont consult*es en premier et, aussi longtemps qu'elles ont du trafic, les autres classes ne sont pas examin*es. weight Le param*tre weight assiste le processus Weighted Round Robin. Chaque classe a tour * tour la possibilit* d'envoyer ses donn*es. Si vous avez des classes avec des bandes passantes significativement plus importantes, il est logique de les autoriser * envoyer plus de donn*es * chaque tour que les autres. Vous pouvez utiliser des nombres arbitraires dans la mesure o* CBQ additionne tous les param*tres weight pr*sents sous une classe et les normalise. La r*gle empirique qui consiste * prendre rate/10 semble fonctionner correctement. Le param*tre weight normalis* est multipli* par le param*tre allot pour d*terminer la quantit* de donn*es * envoyer * chaque tour. Notez, s'il vous pla*t, que toutes les classes * l'int*rieur d'une hi*rarchie CBQ doivent avoir le m*me nombre majeur ! -------------------------------------------------------------------------- Param*tres CBQ qui d*terminent le partage & le pr*t du lien En plus de purement limiter certains trafics, il est *galement possible de sp*cifier quelles classes peuvent emprunter de la bande passante aux autres classes ou, r*ciproquement, pr*ter sa bande passante. isolated/ sharing Une classe qui est configur*e avec isolated ne pr*tera pas sa bande passante * ses classes enfants. Utilisez ceci si vous avez sur votre lien deux agences concurrentes ou qui ne s'appr*cient pas et qui ne veulent pas se pr*ter gratuitement de la bande passante. Le programme de contr*le tc connait *galement sharing, qui agit * l'inverse du param*tre isolated. bounded/ borrow Une classe peut aussi *tre born*e (bounded), ce qui signifie qu'elle n'essaiera pas d'emprunter de la bande passante * ses classes enfants. tc connait *galement borrow, qui agit * l'inverse de bounded. Une situation typique pourrait *tre le cas o* vous avez deux agences pr*sentes sur votre lien qui sont * la fois isolated et bounded. Ceci signifie qu'elles sont strictement limit*es * leur d*bit et qu'elles ne pr*teront pas aux autres leur bande passante. A l'int*rieur de ces classes d'agence, il pourrait y avoir d'autres classes qui sont autoris*es * *changer leur bande passante. -------------------------------------------------------------------------- Configuration simple 1: gestionnaire de mise en file d'attente racine | 1:1 classe enfant / \ / \ 1:3 1:4 classes terminales | | 30: 40: gestionnares de mise en file d'attente (sfq) (sfq) Cette configuration limite le trafic d'un serveur web * 5 mbit et le trafic SMTP * 3 mbit. Il est souhaitable qu'ils n'occupent pas plus de 6 mbit * eux deux. Nous avons une carte r*seau * 100 mbit et les classes peuvent s'emprunter mutuellement de la bande passante. # tc qdisc add dev eth0 root handle 1:0 cbq bandwidth 100Mbit \ avpkt 1000 cell 8 # tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 100Mbit \ rate 6Mbit weight 0.6Mbit prio 8 allot 1514 cell 8 maxburst 20 \ avpkt 1000 bounded Cette partie installe la racine et la classe 1:1 habituelle. La classe 1:1 est born*e, la bande passante totale ne pourra donc pas exc*der 6 mbit. Comme dit avant, CBQ a besoin de NOMBREUX param*tres. Tous ces param*tres sont cependant expliqu*s au-dessus. La configuration HTB correspondante est beaucoup plus simple. # tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 100Mbit \ rate 5Mbit weight 0.5Mbit prio 5 allot 1514 cell 8 maxburst 20 \ avpkt 1000 # tc class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 100Mbit \ rate 3Mbit weight 0.3Mbit prio 5 allot 1514 cell 8 maxburst 20 \ avpkt 1000 Ce sont nos deux classes. Notez comment nous avons configur* la valeur du param*tre weight en fonction du param*tre rate. La bande passante de l'ensemble des deux classes ne pourra jamais d*passer 6 mbit. En fait, les identifieurs de classe (classid) doivent avoir le m*me num*ro majeur que le gestionnaire de mise en file d'attente parent ! # tc qdisc add dev eth0 parent 1:3 handle 30: sfq # tc qdisc add dev eth0 parent 1:4 handle 40: sfq Les deux classes ont par d*faut un gestionnaire de mise en file d'attente FIFO. Nous les rempla*ons par une file d'attente SFQ de telle sorte que chaque flux de donn*es soit trait* de mani*re *gale. # tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \ sport 80 0xffff flowid 1:3 # tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \ sport 25 0xffff flowid 1:4 Ces commandes, directement attach*es * la racine, envoient le trafic vers le bon gestionnaire de mise en file d'attente. Notez que nous utilisons tc class add pour CREER des classes * l'int*rieur d'un gestionnaire de mise en file d'attente, et que nous utilisons tc qdisc add pour v*ritablement configurer ces classes. Vous vous demandez peut-*tre ce qui arrive au trafic qui n'est classifi* par aucune des deux r*gles. Dans ce cas, les donn*es seront trait*es * l'int*rieur de 1:0, et le d*bit ne sera pas limit*. Si le trafic SMTP+web tente de d*passer la limite de 6 mbit/s, la bande passante sera divis*e selon le param*tre weight, donnant 5/8 du trafic au serveur web et 3/8 au serveur smtp. Avec cette configuration, vous pouvez *galement dire que le trafic du serveur web sera au minimum de 5/8 * 6 mbit = 3.75 mbit. -------------------------------------------------------------------------- D'autres param*tres CBQ : split & defmap Comme pr*cis* avant, un gestionnaire de mise en file d'attente bas* sur des classes doit appeler des filtres pour d*terminer dans quelle classe un paquet sera mis en file d'attente. En plus d'appeler les filtres, CBQ offre d'autres options : defmap & split. C'est plut*t compliqu* * comprendre et, de plus, ce n'est pas vital. Mais, *tant donn* que ceci est le seul endroit connu o* defmap & split sont correctement expliqu*s, je vais faire de mon mieux. Etant donn* que nous voulons le plus souvent r*aliser le filtrage en ne consid*rant que le champ TOS, une syntaxe sp*ciale est fournie. Chaque fois que CBQ doit trouver o* le paquet doit *tre mis en file d'attente, il v*rifie si le noeud est un noeud d'aiguillage (split node). Si c'est le cas, un de ses sous-gestionnaires a indiqu* son souhait de recevoir tous les paquets configur*s avec une certaine priorit*. Celle ci peut *tre d*riv*e du champ TOS ou des options des sockets positionn*es par les applications. Les bits de priorit*s des paquets subissent un ET logique avec le champ defmap pour voir si une correspondance existe. En d'autres termes, c'est un moyen pratique de cr*er un filtre tr*s rapide, qui ne sera actif que pour certaines priorit*s. Un defmap de ff (en hexad*cimal) v*rifiera tout tandis qu'une valeur de 0 ne v*rifiera rien. Une configuration simple aidera peut-*tre * rendre les choses plus claires : # tc qdisc add dev eth1 root handle 1: cbq bandwidth 10Mbit allot 1514 \ cell 8 avpkt 1000 mpu 64 # tc class add dev eth1 parent 1:0 classid 1:1 cbq bandwidth 10Mbit \ rate 10Mbit allot 1514 cell 8 weight 1Mbit prio 8 maxburst 20 \ avpkt 1000 Pr*ambule standard de CBQ. Je n'ai jamais pris l'habitude de la quantit* de nombres n*cessaires ! Le param*tre defmap se r*f*re aux bits TC_PRIO qui sont d*finis comme suit : TC_PRIO.. Num Correspond * TOS ------------------------------------------------- BESTEFFORT 0 Maximalise la Fiabilit* FILLER 1 Minimalise le Co*t BULK 2 Maximalise le D*bit (0x8) INTERACTIVE_BULK 4 INTERACTIVE 6 Minimise le D*lai (0x10) CONTROL 7 Les nombres TC_PRIO.. correspondent aux bits compt*s * partir de la droite. Voir la section pfifo_fast pour plus de d*tails sur la fa*on dont les bits TOS sont convertis en priorit*s. Maintenant, les classes interactive et de masse : # tc class add dev eth1 parent 1:1 classid 1:2 cbq bandwidth 10Mbit \ rate 1Mbit allot 1514 cell 8 weight 100Kbit prio 3 maxburst 20 \ avpkt 1000 split 1:0 defmap c0 # tc class add dev eth1 parent 1:1 classid 1:3 cbq bandwidth 10Mbit \ rate 8Mbit allot 1514 cell 8 weight 800Kbit prio 7 maxburst 20 \ avpkt 1000 split 1:0 defmap 3f La gestion de mise en file d'attente d'aiguillage (split qdisc) est 1:0 et c'est * ce niveau que le choix sera fait. C0 correspond au nombre binaire 11000000 et 3F au nombre binaire 00111111. Ces valeurs sont choisies de telle sorte qu'* elles deux, elles v*rifient tous les bits. La premi*re classe correspond aux bits 6 & 7, ce qui est *quivalent aux trafics <<*interactif*>> et de <<*contr*le*>>. La seconde classe correspond au reste. Le noeud 1:0 poss*de maintenant la table suivante : priorit* envoyer * 0 1:3 1 1:3 2 1:3 3 1:3 4 1:3 5 1:3 6 1:2 7 1:2 Pour d'autres amusements, vous pouvez *galement donner un <<*masque de changement*>> qui indique exactement les priorit*s que vous souhaitez changer. N'utilisez ceci qu'avec la commande tc class change. Par exemple, pour ajouter le trafic best effort * la classe 1:2, nous devrons ex*cuter ceci : # tc class change dev eth1 classid 1:2 cbq defmap 01/01 La carte des priorit*s au niveau de 1:0 ressemble maintenant * ceci : priorit* envoyer * 0 1:2 1 1:3 2 1:3 3 1:3 4 1:3 5 1:3 6 1:2 7 1:2 FIXME: tc class change n'a pas *t* test*, mais simplement vu dans les sources. -------------------------------------------------------------------------- Seau de jetons * contr*le hi*rarchique (Hierarchical Token Bucket) Martin Devera() r*alisa * juste titre que CBQ est complexe et qu'il ne semble pas optimis* pour de nombreuses situations classiques. Son approche hi*rarchique est bien adapt*e dans le cas de configurations o* il y a une largeur de bande passante fix*e * diviser entre diff*rents *l*ments. Chacun de ces *l*ments aura une bande passante garantie, avec la possibilit* de sp*cifier la quantit* de bande passante qui pourra *tre emprunt*e. HTB travaille juste comme CBQ, mais il n'a pas recourt * des calculs de temps d'inoccupation pour la mise en forme. A la place, c'est un Token Bucket Filter bas* sur des classes, d'o* son nom. Il n'a que quelques param*tres, qui sont bien document*s sur ce [185]site. Au fur et * mesure que votre configuration HTB se complexifie, votre configuration s'adapte bien. Avec CBQ, elle est d*j* complexe m*me dans les cas simples ! HTB3 (voir [186]sa page principale pour les d*tails des versions HTB) fait maintenant parti des sources officielles du noyau (* partir des versions 2.4.20-pre1 et 2.5.31 et sup*rieures). Il est encore cependant possible que vous soyez oblig* de r*cup*rer la version mise * jour de 'tc' pour HTB3. Les programmes de l'espace utilisateur et la partie HTB du noyau doivent avoir le m*me num*ro majeur. Sans cela, 'tc' ne marchera pas avec HTB. Si vous avez d*j* un noyau r*cent ou si vous *tes sur le point de mettre * jour votre noyau, consid*rez HTB co*te que co*te. -------------------------------------------------------------------------- Configuration simple Fonctionnellement presque identique * la configuration simple CBQ pr*sent*e ci-dessus : # tc qdisc add dev eth0 root handle 1: htb default 30 # tc class add dev eth0 parent 1: classid 1:1 htb rate 6mbit burst 15k # tc class add dev eth0 parent 1:1 classid 1:10 htb rate 5mbit burst 15k # tc class add dev eth0 parent 1:1 classid 1:20 htb rate 3mbit ceil 6mbit burst 15k # tc class add dev eth0 parent 1:1 classid 1:30 htb rate 1kbit ceil 6mbit burst 15k L'auteur recommande SFQ sous ces classes : # tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10 # tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10 # tc qdisc add dev eth0 parent 1:30 handle 30: sfq perturb 10 Ajouter les filtres qui dirigent le trafic vers les bonnes classes : # U32="tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32" # $U32 match ip dport 80 0xffff flowid 1:10 # $U32 match ip sport 25 0xffff flowid 1:20 Et, c'est tout. Pas de vilains nombres non expliqu*s, pas de param*tres non document*s. HTB semble vraiment merveilleux. Si 10: et 20: ont atteint tous les deux leur bande passante garantie et qu'il en reste * partager, ils l'empruntent avec un rapport de 5:3, comme attendu. Le trafic non classifi* est achemin* vers 30:, qui a une petite bande passante, mais qui peut emprunter tout ce qui est laiss* libre. Puisque nous avons choisi SFQ en interne, on h*rite naturellement de l'*quit*. -------------------------------------------------------------------------- Classifier des paquets avec des filtres Pour d*terminer quelle classe traitera un paquet, la <<*cha*ne de classificateurs*>> est appel*e chaque fois qu'un choix a besoin d'*tre fait. Cette cha*ne est constitu*e de tous les filtres attach*s aux gestionnaires de mise en file d'attente bas*s sur des classes qui doivent prendre une d*cision. On reprend l'arbre qui n'est pas un arbre : racine 1: | _1:1_ / | \ / | \ / | \ 10: 11: 12: / \ / \ 10:1 10:2 12:1 12:2 Quand un paquet est mis en file d'attente, l'instruction appropri*e de la cha*ne de filtre est consult*e * chaque branche. Une configuration typique devrait avoir un filtre en 1:1 qui dirige le paquet vers 12: et un filtre en 12: qui l'envoie vers 12:2. Vous pourriez *galement avoir ce dernier filtre en 1:1, mais vous pouvez gagner en efficacit* en ayant des tests plus sp*cifiques plus bas dans la cha*ne. A ce propos, vous ne pouvez pas filtrer un paquet <<*vers le haut*>>. Donc, avec HTB, vous devrez attacher tous les filtres * la racine ! Encore une fois, les paquets ne sont mis en file d'attente que vers le bas ! Quand ils sont retir*s de la file d'attente, ils montent de nouveau, vers l'interface. Ils ne tombent PAS vers l'extr*mit* de l'arbre en direction de l'adaptateur r*seau ! -------------------------------------------------------------------------- Quelques exemples simples de filtrage Comme expliqu* dans le chapitre [187]Filtres avanc*s pour la classification des paquets>, vous pouvez vraiment analyser n'importe quoi en utilisant une syntaxe tr*s compliqu*e. Pour commencer, nous allons montrer comment r*aliser les choses *videntes, ce qui heureusement est plut*t facile. Disons que nous avons un gestionnaire de mise en file d'attente PRIO appel* 10: qui contient trois classes, et que nous voulons assigner * la bande de plus haute priorit* tout le trafic allant et venant du port 22. Les filtres seraient les suivants : # tc filter add dev eth0 protocol ip parent 10: prio 1 u32 match \ ip dport 22 0xffff flowid 10:1 # tc filter add dev eth0 protocol ip parent 10: prio 1 u32 match \ ip sport 80 0xffff flowid 10:1 # tc filter add dev eth0 protocol ip parent 10: prio 2 flowid 10:2 Qu'est-ce que cela signifie ? Cela dit : attacher * eth0, au noeud 10: un filtre u32 de priorit* 1 qui analyse le port de destination ip 22 et qui l'envoie vers la bande 10:1. La m*me chose est r*p*t*e avec le port source 80. La derni*re commande indique que si aucune correspondance n'est trouv*e, alors le trafic devra aller vers la bande 10:2, la plus grande priorit* suivante. Vous devez ajouter eth0 ou n'importe laquelle de vos interfaces, car chaque interface poss*de un espace de nommage de ses descripteurs qui lui est propre. Pour s*lectionner une adresse IP, utilisez ceci : # tc filter add dev eth0 parent 10:0 protocol ip prio 1 u32 \ match ip dst 4.3.2.1/32 flowid 10:1 # tc filter add dev eth0 parent 10:0 protocol ip prio 1 u32 \ match ip src 1.2.3.4/32 flowid 10:1 # tc filter add dev eth0 protocol ip parent 10: prio 2 \ flowid 10:2 Ceci dirige le trafic allant vers 4.3.2.1 et venant de 1.2.3.4 vers la file d'attente de plus haute priorit*, tandis que le reste ira vers la prochaine plus haute priorit*. Vous pouvez rassembler ces deux v*rifications pour r*cup*rer le trafic venant de 1.2.3.4 avec le port source 80 : # tc filter add dev eth0 parent 10:0 protocol ip prio 1 u32 match ip src 4.3.2.1/32 match ip sport 80 0xffff flowid 10:1 -------------------------------------------------------------------------- Toutes les commandes de filtres dont vous aurez normalement besoin La plupart des commandes pr*sent*es ici commencent avec le pr*ambule suivant : # tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 .. Ils sont appel*s filtres u32 et analysent N'IMPORTE QUELLE partie d'un paquet. Sur l'adresse source/destination Masque pour la source match ip src 1.2.3.0/24 et masque pour la destination match ip dst 4.3.2.0/24. Pour analyser un h*te simple, employez /32 ou omettez le masque. Sur le port source/destination, tous les protocoles IP Source: match ip sport 80 0xffff et destination : match ip dport ?? 0xffff Sur le protocole ip (tcp, udp, icmp, gre, ipsec) Utilisez les nombres d*finis dans /etc/protocols, par exemple 1 pour icmp : match ip protocol 1 0xff. Sur fwmark Vous pouvez marquer les paquets avec ipchains ou iptables et voir cette marque pr*serv*e lors du routage * travers les interfaces. Ceci est vraiment utile pour mettre uniquement en forme le trafic sur eth1 et venant de eth0, par exemple. La syntaxe est la suivante : # tc filter add dev eth1 protocol ip parent 1:0 prio 1 handle 6 fw flowid 1:1 Notez que ce n'est pas une correspondance u32 ! Vous pouvez positionner une marque comme ceci : # iptables -A PREROUTING -t mangle -i eth0 -j MARK --set-mark 6 Le nombre 6 est arbitraire. Si vous ne voulez pas assimiler la syntaxe compl*te de tc filter, utilisez juste iptables et apprenez seulement la s*lection bas*e sur fwmark. Sur le champ TOS Pour s*lectionner le trafic interactif, d*lai minimum : # tc filter add dev ppp0 parent 1:0 protocol ip prio 10 u32 \ match ip tos 0x10 0xff \ flowid 1:4 Utilisez 0x08 0xff pour le trafic de masse. Pour plus de commandes de filtrage, voir le chapitre [188]Filtres avanc*s pour la classification des paquets>. -------------------------------------------------------------------------- Le p*riph*rique de file d'attente interm*diaire (The Intermediate queueing device (IMQ)) Le p*riph*rique IMQ n'est pas un gestionnaire de mise en file d'attente mais son utilisation est fortement li*e * ceux-ci. Au coeur de Linux, les gestionnaires de mise en file d'attente sont attach*s aux p*riph*riques r*seaux et tout ce qui est mis en file d'attente dans ce p*riph*rique l'est d'abord dans le gestionnaire. Avec ce concept, il existe deux limitations : 1. Seule la mise en forme du trafic sortant est possible (un gestionnaire d'entr*e existe, mais ses possibilit*s sont tr*s limit*es en comparaison des gestionnaires de mise en file bas*s sur les classes). 2. Un gestionnaire de mise en file d'attente ne voit le trafic que d'une interface, et des limitations globales ne peuvent pas *tre mises en place. IMQ est ici pour aider * r*soudre ces deux limitations. En r*sum*, vous pouvez mettre tout ce que vous voulez dans un gestionnaire de mise en file d'attente. Les paquets sp*cialement marqu*s sont intercept*s par les points d'accroche netfilter NF_IP_PRE_ROUTING et NF_IP_POST_ROUTING et sont transf*r*s vers le gestionnaire attach* au p*riph*rique imq. Une cible iptables est utilis*e pour le marquage des paquets. Ceci vous permet de r*aliser de la mise en forme d'entr*e *tant donn* que vous pouvez marquer les paquets entrant par un p*riph*rique quelconque et/ou traiter les interfaces comme des classes pour configurer des limites globales. Vous pouvez *galement r*aliser de nombreuses autres choses comme simplement mettre votre trafic http dans un gestionnaire, mettre les requ*tes de nouvelles connexions dans un gestionnaire, ... -------------------------------------------------------------------------- Configuration simple La premi*re chose qui devrait vous venir * l'esprit est d'utiliser la mise en forme du trafic entrant pour vous garantir une grande passante. ;) La configuration se fait comme avec n'importe quelle autre interface : tc qdisc add dev imq0 root handle 1: htb default 20 tc class add dev imq0 parent 1: classid 1:1 htb rate 2mbit burst 15k tc class add dev imq0 parent 1:1 classid 1:10 htb rate 1mbit tc class add dev imq0 parent 1:1 classid 1:20 htb rate 1mbit tc qdisc add dev imq0 parent 1:10 handle 10: pfifo tc qdisc add dev imq0 parent 1:20 handle 20: sfq tc filter add dev imq0 parent 10:0 protocol ip prio 1 u32 match \ ip dst 10.0.0.230/32 flowid 1:10 Dans cet exemple, u32 est utilis* pour la classification. Les autres classificateurs devraient marcher tout aussi bien. Le trafic doit ensuite *tre s*lectionn* et marqu* pour *tre mis en file d'attente vers imq0. iptables -t mangle -A PREROUTING -i eth0 -j IMQ --todev 0 ip link set imq0 up Les cibles iptables IMQ sont valides dans les cha*nes PREROUTING et POSTROUTING de la table mangle. La syntaxe est la suivante : IMQ [ --todev n ] n : num*ro du p*riph*rique imq Il existe aussi une cible ip6tables. Notez que le trafic n'est pas mis en file d'attente quand la cible est activ*e, mais apr*s. La localisation exacte de l'entr*e du trafic dans le p*riph*rique imq d*pend de la direction de ce trafic (entrant/sortant). Ces entr*es sont les points d'accroche pr*d*finis de netfilter et utilis*s par iptables : enum nf_ip_hook_priorities { NF_IP_PRI_FIRST = INT_MIN, NF_IP_PRI_CONNTRACK = -200, NF_IP_PRI_MANGLE = -150, NF_IP_PRI_NAT_DST = -100, NF_IP_PRI_FILTER = 0, NF_IP_PRI_NAT_SRC = 100, NF_IP_PRI_LAST = INT_MAX, }; Pour le trafic entrant, imq se d*clare avec la priorit* NF_IP_PRI_MANGLE + 1, ce qui signifie que les paquets entrent dans le p*riph*rique imq juste apr*s la chaine PREROUTING de la table mangle. Pour le trafic sortant, imq utilise NF_IP_PRI_LAST qui honore le fait que les paquets rejet*s par la table filter n'occuperont pas de bande passante. Les mises * jour et de plus amples informations peuvent *tre trouv*es sur le [189]site imq. -------------------------------------------------------------------------- Chapitre 10. quilibrage de charge sur plusieurs interfaces Il existe plusieurs mani*res pour le faire. Une des plus faciles et des plus directes est TEQL (True (or Trivial) Link Equalizer. Comme la plupart des *l*ments en relation avec la gestion de file d'attente, l'*quilibrage de charge est bidirectionnel. Les deux *quipements terminaux du lien ont besoin de participer pour obtenir une efficacit* optimale. Imaginez la situation suivante : +-------+ eth1 +-------+ | |==========| | 'r*seau 1' -----| A | | B |---- 'r*seau 2' | |==========| | +-------+ eth2 +-------+ A et B sont des routeurs dont nous supposerons qu'ils fonctionnent avec Linux pour le moment. Si le trafic va du r*seau 1 vers le r*seau 2, le routeur A a besoin de distribuer les paquets sur les deux liens allant vers B. Le routeur B a besoin d'*tre configur* pour l'accepter. On retrouve la m*me chose dans le sens inverse, pour les paquets allant du r*seau 2 vers le r*seau 1. Le routeur B a besoin d'envoyer les paquets * la fois sur eth1 et eth2. La r*partition est faite par un p*riph*rique TEQL, comme ceci (cela ne pouvait pas *tre plus simple) : # tc qdisc add dev eth1 root teql0 # tc qdisc add dev eth2 root teql0 # ip link set dev teql0 up N'oubliez pas la commande ip link set up ! Ceci a besoin d'*tre fait sur les deux h*tes. Le p*riph*rique teql0 est basiquement un distributeur tourniquet au-dessus de eth1 et eth2 pour l'envoi des paquets. Aucune donn*e n'arrive jamais * travers un p*riph*rique teql, mais les donn*es apparaissent sur eth1 et eth2. Nous n'avons pour le moment que les p*riph*riques et nous avons *galement besoin d'un routage correct. L'une des possibilit*s pour r*aliser cela est d'assigner un r*seau /31 sur chacun des liens, ainsi que sur le p*riph*rique teql0 : FIXME: Avons nous besoin de quelque chose comme nobroadcast ? Un /31 est trop petit pour contenir une adresse r*seau et une adresse de diffusion. Si cela ne marche pas comme pr*vu, essayez un /30, et ajustez les adresses IP. Vous pouvez m*me essayer sans attribuer d'adresses * eth1 et eth2. Sur le routeur A: # ip addr add dev eth1 10.0.0.0/31 # ip addr add dev eth2 10.0.0.2/31 # ip addr add dev teql0 10.0.0.4/31 Sur le routeur B: # ip addr add dev eth1 10.0.0.1/31 # ip addr add dev eth2 10.0.0.3/31 # ip addr add dev teql0 10.0.0.5/31 Le routeur A devrait maintenant *tre capable de lancer un ping vers 10.0.0.1, 10.0.0.3 et 10.0.0.5 * travers les deux liens physiques et le p*riph*rique <<**galis**>>. Le routeur B devrait maintenant *tre capable de lancer un ping vers 10.0.0.0, 10.0.0.2 et 10.0.0.4 * travers les liens. Si cela marche, le routeur A peut prendre 10.0.0.5 comme route vers le r*seau 2 et le routeur B 10.0.0.4 comme route vers le r*seau 1. Pour le cas particulier o* le r*seau 1 est votre r*seau personnel et o* le r*seau 2 est l'Internet, le routeur A peut prendre 10.0.0.5 comme passerelle par d*faut. -------------------------------------------------------------------------- Avertissement Rien n'est aussi simple qu'il y para*t. Les interfaces eth1 et eth2 sur les deux routeurs A et B ne doivent pas avoir la fonction de filtrage par chemin inverse activ*e. Dans le cas contraire, ils rejetteront les paquets destin*s * des adresses autres que les leurs : # echo 0 > /proc/sys/net/ipv4/conf/eth1/rp_filter # echo 0 > /proc/sys/net/ipv4/conf/eth2/rp_filter Il y a un s*rieux probl*me avec le r*ordonnancement des paquets. Supposons que six paquets aient besoin d'*tre envoy*s de A vers B. Par exemple, eth1 peut traiter les paquets 1, 3 et 5 et eth2 les paquets 2, 4 et 6. Dans un monde id*al, le routeur B devrait recevoir ces paquets dans l'ordre 1, 2, 3, 4, 5, 6. Mais il est plus probable que le noyau les recevra comme ceci : 2, 1, 4, 3, 6, 5. Ce probl*me va perturber TCP/IP. Alors qu'il n'y a pas de probl*mes pour les liens transportant diff*rentes sessions TCP/IP, vous ne serez pas capable de regrouper plusieurs liens et obtenir par ftp un simple fichier beaucoup plus rapidement, * moins que le syst*me d'exploitation envoyant ou recevant ne soit Linux. En effet, celui-ci n'est pas facilement perturb* par de simples r*ordonnancements. Cependant, l'*quilibrage de charge est une bonne id*e pour de nombreuses applications. -------------------------------------------------------------------------- Chapitre 11. Netfilter et iproute - marquage de paquets Jusqu'* maintenant, nous avons vu comment iproute travaille, et netfilter a *t* mentionn* plusieurs fois. Vous ne perdrez pas votre temps * consulter [190]Rusty's Remarkably Unreliable Guides. Le logiciel Netfilter peut *tre trouv* [191]ici. Netfilter nous permet de filtrer les paquets ou de d*sosser leurs en-t*tes. Une de ses fonctionnalit*s particuli*res est de pouvoir marquer un paquet avec un nombre, grce * l'option --set-mark. Comme exemple, la commande suivante marque tous les paquets destin*s au port 25, en l'occurrence le courrier sortant. # iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 25 \ -j MARK --set-mark 1 Disons que nous avons plusieurs connexions, une qui est rapide (et ch*re au m*gaoctet) et une qui est plus lente, mais avec un tarif moins *lev*. Nous souhaiterions que le courrier passe par la route la moins ch*re. Nous avons d*j* marqu* le paquet avec un "1" et nous allons maintenant renseigner la base de donn*es de la politique de routage pour qu'elle agisse sur ces paquets marqu*s. # echo 201 mail.out >> /etc/iproute2/rt_tables # ip rule add fwmark 1 table mail.out # ip rule ls 0: from all lookup local 32764: from all fwmark 1 lookup mail.out 32766: from all lookup main 32767: from all lookup default Nous allons maintenant g*n*rer la table mail.out avec une route vers la ligne lente, mais peu co*teuse. # /sbin/ip route add default via 195.96.98.253 dev ppp0 table mail.out Voil* qui est fait. Il se peut que nous voulions mettre en place des exceptions, et il existe de nombreux moyens pour le faire. Nous pouvons modifier la configuration de netfilter pour exclure certains h*tes ou nous pouvons ins*rer une r*gle avec une priorit* plus faible qui pointe sur la table principale pour nos h*tes faisant exception. Nous pouvons aussi utiliser cette fonctionnalit* pour nous conformer aux bits TOS en marquant les paquets avec diff*rents types de service et les nombres correspondants. On cr*e ensuite les r*gles qui agissent sur ces types de service. De cette fa*on, on peut d*dier une ligne RNIS aux connexions interactives. Inutile de le dire, cela marche parfaitement sur un h*te qui fait de la translation d'adresse (NAT), autrement dit du masquerading. IMPORTANT : Nous avons re*u une information selon laquelle MASQ et SNAT entrent en conflit avec le marquage de paquets. Rusty Russell l'explique dans [192]ce courrier. D*sactivez le filtrage de chemin inverse pour que cela fonctionne correctement. Note : pour marquer les paquets, vous aurez besoin de valider quelques options du noyau : IP: advanced router (CONFIG_IP_ADVANCED_ROUTER) [Y/n/?] IP: policy routing (CONFIG_IP_MULTIPLE_TABLES) [Y/n/?] IP: use netfilter MARK value as routing key (CONFIG_IP_ROUTE_FWMARK) [Y/n/?] Voir aussi [193]la section intitul*e Cache web transparent utilisant netfilter, iproute2, ipchains et squid dans Chapitre 15> dans le chapitre [194]Recettes de cuisine>. -------------------------------------------------------------------------- Chapitre 12. Filtres avanc*s pour la (re-)classification des paquets Comme expliqu* dans la section sur les gestionnaires de mise en file d'attente bas*s sur des classes, les filtres sont n*cessaires pour classifier les paquets dans n'importe laquelle des sous-files d'attente. Ces filtres sont appel*s * l'int*rieur des gestionnaires de mise en file d'attente bas*s sur des classes. Voici une liste incompl*te des classificateurs disponibles : fw Base la d*cision sur la fa*on dont le pare-feu a marqu* les paquets. Ceci peut *tre un passage facile si vous ne voulez pas apprendre la syntaxe tc li*e aux filtres. Voir le chapitre sur les gestionnaires de mise en file d'attente pour plus de d*tails. u32 Base la d*cision sur les champs * l'int*rieur du paquet (c'est-*-dire l'adresse IP source, etc.) route Base la d*cision sur la route que va emprunter le paquet. rsvp, rsvp6 Route les paquets en se basant sur [195]RSVP. Seulement utile sur les r*seaux que vous contr*lez. Internet ne respecte pas RSVP. tcindex Utilis* par le gestionnaire de file d'attente DSMARK. Voir la section [196]DSMARK>. Notez qu'il y a g*n*ralement plusieurs mani*res de classifier un paquet. Cela d*pend du syst*me de classification que vous souhaitez utiliser. Les classificateurs acceptent en g*n*ral quelques arguments communs. Ils sont list*s ici pour des raisons pratiques : protocol Le protocole que ce classificateur acceptera. G*n*ralement, on n'acceptera que le trafic IP. Exig*. parent Le descripteur auquel ce classificateur est attach*. Ce descripteur doit *tre une classe d*j* existante. Exig*. prio La priorit* de ce classificateur. Les plus petits nombres seront test*s en premier. handle Cette r*f*rence a plusieurs significations suivant les diff*rents filtres. Toutes les sections suivantes supposeront que vous essayez de mettre en forme le trafic allant vers HostA. Ces sections supposeront que la classe racine a *t* configur*e sur 1: et que la classe vers laquelle vous voulez envoyer le trafic s*lectionn* est 1:1. -------------------------------------------------------------------------- Le classificateur u32 Le filtre u32 est le filtre le plus avanc* dans l'impl*mentation courante. Il est enti*rement bas* sur des tables de hachage, ce qui le rend robuste quand il y a beaucoup de r*gles de filtrage. Dans sa forme la plus simple, le filtre u32 est une liste d'enregistrements, chacun consistant en deux champs : un s*lecteur et une action. Les s*lecteurs, d*crits ci-dessous, sont compar*s avec le paquet IP trait* jusqu'* la premi*re correspondance, et l'action associ*e est r*alis*e. Le type d'action le plus simple serait de diriger le paquet vers une classe CBQ d*finie. La ligne de commande du programme tc filter, utilis*e pour configurer le filtre, consiste en trois parties : la sp*cification du filtre, un s*lecteur et une action. La sp*cification du filtre peut *tre d*finie comme : tc filter add dev IF [ protocol PROTO ] [ (preference|priority) PRIO ] [ parent CBQ ] Le champ protocol d*crit le protocole sur lequel le filtre sera appliqu*. Nous ne discuterons que du cas du protocole ip. Le champ preference (priority peut *tre utilis* comme alternative) fixe la priorit* du filtre que l'on d*finit. C'est important dans la mesure o* vous pouvez avoir plusieurs filtres (listes de r*gles) avec des priorit*s diff*rentes. Chaque liste sera scrut*e dans l'ordre d'ajout des r*gles. Alors, la liste avec la priorit* la plus faible (celle qui a le num*ro de pr*f*rence le plus *lev*) sera trait*e. Le champ parent d*finit le sommet de l'arbre CBQ (par ex. 1:0) auquel le filtre doit *tre attach*. Les options d*crites s'appliquent * tous les filtres, pas seulement * u32. -------------------------------------------------------------------------- Le s*lecteur U32 Le s*lecteur U32 contient la d*finition d'un mod*le, qui sera compar* au paquet trait*. Plus pr*cis*ment, il d*finit quels bits doivent correspondre dans l'en-t*te du paquet, et rien de plus, mais cette m*thode simple est tr*s puissante. Jetons un oeil sur l'exemple suivant, directement tir* d'un filtre assez complexe r*ellement existant : # tc filter parent 1: protocol ip pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:3 \ match 00100000/00ff0000 at 0 Pour l'instant, laissons de c*t* la premi*re ligne ; tous ces param*tres d*crivent les tables de hachage du filtre. Focalisons-nous sur la ligne de s*lection contenant le mot-cl* match. Ce s*lecteur fera correspondre les en-t*tes IP dont le second octet sera 0x10 (0010). Comme nous pouvons le deviner, le nombre 00ff est le masque de correspondance, disant au filtre quels bits il doit regarder. Ici, c'est 0xff, donc l'octet correspondra si c'est exactement 0x10. Le mot-cl* at signifie que la correspondance doit d*marrer au d*calage sp*cifi* (en octets) - dans notre cas, c'est au d*but du paquet. Traduisons tout cela en langage humain : le paquet correspondra si son champ Type de Service (TOS) a le bit <<*faible d*lai*>> positionn*. Analysons une autre r*gle : # tc filter parent 1: protocol ip pref 10 u32 fh 800::803 order 2051 key ht 800 bkt 0 flowid 1:3 \ match 00000016/0000ffff at nexthdr+0 L'option nexthdr d*signe l'en-t*te suivant encapsul* dans le paquet IP, c'est * dire celui du protocole de la couche sup*rieure. La correspondance commencera *galement au d*but du prochain en-t*te. Elle devrait avoir lieu dans le deuxi*me mot de 32 bits de l'en-t*te. Dans les protocoles TCP et UDP, ce champ contient le port de destination du paquet. Le nombre est donn* dans le format big-endian, c'est-*-dire les bits les plus significatifs en premier. Il faut donc lire 0x0016 comme 22 en d*cimal, qui correspond au service SSH dans le cas de TCP. Comme vous le devinez, cette correspondance est ambigu* sans un contexte, et nous en discuterons plus loin. Ayant compris tout cela, nous trouverons le s*lecteur suivant tr*s facile * lire : match c0a80100/ffffff00 at 16. Ce que nous avons ici, c'est une correspondance de trois octets au 17*me octet, en comptant * partir du d*but de l'en-t*te IP. Cela correspond aux paquets qui ont une adresse de destination quelconque dans le r*seau 192.168.1/24. Apr*s avoir analys* les exemples, nous pouvons r*sumer ce que nous avons appris. -------------------------------------------------------------------------- S*lecteurs g*n*raux Les s*lecteurs g*n*raux d*finissent le mod*le, le masque et le d*calage qui seront compar*s au contenu du paquet. En utilisant les s*lecteurs g*n*raux, vous pouvez rechercher des correspondances sur n'importe quel bit de l'en-t*te IP (ou des couches sup*rieures). Ils sont quand m*me plus difficiles * *crire et * lire que les s*lecteurs sp*cifiques d*crits ci-dessus. La syntaxe g*n*rale des s*lecteurs est : match [ u32 | u16 | u8 ] PATTERN MASK [ at OFFSET | nexthdr+OFFSET] Un des mots-cl*s u32, u16 ou u8 doit sp*cifier la longueur du mod*le en bits. PATTERN et MASK se rapporteront * la longueur d*finie par ce mot-cl*. Le param*tre OFFSET est le d*calage, en octets, pour le d*marrage de la recherche de correspondance. Si le mot-clef nexthdr+ est pr*sent, le d*calage sera relatif * l'en-t*te de la couche r*seau sup*rieure. Quelques exemples : # tc filter add dev ppp14 parent 1:0 prio 10 u32 \ match u8 64 0xff at 8 \ flowid 1:4 Un paquet correspondra * cette r*gle si sa <<*dur*e de vie*>> (TTL) est de 64. TTL est le champ d*marrant juste apr*s le 8*me octet de l'en-t*te IP. Correspond * tous les paquets TCP ayant le bit ACK activ* : # tc filter add dev ppp14 parent 1:0 prio 10 u32 \ match ip protocol 6 0xff \ match u8 0x10 0xff at nexthdr+13 \ flowid 1:3 Utilisez ceci pour d*terminer la pr*sence du bit ACK sur les paquets d'une longueur inf*rieure * 64 octets : ## V*rifie la pr*sence d'un ACK, ## protocol IP 6, ## longueur de l'en-t*te IP 0x5(mots de 32 bits), ## longueur total IP 0x34 (ACK + 12 octets d'options TCP) ## TCP ack actif (bit 5, offset 33) # tc filter add dev ppp14 parent 1:0 protocol ip prio 10 u32 \ match ip protocol 6 0xff \ match u8 0x05 0x0f at 0 \ match u16 0x0000 0xffc0 at 2 \ match u8 0x10 0xff at 33 \ flowid 1:3 Seuls les paquets TCP sans charge utile et avec le bit ACK positionn* v*rifieront cette r*gle. Ici, nous pouvons voir un exemple d'utilisation de deux s*lecteurs, le r*sultat final *tant un ET logique de leur r*sultat. Si nous jetons un coup d'oeil sur un sch*ma de l'en-t*te TCP, nous pouvons voir que le bit ACK est le second bit (0x10) du 14*me octet de l'en-t*te TCP (at nexthdr+13). Comme second s*lecteur, si nous voulons nous compliquer la vie, nous pouvons *crire match u8 0x06 0xff at 9 * la place du s*lecteur sp*cifique protocol tcp, puisque 6 est le num*ro du protocole TCP, sp*cifi* au 10*me octet de l'en-t*te IP. D'un autre c*t*, dans cet exemple, nous ne pourrons pas utiliser de s*lecteur sp*cifique pour la premi*re correspondance, simplement parce qu'il n'y a pas de s*lecteur sp*cifique pour d*signer les bits TCP ACK. Le filtre ci dessous est une version modifi*e du filtre pr*sent* au-dessus. La diff*rence est qu'il ne v*rifie pas la longueur de l'en-t*te ip. Pourquoi ? Car le filtre au-dessus ne marche que sur les syst*mes 32 bits. tc filter add dev ppp14 parent 1:0 protocol ip prio 10 u32 \ match ip protocol 6 0xff \ match u8 0x10 0xff at nexthdr+13 \ match u16 0x0000 0xffc0 at 2 \ flowid 1:3 -------------------------------------------------------------------------- Les s*lecteurs sp*cifiques La table suivante contient la liste de tous les s*lecteurs sp*cifiques que les auteurs de cette section ont trouv*s dans le code source du programme tc. Ils rendent simplement la vie plus facile en accroissant la lisibilit* de la configuration du filtre. FIXME: emplacement de la table - la table est dans un fichier s*par* "selector.html" FIXME: C'est encore en Polonais :-( FIXME: doit *tre "sgmlis*" Quelques exemples : # tc filter add dev ppp0 parent 1:0 prio 10 u32 \ match ip tos 0x10 0xff \ flowid 1:4 FIXME: tcp dport match ne fonctionne pas comme d*crit ci-dessous : La r*gle ci-dessus correspondra * des paquets qui ont le champ TOS *gal * 0x10. Le champ TOS commence au deuxi*me octet du paquet et occupe 1 octet, ce qui nous permet d'*crire un s*lecteur g*n*ral *quivalent : match u8 0x10 0xff at 1. Cela nous donne une indication sur l'impl*mentation du filtre u32. Les r*gles sp*cifiques sont toujours traduites en r*gles g*n*rales, et c'est sous cette forme qu'elles sont stock*es en m*moire par le noyau. Cela am*ne * une autre conclusion : les s*lecteurs tcp et udp sont exactement les m*mes et c'est la raison pour laquelle vous ne pouvez pas utiliser un simple s*lecteur match tcp dport 53 0xffff pour d*signer un paquet TCP envoy* sur un port donn*. Ce s*lecteur d*signe aussi les paquets UDP envoy*s sur ce port. Vous devez *galement sp*cifier le protocole avec la r*gle suivante : # tc filter add dev ppp0 parent 1:0 prio 10 u32 \ match tcp dport 53 0xffff \ match ip protocol 0x6 0xff \ flowid 1:2 -------------------------------------------------------------------------- Le classificateur route Ce classificateur filtre en se basant sur les informations des tables de routage. Quand un paquet passant * travers les classes et en atteint une qui est marqu*e avec le filtre route, il divise le paquet en se basant sur l'information de la table de routage. # tc filter add dev eth1 parent 1:0 protocol ip prio 100 route Ici, nous ajoutons un classificateur route sur le noeud parent 1:0, avec la priorit* 100. Quand un paquet atteint ce noeud (ce qui arrive imm*diatement, puisqu'il est racine), il consulte la table de routage et si une entr*e de la table correspond, il envoie le paquet vers la classe donn*e et lui donne une priorit* de 100. Ensuite, vous ajoutez l'entr*e de routage appropri*e pour finalement activer les choses. L'astuce ici est de d*finir realm en se basant soit sur la destination, soit sur la source. Voici la fa*on de proc*der : # ip route add Host/Network via Gateway dev Device realm RealmNumber Par exemple, nous pouvons d*finir notre r*seau de destination 192.168.10.0 avec le nombre realm *gal * 10 : # ip route add 192.168.10.0/24 via 192.168.10.1 dev eth1 realm 10 Quand on ajoute des filtres route, on peut utiliser les nombres realm pour repr*senter les r*seaux ou les h*tes et sp*cifier quelle est la correspondance entre les routes et les filtres. # tc filter add dev eth1 parent 1:0 protocol ip prio 100 \ route to 10 classid 1:10 La r*gle ci-dessus indique que les paquets allant vers le r*seau 192.168.10.0 correspondent * la classe 1:10. Le filtre route peut aussi *tre utilis* avec les routes sources. Par exemple, il y a un sous-r*seau attach* * notre routeur Linux sur eth2. # ip route add 192.168.2.0/24 dev eth2 realm 2 # tc filter add dev eth1 parent 1:0 protocol ip prio 100 \ route from 2 classid 1:2 Ici, le filtre sp*cifie que les paquets venant du r*seau 192.168.2.0 (realm 2) correspondront * la classe 1:2. -------------------------------------------------------------------------- Les filtres de r*glementation (Policing filters) Pour r*aliser des configurations encore plus compliqu*es, vous pouvez avoir des filtres qui analysent le trafic * hauteur d'une certaine bande passante. Vous pouvez configurer un filtre pour qu'il cesse compl*tement l'analyse de tout le trafic au-dessus d'un certain d*bit ou pour qu'il n'analyse pas la bande passante d*passant un certain d*bit. Ainsi, si vous d*cidez de r*glementer * 4mbit/s, mais qu'un trafic de 5mbit/s est pr*sent, vous pouvez cesser d'analyser l'ensemble des 5mbit/s ou seulement cesser d'analyser le 1 mbit/s suppl*mentaire et envoyer 4 mbit/s * la classe correspondante. Si la bande passante d*passe le d*bit configur*, vous pouvez rejeter un paquet, le reclassifier ou voir si un autre filtre y correspond. -------------------------------------------------------------------------- Techniques de r*glementation Il y a essentiellement deux fa*ons de r*glementer. Si vous avez compil* le noyau avec Estimators, celui-ci peut mesurer plus ou moins pour chaque filtre le trafic qui est pass*. Ces estimations ne sont pas co*teuses en temps CPU, *tant donn* qu'il ne compte que 25 fois par seconde le nombre de donn*es qui sont pass*es, et qu'il calcule le d*bit * partir de l*. L'autre mani*re utilise encore le Token Bucket Filter qui r*side * l'int*rieur du filtre cette fois. Le TBF analyse seulement le trafic A HAUTEUR de la bande passante que vous avez configur*e. Si cette bande passante est d*pass*e, seul l'exc*s est trait* par l'action de d*passement de limite configur*e. -------------------------------------------------------------------------- Avec l'estimateur du noyau Ceci est tr*s simple et il n'y a qu'un seul param*tre : avrate. Soit le flux demeure sous avrate et le filtre classifie le trafic vers la classe appropri*e, soit votre d*bit le d*passe et l'action indiqu*e par d*faut, la <<*reclassification*>>, est r*alis*e dans ce cas. Le noyau utilise l'algorithme EWMA pour votre bande passante, ce qui la rend moins sensible aux courtes rafales de donn*es. -------------------------------------------------------------------------- Avec le Token Bucket Filter Utilisez les param*tres suivants : * buffer/maxburst * mtu/minburst * mpu * rate Ceux-ci se comportent la plupart du temps de mani*re identique * ceux d*crits dans la section [197]Filtre * seau de jetons>. Notez cependant que si vous configurez le mtu du filtre de r*glementation TBF trop bas, aucun paquet ne passera et le gestionnaire de mise en file d'attente de sortie TBF ne fera que les ralentir. Une autre diff*rence est que la r*glementation ne peut que laisser passer ou jeter un paquet. Il ne peut pas le retenir dans le but de le retarder. -------------------------------------------------------------------------- Actions de d*passement de limite (Overlimit actions) Si votre filtre d*cide qu'un d*passement de limite est atteint, il peut mettre en oeuvre des <<*actions*>>. Actuellement, trois actions sont disponibles : continue Provoque l'arr*t de l'analyse du filtre, bien que d'autres filtres aient la possibilit* de le faire. drop Ceci est une option tr*s f*roce qui supprime simplement le trafic exc*dant un certain d*bit. Elle est souvent employ*e dans le Ingress policer et a des utilisations limit*es. Par exemple, si vous avez un serveur de noms qui s'*croule s'il traite plus de 5mbit/s de paquets, alors, vous pourrez dans ce cas utiliser un filtre d'entr*e pour *tre s*r qu'il ne traitera jamais plus de 5mbit/s. Pass/OK Transmettre le trafic. Peut *tre utilis* pour mettre hors service un filtre compliqu*, tout en le laissant en place. reclassify Permet le plus souvent une reclassification vers Best Effort. Ceci est l'action par d*faut. -------------------------------------------------------------------------- Exemples Le seul vrai exemple connu est mentionn* dans la section [198]Prot*ger votre machine des inondations SYN>. FIXME: Si vous avez d*j* utilis* ceci, partagez s'il vous pla*t votre exp*rience avec nous. -------------------------------------------------------------------------- Filtres hach*s pour un filtrage massif tr*s rapide Si vous avez besoin de milliers de r*gles, par exemple, dans le cas o* vous avez beaucoup de clients ou d'ordinateurs, tous avec des sp*cifications QoS diff*rentes, vous pourrez constater que le noyau passe beaucoup de temps * analyser toutes ces r*gles. Par d*faut, tous les filtres r*sident dans une grande cha*ne qui est analys*e par ordre d*croissant des priorit*s. Si vous avez 1000 r*gles, 1000 contr*les peuvent *tre n*cessaires pour d*terminer ce qu'il faut faire d'un paquet. La v*rification irait plus vite s'il y avait 256 cha*nes avec chacune quatre r*gles et si vous pouviez r*partir les paquets sur ces 256 cha*nes, afin que la bonne r*gle soit pr*sente. Ceci est rendu possible par le hachage. Imaginons que vous ayez sur votre r*seau 1024 clients avec des modems cble, avec des adresses IP allant de 1.2.0.0 * 1.2.3.255, et que chacun doit avoir un classement particulier, par exemple <<*pauvre*>>, <<*moyen*>> et <<*bourrage*>>. Cela vous ferait alors 1024 r*gles, dans le genre : # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.0.0 classid 1:1 # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.0.1 classid 1:1 ... # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.3.254 classid 1:3 # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.3.255 classid 1:2 Pour aller plus vite, nous pouvons utiliser la derni*re partie de l'adresse IP comme <<*cl* de hachage*>>. Nous obtenons alors 256 tables, la premi*re ressemblant * ceci : # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.0.0 classid 1:1 # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.1.0 classid 1:1 # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.2.0 classid 1:3 # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.3.0 classid 1:2 La suivante commence comme ceci : # tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \ 1.2.0.1 classid 1:1 ... De cette mani*re, seules quatre recherches au plus sont n*cessaires et deux en moyenne. La configuration est plut*t compliqu*e, mais elle en vaut vraiment la peine du fait des nombreuses r*gles. Nous cr*ons d'abord un filtre racine, puis une table avec 256 entr*es : # tc filter add dev eth1 parent 1:0 prio 5 protocol ip u32 # tc filter add dev eth1 parent 1:0 prio 5 handle 2: u32 divisor 256 Nous ajoutons maintenant des r*gles dans la table pr*c*demment cr**e : # tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 2:7b: \ match ip src 1.2.0.123 flowid 1:1 # tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 2:7b: \ match ip src 1.2.1.123 flowid 1:2 # tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 2:7b: \ match ip src 1.2.3.123 flowid 1:3 # tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 2:7b: \ match ip src 1.2.4.123 flowid 1:2 Ceci est l'entr*e 123, qui contient les correspondances pour 1.2.0.13, 1.2.1.123, 1.2.2.123 et 1.2.3.123 qui les envoient respectivement vers 1:1, 1:2, 1:3 et 1:2. Notez que nous devons sp*cifier notre seau de hachage en hexad*cimal, 0x7b pour 123. Nous cr*ons ensuite un <<*filtre de hachage*>>qui dirige le trafic vers la bonne entr*e de la table de hachage : # tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 800:: \ match ip src 1.2.0.0/16 \ hashkey mask 0x000000ff at 12 \ link 2: Ok, certains nombres doivent *tre expliqu*s. La table de hachage par d*faut est appel*e 800:: et tous les filtres d*marrent de l*. Nous s*lectionnons alors l'adresse source qui est en position 12, 13, 14 et 15 dans l'en-t*te IP, et indiquons que seule la derni*re partie nous int*resse. Ceci est envoy* vers la table de hachage 2: qui a *t* cr**e plus t*t. C'est plut*t compliqu*, mais cela marche en pratique et les performances seront *poustouflantes. Notez que cet exemple pourrait *tre am*lior* pour que chaque cha*ne contienne un filtre, ce qui repr*senterait le cas id*al ! -------------------------------------------------------------------------- Filtrer le trafic IPv6 Comment se fait-il que ces filtres tc IPv6 ne fonctionnent pas ? La base de donn*es des politiques de routage (RPDB) a remplac* le routage IPv4 et la structure d'adressage * l'int*rieur du noyau Linux, ce qui a permis les merveilleuses fonctionnalit*s d*crites dans ce HOWTO. Malheureusement, la pile IPv6 * l'int*rieur de Linux a *t* impl*ment*e en dehors de cette structure principale. Bien qu'ils partagent des fonctionnalit*s, la structure RPDB de base ne participe pas dans ou avec les structures d'adressage et de routage de IPv6. Ceci va s*rement changer, nous devons juste attendre un peu plus longtemps. FIXME : Des id*es sur des personnes travaillant sur ce sujet ? Planifications ? -------------------------------------------------------------------------- Marquer les paquets IPv6 en utilisant ip6tables ip6tables est capable de marquer un paquet et de lui assigner un num*ro : # ip6tables -A PREROUTING -i eth0 -t mangle -p tcp -j MARK --mark 1 Ceci ne va cependant pas nous aider dans la mesure o* le paquet ne passera pas par la structure RPDB. -------------------------------------------------------------------------- Utiliser le s*lecteur u32 pour rep*rer le paquet IPv6 IPv6 est normalement encapsul* dans un tunnel SIT et transport* * travers les r*seaux IPv4. Voir la section sur le tunnel IPv6 pour de plus amples informations quant * la configuration d'un tel tunnel. Ceci nous permet de filtrer les paquets IPv4 en consid*rant les paquets IPv6 comme la charge utile. Le filtre suivant rep*re tous les paquets IPv6 encapsul*s dans des paquets IPv4 : # tc filter add dev $DEV parent 10:0 protocol ip prio 10 u32 \ match ip protocol 41 0xff flowid 42:42 Continuons. Supposons que les paquets IPv6 soient envoy*s grce * des paquets IPv4 et que ces paquets n'ont pas d'options. On pourrait utiliser le filtre suivant pour rep*rer ICMPv6 dans IPv6 dans IPv4 n'ayant aucune option. 0x3a (58) est le type du champ en-t*te suivant pour ICMPv6. # tc filter add dev $DEV parent 10:0 protocol ip prio 10 u32 \ match ip protocol 41 0xff \ match u8 0x05 0x0f at 0 \ match u8 0x3a 0xff at 26 \ flowid 42:42 Rep*rer l'adresse de destination IPv6 n*cessite un peu plus de travail. Le filtre suivant rep*re l'adresse de destination 3ffe:202c:ffff:32:230:4fff:fe08:358d: # tc filter add dev $DEV parent 10:0 protocol ip prio 10 u32 \ match ip protocol 41 0xff \ match u8 0x05 0x0f at 0 \ match u8 0x3f 0xff at 44 \ match u8 0xfe 0xff at 45 \ match u8 0x20 0xff at 46 \ match u8 0x2c 0xff at 47 \ match u8 0xff 0xff at 48 \ match u8 0xff 0xff at 49 \ match u8 0x00 0xff at 50 \ match u8 0x32 0xff at 51 \ match u8 0x02 0xff at 52 \ match u8 0x30 0xff at 53 \ match u8 0x4f 0xff at 54 \ match u8 0xff 0xff at 55 \ match u8 0xfe 0xff at 56 \ match u8 0x08 0xff at 57 \ match u8 0x35 0xff at 58 \ match u8 0x8d 0xff at 59 \ flowid 10:13 La m*me technique peut *tre utilis*e pour rep*rer les r*seaux. Par exemple 2001:: # tc filter add dev $DEV parent 10:0 protocol ip prio 10 u32 \ match ip protocol 41 0xff \ match u8 0x05 0x0f at 0 \ match u8 0x20 0xff at 28 \ match u8 0x01 0xff at 29 \ flowid 10:13 -------------------------------------------------------------------------- Chapitre 13. Param*tres r*seau du noyau Le noyau utilise de nombreux param*tres qui peuvent *tre ajust*s en diff*rentes circonstances. Bien que, comme d'habitude, les param*tres par d*faut conviennent * 99% des installations, nous ne pourrions pas appeler ce document <<*HOWTO avanc**>> sans en dire un mot. Les *l*ments int*ressants sont dans /proc/sys/net, jetez-y un oeil. Tout ne sera pas document* ici au d*part, mais nous y travaillons. En attendant, vous pouvez jeter un oeil dans les sources du noyau Linux et lire le fichier Documentation/filesystems/proc.txt. La plupart des fonctionnalit*s y sont expliqu*es. -------------------------------------------------------------------------- Filtrage de Chemin Inverse (Reverse Path Filtering) Par d*faut, les routeurs routent tout, m*me les paquets qui visiblement n'appartiennent pas * votre r*seau. Un exemple courant est l'espace des adresses IP priv*es s'*chappant sur Internet. Si vous avez une interface avec une route pour 195.96.96.0/24 dessus, vous ne vous attendrez pas * voir arriver des paquets venant de 212.64.94.1. Beaucoup d'utilisateurs veulent d*sactiver cette fonctionnalit*. Les d*veloppeurs du noyau ont permis de le faire facilement. Il y a des fichiers dans /proc o* vous pouvez ordonner au noyau de le faire pour vous. La m*thode est appel*e <<*Filtrage par Chemin Inverse*>> (Reverse Path Filtering). Pour faire simple, si la r*ponse * ce paquet ne sort pas par l'interface par laquelle il est entr*, alors c'est un paquet <<*bogu**>> et il sera ignor*. Les instructions suivantes vont activer cela pour toutes les interfaces courantes et futures. # for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do > echo 2 > $i > done En reprenant l'exemple du d*but, si un paquet arrivant sur le routeur Linux par eth1 pr*tend venir du r*seau Bureau+FAI, il sera *limin*. De m*me, si un paquet arrivant du r*seau Bureau pr*tend *tre de quelque part * l'ext*rieur du pare-feu, il sera *galement *limin*. Ce qui est pr*sent* ci-dessus est le filtrage de chemin inverse complet. Le param*trage par d*faut filtre seulement sur les adresses IP des r*seaux directement connect*s. Ce param*trage par d*faut est utilis* parce que le filtrage complet *choue dans le cas d'un routage asym*trique (o* il y a des paquets arrivant par un chemin et ressortant par un autre, comme dans le cas du trafic satellite ou si vous avez des routes dynamiques (bgp, ospf, rip) dans votre r*seau. Les donn*es descendent vers la parabole satellite et les r*ponses repartent par des lignes terrestres normales). Si cette exception s'applique dans votre cas (vous devriez *tre au courant), vous pouvez simplement d*sactiver le rp_filter sur l'interface d'arriv*e des donn*es satellite. Si vous voulez voir si des paquets sont *limin*s, le fichier log_martians du m*me r*pertoire indiquera au noyau de les enregistrer dans votre syslog. # echo 1 >/proc/sys/net/ipv4/conf//log_martians FIXME: Est-ce que la configuration des fichiers dans .../conf/{default,all} suffit ? - martijn -------------------------------------------------------------------------- Configurations obscures Bon, il y a beaucoup de param*tres qui peuvent *tre modifi*s. Nous essayons de tous les lister. Voir aussi une documentation partielle dans Documentation/ip-sysctl.txt. Certaines de ces configurations ont des valeurs par d*faut diff*rentes suivant que vous r*pondez Yes ou No * la question Configure as router and not host lors de la compilation du noyau. Oskar Andreasson a une page sur ces options et il appara*t qu'elle soit meilleure que la notre. De ce fait, allez *galement voir [199]http://ipsysctl-tutorial.frozentux.net/. -------------------------------------------------------------------------- ipv4 g*n*rique En remarque g*n*rale, les fonctionnalit*s de limitation de d*bit ne fonctionnent pas sur l'interface loopback. N'essayez donc pas de les tester localement. Les limites sont exprim*es en <<*tic-tac*>> (jiffies) et elles utilisent obligatoirement le Token Bucket Filter mentionn* plus t*t. [NdT : le terme jiffies d*signe un mouvement r*gulier, faisant r*f*rence au <<*tic-tac*>> d'une horloge. Dans le noyau lui-m*me, une variable globale nomm*e jiffies est incr*ment*e * chaque interruption d'horloge] Le noyau a une horloge interne qui tourne * HZ impulsions (ou jiffies) par seconde. Sur Intel, HZ est la plupart du temps *gale * 100. Donc, configurer un fichier *_rate *, disons 50, autorise 2 paquets par seconde. Le Token Bucket Filter est *galement configur* pour autoriser une rafale de donn*es de 6 paquets au plus, si suffisamment de jetons ont *t* gagn*s. Plusieurs *l*ments de la liste suivante proviennent du fichier /usr/src/linux/Documentation/networking/ip-sysctl.txt, *crit par Alexey Kuznetsov <[200]kuznet@ms2.inr.ac.ru> et Andi Kleen <[201]ak@muc.de>. /proc/sys/net/ipv4/icmp_destunreach_rate Si le noyau d*cide qu'il ne peut pas d*livrer un paquet, il le rejettera et enverra * la source du paquet un ICMP notifiant ce rejet. /proc/sys/net/ipv4/icmp_echo_ignore_all N'agit en aucun cas comme *cho pour les paquets. Ne configurez pas ceci par d*faut. Cependant, si vous *tes utilis* comme relais dans une attaque de D*ni de Services, cela peut *tre utile. /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts [Utile] Si vous pinguez l'adresse de diffusion d'un r*seau, tous les h*tes sont sens*s r*pondre. Cela permet de coquettes attaques de d*ni de service. Mettez cette valeur * 1 pour ignorer ces messages de diffusion. /proc/sys/net/ipv4/icmp_echoreply_rate Le d*bit auquel les r*ponses echo sont envoy*es aux destinataires. /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses Configurer ceci pour ignorer les erreurs ICMP d'h*tes du r*seau r*agissant mal aux trames envoy*es vers ce qu'ils per*oivent comme l'adresse de diffusion. /proc/sys/net/ipv4/icmp_paramprob_rate Un message ICMP relativement peu connu, qui est envoy* en r*ponse * des paquets qui ont des en-t*tes IP ou TCP erron*s. Avec ce fichier, vous pouvez contr*ler le d*bit auquel il est envoy*. /proc/sys/net/ipv4/icmp_timeexceed_rate Voici la c*l*bre cause des <<**toiles Solaris*>> dans traceroute. Limite le nombre de messages ICMP Time Exceeded envoy*s. /proc/sys/net/ipv4/igmp_max_memberships Nombre maximal de sockets igmp (multidistribution) en *coute sur l'h*te. FIXME: Est-ce vrai ? /proc/sys/net/ipv4/inet_peer_gc_maxtime FIXME : Ajouter une petite explication sur le stockage des partenaires internet (inet peer) ? Intervalle de temps minimum entre deux passages du ramasse-miettes. Cet intervalle est pris en compte lors d'une faible (voire inexistante) utilisation du pool. Mesur* en jiffies. [NdT : Le pool d*signe ici la liste des adresses IP des partenaires internet.] /proc/sys/net/ipv4/inet_peer_gc_mintime Intervalle de temps minimum entre deux passages du ramasse-miettes. Cet intervalle est pris en compte lors d'une utilisation intensive du pool. Mesur* en jiffies. /proc/sys/net/ipv4/inet_peer_maxttl Dur*e de conservation maximale des enregistrements. Les entr*es non utilis*es expireront au bout de cet intervalle de temps (c'est-*-dire quand le nombre d'entr*es dans le pool est tr*s petit). Mesur* en jiffies. /proc/sys/net/ipv4/inet_peer_minttl Dur*e de conservation minimale des enregistrements. Devrait *tre suffisante pour prendre en compte le temps de vie des fragments sur l'h*te qui doit r*assembler les paquets. Cette dur*e minimale est garantie si le nombre d'*l*ments dans le pool est inf*rieur au seuil fix* par inet_peer_threshold. /proc/sys/net/ipv4/inet_peer_threshold Taille approximative de l'espace de stockage des partenaires internet. A partir de ce seuil, les entr*es sont effac*es. Ce seuil d*termine la dur*e de vie des entr*es, ainsi que les intervalles de temps entre deux d*clenchements du ramasse-miettes. Plus il y a d'entr*es, plus le temps de vie est faible et plus l'intervalle du ramasse-miettes est faible. /proc/sys/net/ipv4/ip_autoconfig Ce fichier contient la valeur 1 si l'h*te a re*u sa configuration IP par RARP, BOOTP, DHCP ou un m*canisme similaire. Autrement, il contient la valeur z*ro. /proc/sys/net/ipv4/ip_default_ttl Dur*e de vie (TTL) des paquets. Fixer * la valeur s*re de 64. Augmentez-la si vous avez un r*seau immense, mais pas <<*pour s'amuser*>> : les boucles sans fin d'un mauvais routage sont plus dangereuses si le TTL est *lev*. Vous pouvez m*me envisager de diminuer la valeur dans certaines circonstances. /proc/sys/net/ipv4/ip_dynaddr Vous aurez besoin de positionner cela si vous utilisez la connexion * la demande avec une adresse d'interface dynamique. Une fois que votre interface a *t* configur*e, toutes les sockets TCP locaux qui n'ont pas eu de paquets de r*ponse seront retrait*es pour avoir la bonne adresse. Cela r*sout le probl*me pos* par une connexion d*fectueuse ayant configur* une interface, suivie par une deuxi*me tentative r*ussie (avec une adresse IP diff*rente). /proc/sys/net/ipv4/ip_forward Le noyau doit-il essayer de transmettre les paquets ? D*sactiv* par d*faut. /proc/sys/net/ipv4/ip_local_port_range Intervalle des ports locaux pour les connexions sortantes. En fait, assez petit par d*faut, 1024 * 4999. /proc/sys/net/ipv4/ip_no_pmtu_disc Configurez ceci si vous voulez d*sactiver la d*couverte du MTU de chemin, une technique pour d*terminer le plus grand MTU possible sur votre chemin. Voir aussi la section sur la d*couverte du MTU de chemin dans le chapitre [202]Recettes de cuisine>. /proc/sys/net/ipv4/ipfrag_high_thresh M*moire maximum utilis*e pour r*assembler les fragments IP. Quand ipfrag_high_thresh octets de m*moire sont allou*s pour cela, le gestionnaire de fragments rejettera les paquets jusqu'* ce que ipfrag_low_thresh soit atteint. /proc/sys/net/ipv4/ip_nonlocal_bind Configurez ceci si vous voulez que vos applications soient capables de se lier * une adresse qui n'appartient pas * une interface de votre syst*me. Ceci peut *tre utile quand votre machine est sur un lien non-permanent (ou m*me permanent). Vos services sont donc capables de d*marrer et de se lier * une adresse sp*cifique quand votre lien est inactif. /proc/sys/net/ipv4/ipfrag_low_thresh M*moire minimale utilis*e pour r*assembler les fragments IP. /proc/sys/net/ipv4/ipfrag_time Temps en secondes du maintien d'un fragment IP en m*moire. /proc/sys/net/ipv4/tcp_abort_on_overflow Une option bool*enne contr*lant le comportement dans le cas de nombreuses connexions entrantes. Quand celle-ci est activ*e, le noyau envoie rapidement des paquets RST quand un service est surcharg*. /proc/sys/net/ipv4/tcp_fin_timeout Temps de maintien de l'*tat FIN-WAIT-2 pour un socket dans le cas o* il a *t* ferm* de notre c*t*. Le partenaire peut *tre d*fectueux et ne jamais avoir ferm* son c*t* ou m*me mourir de mani*re inattendue. La valeur par d*faut est de 60 secondes. La valeur usuelle utilis*e dans le noyau 2.2 *tait de 180 secondes. Vous pouvez la remettre, mais rappelez vous que si votre machine a un serveur WEB surcharg*, vous risquez de d*passer la m*moire avec des kilotonnes de sockets morts. Les sockets FIN-WAIT2 sont moins dangereux que les sockets FIN-WAIT1 parce qu'ils consomment au maximum 1,5K de m*moire, mais ils ont tendance * vivre plus longtemps. Cf tcp_max_orphans. /proc/sys/net/ipv4/tcp_keepalive_time Dur*e entre l'envoi de deux messages keepalive quand l'option keepalive est activ*e. Par d*faut : 2 heures. /proc/sys/net/ipv4/tcp_keepalive_intvl A quelle fr*quence les sondes sont retransmises lorsqu'il n'y a pas eu acquittement de sonde. Par d*faut : 75 secondes. /proc/sys/net/ipv4/tcp_keepalive_probes Combien de sondes TCP keepalive seront envoy*es avant de d*cider que la connexion est bris*e. Par d*faut : 9. En multipliant par tcp_keepalive_intvl, cela donne le temps pendant lequel un lien peut *tre actif sans donner de r*ponses apr*s l'envoi d'un keepalive. /proc/sys/net/ipv4/tcp_max_orphans Nombre maximum de sockets TCP qui ne sont pas reli*s * un descripteur de fichier utilisateur, g*r* par le syst*me. Si ce nombre est d*pass*, les connexions orphelines sont imm*diatement r*initialis*es et un avertissement est envoy*. Cette limite existe seulement pour pr*venir des attaques de d*ni de services simples. Vous ne devez pas compter sur ceci ou diminuer cette limite artificiellement, mais plut*t l'augmenter (probablement apr*s avoir augment* la m*moire) si les conditions du r*seau r*clament plus que cette valeur par d*faut et r*gler vos services r*seau pour qu'ils d*truisent sans tarder ce type d'*tat. Laissez-moi vous rappeler encore que chaque orphelin consomme jusqu'* environ 64K de m*moire non swappable. /proc/sys/net/ipv4/tcp_orphan_retries Combien d'essais avant de d*truire une connexion TCP, ferm*e par notre c*t*. La valeur par d*faut de 7 correspond * un temps d'environ 50s * 16 min suivant le RTO. Si votre machine supporte un serveur Web, vous pouvez envisager de baisser cette valeur, dans la mesure o* de tels sockets peuvent consommer des ressources significatives. Cf tcp_max_orphans. /proc/sys/net/ipv4/tcp_max_syn_backlog Nombre maximum de requ*tes d'une connexion m*moris*e, qui n'avait pas encore re*u d'accus* de r*ception du client connect*. La valeur par d*faut est de 1024 pour des syst*mes avec plus de 128 Mo de m*moire et 128 pour des machines avec moins de m*moire. Si un serveur souffre de surcharge, essayez d'augmenter ce nombre. Attention ! Si vous positionnez une valeur sup*rieure * 1024, il serait pr*f*rable de changer TCP_SYNQ_HSIZE dans le fichier include/net/tcp.h pour garder TCP_SYNQ_HSIZE*16 <= tcp_max_syn_backlog et de recompiler de noyau. /proc/sys/net/ipv4/tcp_max_tw_buckets Nombre maximum de sockets timewait g*r*es par le syst*me simultan*ment. Si ce nombre est d*pass*, le socket timewait est imm*diatement d*truit et un message d'avertissement est envoy*. Cette limite n'existe que pour pr*venir des attaques de d*ni de services simples. Vous ne devez pas diminuer cette limite artificiellement, mais plut*t l'augmenter (probablement apr*s avoir augment* la m*moire) si les conditions du r*seau r*clament plus que cette valeur par d*faut. /proc/sys/net/ipv4/tcp_retrans_collapse Compatibilit* bug * bug avec certaines imprimantes d*fectueuses. Tentative d'envoi de plus gros paquets lors de la retransmission pour contourner le bug de certaines piles TCP. /proc/sys/net/ipv4/tcp_retries1 Combien d'essais avant de d*cider que quelque chose est erron* et qu'il est n*cessaire d'informer de cette suspicion la couche r*seau. La valeur minimale du RFC est de 3. C'est la valeur par d*faut ; elle correspond * un temps d'environ 3 sec * 8 min suivant le RTO. /proc/sys/net/ipv4/tcp_retries2 Combien d'essais avant de d*truire une connexion TCP active. Le [203]RFC 1122 pr*cise que la limite ne devrait pas d*passer 100 secondes. C'est un nombre trop petit. La valeur par d*faut de 15 correspond * un temps de environ 13 * 30 minutes suivant le RTO. /proc/sys/net/ipv4/tcp_rfc1337 Ce bool*en active un rectificatif pour <<*l'assassinat hasardeux des time-wait dans tcp*>>, d*crit dans le RFC 1337. S'il est activ*, le noyau rejette les paquets RST pour les sockets * l'*tat de time-wait. Par d*faut : 0 /proc/sys/net/ipv4/tcp_sack Utilise un ACK s*lectif qui peut *tre utilis* pour signifier que des paquets sp*cifiques sont manquant. Facilite ainsi une r*cup*ration rapide. /proc/sys/net/ipv4/tcp_stdurg Utilise l'interpr*tation du RFC Host Requirements du champ TCP pointeur urgent. La plupart des h*tes utilisent la vieille interpr*tation BSD. Donc, si vous activez cette option, il se peut que Linux ne communique plus correctement avec eux. Par d*faut : FALSE (FAUX) /proc/sys/net/ipv4/tcp_syn_retries Nombre de paquets SYN que le noyau enverra avant de tenter l'*tablissement d'une nouvelle connexion. /proc/sys/net/ipv4/tcp_synack_retries Pour ouvrir l'autre c*t* de la connexion, le noyau envoie un SYN avec un ACK superpos* (piggyback), pour accuser r*ception du SYN pr*c*demment envoy*. C'est la deuxi*me partie de la poign*e de main * trois voies (threeway handshake). Cette configuration d*termine le nombre de paquets SYN+ACK * envoyer avant que le noyau n'abandonne la connexion. /proc/sys/net/ipv4/tcp_timestamps Les estampillages horaires sont utilis*s, entre autres, pour se prot*ger du rebouclage des num*ros de s*quence. On peut concevoir qu'un lien * 1 gigabit puisse de nouveau rencontrer un num*ro de s*quence pr*c*dent avec une valeur hors-ligne parcequ'il *tait d'une g*n*ration pr*c*dente. L'estampillage horaire permet de reconna*tre cet <<*ancien paquet*>>. /proc/sys/net/ipv4/tcp_tw_recycle Mise en place du recyclage rapide des sockets TIME-WAIT. La valeur par d*faut est 1. Celle-ci ne devrait pas *tre chang*e sans le conseil/demande d'experts techniques. /proc/sys/net/ipv4/tcp_window_scaling TCP/IP autorise normalement des fen*tres jusqu'* une taille de 65535 octets. Pour des r*seaux vraiment rapides, cela peut ne pas *tre assez. Les options windows scaling autorisent des fen*tres jusqu'au gigaoctet, ce qui est adapt* pour les produits * grande bande passante. -------------------------------------------------------------------------- Configuration des p*riph*riques DEV peut d*signer soit une interface r*elle, soit all, soit default. Default change *galement les param*tres des interfaces qui seront cr**es par la suite. /proc/sys/net/ipv4/conf/DEV/accept_redirects Si un routeur d*cide que vous l'utilisez * tort (c'est-*-dire qu'il a besoin de r*-envoyer votre paquet sur la m*me interface), il vous enverra un message ICMP Redirect. Cela pr*sente cependant un petit risque pour la s*curit*, et vous pouvez le d*sactiver ou utiliser les redirections s*curis*es. /proc/sys/net/ipv4/conf/DEV/accept_source_route Plus vraiment utilis*. On l'utilisait pour *tre capable de donner * un paquet une liste d'adresses IP * visiter. Linux peut *tre configur* pour satisfaire cette option IP. /proc/sys/net/ipv4/conf/DEV/bootp_relay Accepte les paquets avec une adresse source 0.b.c.d et des adresses destinations qui ne correspondent ni * cet h*te, ni au r*seau local. On suppose qu'un d*mon de relais BOOTP interceptera et transmettra de tels paquets. La valeur par d*faut est 0, puisque cette fonctionnalit* n'est pas encore impl*ment*e (noyau 2.2.12). /proc/sys/net/ipv4/conf/DEV/forwarding Active ou d*sactive la transmission IP sur cette interface. /proc/sys/net/ipv4/conf/DEV/log_martians Voir la section sur le [204]Filtrage de Chemin Inverse>. /proc/sys/net/ipv4/conf/DEV/mc_forwarding Si vous faites de la transmission multidistribution (multicast) sur cette interface. /proc/sys/net/ipv4/conf/DEV/proxy_arp Si vous configurez ceci * 1, cet interface r*pondra aux requ*tes ARP pour les adresses que le noyau doit router. Peut *tre tr*s utile si vous mettez en place des <<*pseudo ponts ip*>>. Prenez bien garde d'avoir des masques de sous-r*seau corrects avant d'activer cette option. Faites *galement attention que le rp_filter agisse aussi sur le requ*tes ARP ! /proc/sys/net/ipv4/conf/DEV/rp_filter Voir la section sur le [205]Filtrage de Chemin Inverse>. /proc/sys/net/ipv4/conf/DEV/secure_redirects Accepte les messages de redirection ICMP seulement pour les passerelles indiqu*es dans la liste des passerelles par d*faut. Activ* par d*faut. /proc/sys/net/ipv4/conf/DEV/send_redirects Active la possibilit* d'envoyer les messages de redirections mentionn*es ci-dessus. /proc/sys/net/ipv4/conf/DEV/shared_media Si cela n'est pas activ*, le noyau ne consid*re pas que diff*rents sous-r*seaux peuvent communiquer directement sur cette interface. La configuration par d*faut est Yes. /proc/sys/net/ipv4/conf/DEV/tag FIXME: * remplir -------------------------------------------------------------------------- Politique de voisinage DEV peut d*signer soit une interface r*elle, soit all, soit default. Default change *galement les param*tres des interfaces qui seront cr**es par la suite. /proc/sys/net/ipv4/neigh/DEV/anycast_delay Valeur maximum du d*lai al*atoire de r*ponse exprim* en jiffies (1/100 sec) aux messages de sollicitation des voisins. N'est pas encore impl*ment* (Linux ne poss*de pas encore le support anycast). /proc/sys/net/ipv4/neigh/DEV/app_solicit D*termine le nombre de requ*tes * envoyer au d*mon ARP de l'espace utilisateur. Utilisez 0 pour d*sactiver. /proc/sys/net/ipv4/neigh/DEV/base_reachable_time Une valeur de base utilis*e pour le calcul du temps al*atoire d'acc*s comme sp*cifi* dans le RFC2461. /proc/sys/net/ipv4/neigh/DEV/delay_first_probe_time D*lai avant de tester pour la premi*re fois si le voisin peut *tre atteint. (voir gc_stale_time) /proc/sys/net/ipv4/neigh/DEV/gc_stale_time D*termine la fr*quence * laquelle on doit v*rifier les vieilles entr*es ARP. Si une entr*e est obsol*te, elle devra de nouveau *tre r*solue (ce qui est utile quand une adresse IP a *t* attribu*e * une autre machine). Si ucast_solicit est sup*rieur * 0, alors on essaie d'abord d'envoyer un paquet ARP directement * l'h*te connu. Si cela *choue, et que mcast_solicit est sup*rieur * 0, alors une requ*te ARP est multidiffus*e. /proc/sys/net/ipv4/neigh/DEV/locktime Une entr*e ARP n'est remplac*e par une nouvelle que si l'ancienne est au moins pr*sente depuis locktime. Cela *vite trop d'*criture dans le cache. /proc/sys/net/ipv4/neigh/DEV/mcast_solicit Nombre maximum d'essais cons*cutifs pour une sollicitation multicast. /proc/sys/net/ipv4/neigh/DEV/proxy_delay Temps maximum (le temps r*el est al*atoire et compris entre 0 et proxytime) avant de r*pondre * une requ*te ARP pour laquelle nous avons une entr*e de proxy ARP. Peut *tre utilis* dans certains cas pour se pr*munir des inondations r*seaux. /proc/sys/net/ipv4/neigh/DEV/proxy_qlen Longueur maximale de la file d'attente du temporisateur de cache arp en attente (Voir proxy_delay). /proc/sys/net/ipv4/neigh/DEV/retrans_time Le temps, exprim* en jiffies (1/100 sec), entre deux requ*tes ARP. Utilis* pour la r*solution d'adresses et pour d*terminer si un voisin est inaccessible. /proc/sys/net/ipv4/neigh/DEV/ucast_solicit Nombre maximum de requ*tes ARP unicast. /proc/sys/net/ipv4/neigh/DEV/unres_qlen Longueur maximum de la file d'attente pour la requ*te ARP en cours : le nombre de paquets qui sont accept*s des autres couches pendant la r*solution ARP d'une adresse. Internet QoS: Architectures and Mechanisms for Quality of Service, Zheng Wang, ISBN 1-55860-608-4 Livre traitant des sujets li*s * la qualit* de service. Bien pour comprendre les concepts de base. -------------------------------------------------------------------------- Configuration du routage /proc/sys/net/ipv4/route/error_burst Ces param*tres sont utilis*s pour limiter le nombre de messages d'avertissement *crits dans le journal du noyau par le code de routage. Plus le param*tre error_burst est grand, moins il y aura de messages. Error_burst contr*le le moment o* les messages seront supprim*s. Les configurations par d*faut se limitent * un message d'avertissement toutes les cinq secondes. /proc/sys/net/ipv4/route/error_cost Ces param*tres sont utilis*s pour limiter le nombre de messages d'avertissement *crits dans le journal du noyau par le code de routage. Plus le param*tre error_cost est grand, moins il y aura de messages. error_burst contr*le le moment o* les messages seront jet*s. Les configurations par d*faut se limitent * un message d'avertissement toutes les cinq secondes. /proc/sys/net/ipv4/route/flush L'*criture dans ce fichier provoque la vidange du cache du routage. /proc/sys/net/ipv4/route/gc_elasticity Valeurs qui contr*lent la fr*quence et le comportement de l'algorithme garbage collection du cache de routage. Ceci peut *tre important en cas de d*faut. Au moins gc_timeout secondes s'*couleront avant que le noyau ne passe * une autre route si la pr*c*dente n'est plus op*rationnelle. Configur* par d*faut * 300. Diminuez cette valeur si vous voulez passer plus rapidement ce type de probl*me. Voir aussi [206]ce message par Ard van Breemen. /proc/sys/net/ipv4/route/gc_interval Voir /proc/sys/net/ipv4/route/gc_elasticity. /proc/sys/net/ipv4/route/gc_min_interval Voir /proc/sys/net/ipv4/route/gc_elasticity. /proc/sys/net/ipv4/route/gc_thresh Voir /proc/sys/net/ipv4/route/gc_elasticity. /proc/sys/net/ipv4/route/gc_timeout Voir /proc/sys/net/ipv4/route/gc_elasticity. /proc/sys/net/ipv4/route/max_delay D*lai d'attente pour la vidange du cache du routage. /proc/sys/net/ipv4/route/max_size Taille maximum du cache de routage. Les vieilles entr*es seront purg*es quand le cache aura atteint cette taille. /proc/sys/net/ipv4/route/min_adv_mss FIXME: * remplir /proc/sys/net/ipv4/route/min_delay D*lai d'attente pour vider le cache de routage. /proc/sys/net/ipv4/route/min_pmtu FIXME: * remplir /proc/sys/net/ipv4/route/mtu_expires FIXME: * remplir /proc/sys/net/ipv4/route/redirect_load Facteurs qui d*terminent si plus de redirections ICMP doivent *tre envoy*es * un h*te sp*cifique. Aucune redirection ne sera envoy*e une fois que la limite de charge (load limit) ou que le nombre maximum de redirections aura *t* atteint. /proc/sys/net/ipv4/route/redirect_number Voir /proc/sys/net/ipv4/route/redirect_load. /proc/sys/net/ipv4/route/redirect_silence Temporisation pour les redirections. Au dela de cette p*riode, les redirections seront de nouveau envoy*es, m*me si elles ont *t* stopp*es parce que la charge ou le nombre limite a *t* atteint. -------------------------------------------------------------------------- Chapitre 14. Gestionnaires de mise en file d'attente avanc*s & moins communs Si vous constatez que vous avez des besoins qui ne sont pas g*r*s par les files d'attente cit*es pr*c*demment, le noyau contient quelques autres files d'attente plus sp*cialis*es mentionn*es ici. -------------------------------------------------------------------------- bfifo/pfifo Ces files d'attente sans classes sont plus simples que pfifo_fast dans la mesure o* elles n'ont pas de bandes internes, tout le trafic *tant vraiment *quivalent. Elles ont cependant l'avantage important de r*aliser des statistiques. Donc, m*me si vous n'avez pas besoin de mise en forme ou de donner une priorit*, vous pouvez employer ce gestionnaire pour d*terminer l'arri*r* (backlog) de votre interface. pfifo mesure en paquets et bfifo en octets. -------------------------------------------------------------------------- Param*tres & usage limit Sp*cifie la taille de la file d'attente. Mesur*e en octets pour bfifo et en paquets pour pfifo. Par d*faut, correspond * des paquets de taille *gale au param*tre txqueuelen de l'interface (voir le chapitre [207]pfifo_fast>) ou txqueuelen*mtu octets pour bfifo. -------------------------------------------------------------------------- Algorithme Clark-Shenker-Zhang (CSZ) Ceci est si th*orique que m*me Alexey (l'auteur principal de CBQ) pr*tend ne pas le comprendre. De son propre avis : David D. Clark, Scott Shenker and Lixia Zhang Supporting Real-Time Applications in an Integrated Services Packet Network: Architecture and Mechanism. Comme je le comprends, l'id*e principale est de cr*er des flux WFQ pour chaque service garanti et d'allouer le reste de la bande passante au flux factice, appel* flow-0. Le Flux-0 inclut le trafic de service pr*dictif et le trafic best-effort. Il est trait* par un ordonnanceur de priorit* qui alloue la bande passante de plus grande priorit* aux services pr*dictifs, et le reste aux paquets best-effort. Notez que dans CSZ, les flux ne sont PAS limit*s * leur bande passante. On suppose que le flux a pass* le contr*le d'admission * la fronti*re du r*seau QoS et qu'il n'a pas besoin de mises en forme suppl*mentaires. N'importe quelles autres tentatives pour am*liorer le flux ou pour le mettre en forme grce * un seau de jetons lors d'*tapes interm*diaires introduiront des retards non d*sir*s et augmenteront la gigue. A l'heure actuelle, CSZ est le seul ordonnanceur qui fournit un v*ritable service garanti. Les autres impl*mentations (incluant CBQ) n'assurent pas un d*lai garanti et rendent la gigue al*atoire. Ne semble pas actuellement un bon candidat * utiliser, * moins que vous n'ayez lu et compris l'article mentionn*. -------------------------------------------------------------------------- DSMARK Esteve Camps <[208]marvin@grn.es> <[209]esteve@hades.udg.es> Ce texte est un extrait de ma th*se sur le support QoS dans Linux, Septembre 2000. Documents sources : * [210]Draft-almesberger-wajhak-diffserv-linux-01.txt. * Exemples de la distribution iproute2. * [211]White Paper-QoS protocols and architectures et [212]Foires Aux Questions IP QoS, les deux par Quality of Service Forum. -------------------------------------------------------------------------- Introduction Avant tout, il serait pr*f*rable de lire les RFC *crits sur ce sujet (RFC2474, RFC2475, RFC2597 et RFC2598) sur le [213]site web du groupe de travail DiffServ IETF et sur le [214]site web de Werner Almesberger (Il a *crit le code permettant le support des Services Diff*renci*s sous Linux). -------------------------------------------------------------------------- A quoi DSMARK est-il reli* ? DSMARK est un gestionnaire de mise en file d'attente qui offre les fonctionnalit*s dont ont besoin les services diff*renci*s (Differentiated Services) (*galement appel*s DiffServ ou tout simplement DS). DiffServ est l'une des deux architectures actuelles de la Qualit* de Services (QoS : Quality of Services) (l'autre est appel*e services int*gr*s (Integrated Services). Elle se base sur la valeur du champ DS contenu dans l'en-t*te IP du paquet. Une des premi*res solutions dans IP pour offrir des niveaux de qualit* de services *tait le champ Type de Service (octet TOS) de l'en-t*te IP. En modifiant la valeur de ce champ, nous pouvions choisir un niveau *lev*/faible du d*bit, du d*lai ou de la fiabilit*. Cependant, cela ne fournissait pas une flexibilit* suffisante pour les besoins de nouveaux services (comme les applications temps r*el, les applications interactives et autres). Par la suite, de nouvelles architectures sont apparues. L'une d'elle a *t* DiffServ qui a gard* les bits TOS et les a renomm*s champ DS. -------------------------------------------------------------------------- Guide des services diff*renci*s Les services diff*renci*s sont orient*s groupes. Cela signifie que nous ne savons rien des flux (ce sera le but des services int*gr*s (integrated Services)). Nous connaissons par contre les agr*gations de flux et nous adopterons des comportements diff*rents suivant l'agr*gation * laquelle appartient le paquet. Quand un paquet arrive * un noeud frontalier (noeud d'entr*e du domaine DiffServ) et entre dans un domaine DiffServ, nous devrons avoir une politique, une mise en forme et/ou un marquage de ces paquets (le marquage fait r*f*rence * la mise en place d'une valeur dans le champ DS. Comme on le ferait pour des vaches :-)). Ce sera cette marque/valeur que les noeuds internes de votre domaine DiffServ regarderons pour d*terminer quel comportement ou niveau de qualit* de service appliquer. Comme vous pouvez le d*duire, les Services Diff*renci*s impliquent un domaine sur lequel toutes les r*gles DS devront *tre appliqu*es. Vous pouvez raisonner de la fa*on suivante : <<*Je classifierai tous les paquets entrant dans mon domaine. Une fois qu'ils seront entr*s dans mon domaine, ils seront soumis aux r*gles que ma classification impose et chaque noeud travers* appliquera son niveau de qualit* de service*>>. En fait, vous pouvez appliquer vos propres politiques dans vos domaines locaux, mais des autorisations au niveau service devront *tre consid*r*es lors de la connexion * d'autres domaines DS. En ce moment, vous vous posez peut-*tre beaucoup de questions. DiffServ est plus vaste que ce que j'ai expliqu*. En fait, vous pouvez comprendre que je ne peux pas r*sumer plus de trois RFC en 50 lignes :-). -------------------------------------------------------------------------- Travailler avec DSMARK Comme le sp*cifie la bibliographie concernant DiffServ, nous diff*rencions les noeuds frontaliers et les noeuds int*rieurs. Ce sont deux *l*ments importants dans le chemin qu'emprunte le trafic. Les deux r*alisent une classification quand un paquet arrive. Le r*sultat peut *tre utilis* * diff*rents endroits lors du processus DS avant que le paquet ne soit lib*r* vers le r*seau. Cela est possible car le nouveau code DiffServ fournit une structure appel*e sk_buff, incluant un nouveau champ appel* skb->tcindex. Ce champ m*morisera le r*sultat de la classification initiale et pourra *tre utilis* * plusieurs reprises dans le traitement DS. La valeur skb->tc_index sera initialement configur*e par le gestionnaire de mise en file d'attente DSMARK. Cette valeur sera extraite du champ DS de l'en-t*te IP de tous les paquets re*us. En outre, le classificateur cls_tcindex lira tout ou une partie de la valeur skb->tcindex et l'utilisera pour s*lectionner les classes. Mais, avant tout, regardons la commande qdisc DSMARK et ses param*tres : ... dsmark indices INDICES [ default_index DEFAULT_INDEX ] [ set_tc_index ] Que signifient ces param*tres ? * indices : taille de la table des couples (masque,valeur). La valeur maximum est 2^n, o* n>=0. * default_index : index d'entr*e par d*faut de la table si aucune correspondance n'est trouv*e. * set_tc_index : indique au gestionnaire DSMARK de r*cup*rer le champs DS et de l'enregistrer dans skb->tc_index. Regardons DSMARK proc*der. -------------------------------------------------------------------------- Comment SCH_DSMARK travaille. Ce gestionnaire de mise en file d'attente r*alisera les *tapes suivantes : * Si vous avez d*clar* l'option set_tc_index dans la commande qdisc, le champ DS est r*cup*r* et m*moris* dans la variable skb->tc_index. * Le classificateur est invoqu*. Celui-ci sera ex*cut* et retournera un identificateur de classe (class ID) qui sera enregistr* dans la variable skb->tc_index. Si aucun filtre correspondant n'est trouv*, nous consid*rons l'option default_index comme *tant l'identificateur de classe * enregistrer. Si, ni set_tc_index, ni default_index n'ont *t* d*clar*s, alors les r*sultats peuvent *tre non pr*dictifs. * Apr*s avoir *t* envoy* dans le gestionnaire de file d'attente interne, o* le r*sultat du filtre peut *tre r*utilis*, l'identificateur de classe retourn* par le gestionnaire est stock* dans la variable skb->tc_index. Cette valeur sera utilis*e plus tard pour indexer la table masque-valeur. Le r*sultat de l'op*ration suivante sera assign* au paquet : Nouveau_champ_DS = ( Ancien_champ_DS & masque ) | valeur * La nouvelle valeur r*sultera donc d'un ET logique entre les valeurs du champ_DS et du masque, suivi d'un OU logique avec le param*tre valeur. Regardez la figure suivante pour comprendre tout ce processus : skb->ihp->tos - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > | | ^ | -- Si vous d*clarez set_tc_index, nous configurons | | <-----Peut changer | la valeur DS dans la variable skb->tc_index | |O le champ DS | A| |R +-|-+ +------+ +---+-+ File d'attente-+ +---N|-----|----+ | | | |filtre|--->| | |--> . . . -->| | | D| | | | | |----->| tc |--->| | | interne | |---->| v | | | | | |index |--->| | | +---------------+ | ---->(masque,valeur)| -->| O | +------+ +-|-+--------------^----+ / | (. , .) | | | | ^ | | | | (. , .) | | | +----------|---------|----------------|-------|--+ (. , .) | | | sch_dsmark | | | | | +-|------------|---------|----------------|-------|------------------+ | | | <- tc_index -> | | | |(lecture)| peut changer | | <--------------Index de la table | | | | | des couples v | v v | (masque,valeur) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -> skb->tc_index Comment faire le marquage ? Il suffit de modifier le masque et la valeur associ*s * la classe que vous voulez marquer. Regardez la ligne de code suivante : tc class change dev eth0 classid 1:1 dsmark mask 0x3 value 0xb8 Cela modifie le couple (masque,valeur) dans la table de hachage, et re-marque les paquets appartenant * la classe 1:1. Vous devez "changer" ces valeurs en raison des valeurs par d*faut que le couple (masque, valeur) obtient initialement (voir le tableau ci-dessous). Nous allons maintenant expliquer comment le filtre TC_INDEX travaille, et comment il s'int*gre dans tout cela. En outre, le filtre TC_INDEX peut *tre utilis* dans des configurations autres que celles incluant les services DS. -------------------------------------------------------------------------- Le filtre TC_INDEX Voici la commande de base pour d*clarer un filtre TC_INDEX : ... tcindex [ hash SIZE ] [ mask MASK ] [ shift SHIFT ] [ pass_on | fall_through ] [ classid CLASSID ] [ police POLICE_SPEC ] Ensuite, nous montrons l'exemple utilis* pour expliquer le mode op*ratoire de TC_INDEX. Soyez attentif aux mots en gras : tc qdisc add dev eth0 handle 1:0 root dsmark indices 64 set_tc_index tc filter add dev eth0 parent 1:0 protocol ip prio 1 tcindex mask 0xfc shift 2 tc qdisc add dev eth0 parent 1:0 handle 2:0 cbq bandwidth 10Mbit cell 8 avpkt 1000 mpu 64 # Classe du trafic EF tc class add dev eth0 parent 2:0 classid 2:1 cbq bandwidth 10Mbit rate 1500Kbit avpkt 1000 prio 1 bounded isolated allot 1514 weight 1 maxburst 10 # Gestionnaire de file d'attente fifo pour le trafic EF tc qdisc add dev eth0 parent 2:1 pfifo limit 5 tc filter add dev eth0 parent 2:0 protocol ip prio 1 handle 0x2e tcindex classid 2:1 pass_on (Ce code n'est pas complet. Ce n'est qu'un extrait de l'exemple EFCBQ inclus dans la distribution iproute2). Avant tout, supposons que nous recevons un paquet marqu* comme EF. Si vous lisez le RFC2598, vous verrez que DSCP recommande une valeur de 101110 pour le trafic EF. Cela signifie que le champ DS sera *gal * 10111000 (rappelez- vous que les bits les moins significatifs de l'octet TOS ne sont pas utilis*s dans DS) ou 0xb8 en notation hexad*cimale. FILTRE TC INDEX +---+ +-------+ +---+-+ +------+ +-+ +-------+ | | | | | | | |FILTRE| +-+ +-+ | | | | | |----->| MASK | -> | | | -> |HANDLE|->| | | | -> | | -> | | | | . | =0xfc | | | | |0x2E | | +----+ | | | | | | | . | | | | | +------+ +--------+ | | | | | | . | | | | | | | | | -->| | . | SHIFT | | | | | | | |--> | | . | =2 | | | +----------------------------+ | | | | | | | | | CBQ 2:0 | | | | | +-------+ +---+--------------------------------+ | | | | | | | +-------------------------------------------------------------+ | | DSMARK 1:0 | +-------------------------------------------------------------------------+ Le paquet arrive alors avec la valeur du champ DS configur*e * 0xb8. Comme je l'ai expliqu* auparavant, le gestionnaire de mise en file d'attente dsmark, identifi* par 1:0 dans cet exemple, r*cup*re le champ DS et l'enregistre dans la variable skb->tc_index. L'*tape suivante consistera * associer un filtre * ce gestionnaire de mise en file d'attente (la seconde ligne dans cet exemple). Les op*rations suivantes seront r*alis*es : Valeur1 = skb->tc_index & MASK Cl* = Valeur1 >> SHIFT Dans cet exemple, MASK=0xFC et SHIFT=2. Valeur1 = 10111000 & 11111100 = 10111000 Cl* = 10111000 >> 2 = 00101110 -> 0x2E en hexad*cimal La valeur retourn*e correspondra * un identificateur de filtre du gestionnaire de file d'attente interne (dans l'exemple, identifier par 2:0). Si un filtre avec cet identificateur (id) existe, les conditions de contr*le et de performance seront v*rifi*es (au cas o* le filtre inclurait ceci) et l'identificateur de classe sera retourn* (dans notre exemple, classid 2:1) et stock* dans la variable skb->tc_index. Si aucun filtre avec cet identificateur n'est trouv*, le r*sultat d*pendra de la d*claration de l'option fall_through. Si tel est le cas, la valeur Cl* est retourn*e comme identificateur de classe. Si cela n'est pas le cas, une erreur est retourn*e et le traitement continue avec les filtres restant. Faites attention si vous utilisez l'option fall_through ; ceci ne peut *tre fait que si une relation existe entre les valeurs de la variable skb->tc_index et les identificateurs de classe. Les derniers param*tres * commenter sont hash et pass_on. Le premier est reli* * la taille de la table de hachage. Pass_on sera utilis* pour indiquer d'essayer le filtre suivant dans le cas o* aucun identificateur de classe *gal au r*sultat du filtre ne serait trouv*. L'action par d*faut est fall_through (regarder la table suivante). Finalement, regardons quelles sont les valeurs possibles pour la configuration de tous ces param*tres TCINDEX : Nom TC Valeur D*faut ----------------------------------------------------------------- Hash 1...0x10000 D*pendant de l'impl*mentation Mask 0...0xffff 0xffff Shift 0...15 0 Fall through / Pass_on Flag Fall_through Classid Major:minor Rien Police ..... Rien Ce type de filtre est tr*s puissant. Il est n*cessaire d'explorer toutes les possibilit*s. En outre, ce filtre n'est pas seulement utilis* dans les configurations DiffServ. Vous pouvez l'utiliser comme n'importe quel autre filtre. Je vous recommande de regarder les exemples DiffServ inclus dans la distribution iproute2. Je vous promets que j'essaierai de compl*ter ce texte d*s que possible. Tout ce que j'ai expliqu* est le r*sultat de nombreux tests. Merci de me dire si je me suis tromp* quelque part. -------------------------------------------------------------------------- Gestionnaire de mise en file d'attente d'entr*e (Ingress qdisc) Tous les gestionnaires de mise en file d'attente dont nous avons discut* jusqu'ici sont des gestionnaires de sortie. Chaque interface peut *galement avoir un gestionnaire de mise en file d'attente d'entr*e qui n'est pas utilis* pour envoyer les paquets * l'ext*rieur du p*riph*rique r*seau. Au lieu de cela, il vous autorise * appliquer des filtres tc aux paquets entrants par l'interface, ind*pendamment de s'ils ont une destination locale ou s'ils sont destin*s * *tre transmis. Etant donn* que les filtres tc contiennent une impl*mentation compl*te du Filtre * Seau de Jetons, et qu'ils sont *galement capables de s'appuyer sur l'estimation du flux fourni par le noyau, il y a beaucoup de fonctionnalit*s disponibles. Ceci vous permet de r*glementer le trafic entrant de fa*on efficace, avant m*me qu'il n'entre dans la pile IP. -------------------------------------------------------------------------- Param*tres & usage Le gestionnaire de mise en file d'attente d'entr*e ne n*cessite pas de param*tres. Il diff*re des autres gestionnaires dans le fait qu'il n'occupe pas la racine du p*riph*rique. Attachez-le comme ceci : # tc qdisc add dev eth0 ingress Ceci vous autorise * avoir d'autres gestionnaires de sortie sur votre p*riph*rique en plus du gestionnaire d'entr*e. Pour un exemple invent* sur la fa*on dont le gestionnaire d'entr*e peut *tre utilis*, voir le chapitre Recettes de cuisine. -------------------------------------------------------------------------- Random Early Detection (RED) Ce chapitre est con*u comme une introduction au routage de dorsales (backbones). Ces liaisons impliquent souvent des bandes passantes sup*rieures * 100 m*gabits/s, ce qui n*cessite une approche diff*rente de celle de votre modem ADSL * la maison. Le comportement normal des files d'attente de routeurs est appel* "tail-drop" (NdT : *limine le reste). Le "tail-drop" consiste * mettre en file d'attente un certain volume de trafic et * *liminer tout ce qui d*borde. Ce n'est pas du tout *quitable et cela conduit * des retransmissions de synchronisation. Quand une retransmission de synchronisation a lieu, la brusque rafale de rejet d'un routeur qui a atteint sa limite entra*nera une rafale de retransmissions retard*e qui inondera * nouveau le routeur congestionn*. Dans le but d'en finir avec les congestions occasionnelles des liens, les routeurs de dorsales int*grent souvent des files d'attente de grande taille. Malheureusement, bien que ces files d'attente offrent un bon d*bit, elles peuvent augmenter sensiblement les temps de latence et entra*ner un comportement tr*s saccad* des connexions TCP pendant la congestion. Ces probl*mes avec le "tail-drop" deviennent de plus en plus pr*occupants avec l'augmentation de l'utilisation d'applications hostiles au r*seau. Le noyau Linux nous offre la technique RED, abr*viation de Random Early Detect ou d*tection pr*coce directe. RED n'est pas la solution miracle * tous ces probl*mes. Les applications qui n'int*grent pas correctement la technique de "l'exponential backoff" obtiennent toujours une part trop grande de bande passante. Cependant, avec la technique RED elles ne provoquent pas trop de d*gts sur le d*bit et les temps de latence des autres connexions. RED *limine statistiquement des paquets du flux avant qu'il n'atteigne sa limite "dure" (hard). Sur une dorsale congestionn*e, cela entra*ne un ralentissement en douceur de la liaison et *vite les retransmissions de synchronisation. La technique RED aide aussi TCP * trouver une vitesse "*quitable" plus rapidement : en permettant d'*liminer des paquets plus t*t, il conserve une file d'attente plus courte et des temps de latence mieux contr*l*s. La probabilit* qu'un paquet soit *limin* d'une connexion particuli*re est proportionnelle * la bande passante utilis*e par cette connexion plut*t qu'au nombre de paquets qu'elle envoie. La technique RED est une bonne gestion de file d'attente pour les dorsales, o* vous ne pouvez pas vous permettre le co*t d'une m*morisation d'*tat par session qui est n*cessaire pour une mise en file d'attente vraiment *quitable. Pour utiliser RED, vous devez r*gler trois param*tres : Min, Max et burst. Min est la taille minimum de la file d'attente en octets avant que les rejets n'aient lieu, Max est le maximum "doux" (soft) en dessous duquel l'algorithme s'efforcera de rester, et burst est le nombre maximum de paquets envoy*s "en rafale". Vous devriez configurer Min en calculant le plus grand temps de latence acceptable pour la mise en file d'attente, multipli* par votre bande passante. Par exemple, sur mon lien ISDN * 64 Kbits/s, je voudrais avoir un temps de latence de base de mise en file d'attente de 200 ms. Je configure donc Min * 1600 octets (= 0,2 x 64000 / 8). Imposer une valeur Min trop petite va d*grader le d*bit et une valeur Min trop grande va d*grader le temps de latence. Sur une liaison lente, choisir un coefficient Min petit ne peut pas remplacer une r*duction du MTU pour am*liorer les temps de r*ponse. Vous devriez configurer Max * au moins deux fois Min pour *viter les synchronisations. Sur des liens lents avec de petites valeurs de Min, il peut *tre prudent d'avoir Max quatre fois plus grand que Min ou plus. Burst contr*le la r*ponse de l'algorithme RED aux rafales. Burst doit *tre choisi plus grand que min/avpkt (paquet moyen). Exp*rimentalement, j'ai trouv* que (min+min+max)/(3*avpkt) marche bien. De plus, vous devez configurer limit et avpkt. Limit est une valeur de s*curit* : s'il y a plus de Limit octets dans la file, RED reprend la technique "tail-drop". Je choisis une valeur typique *gale * 8 fois Max. Avpkt devrait *tre fix* * la taille moyenne d'un paquet. 1000 fonctionne correctement sur des liaisons Internet haut d*bit ayant un MTU de 1500 octets. Lire [215]l'article sur la file d'attente RED par Sally Floyd et Van Jacobson pour les informations techniques. -------------------------------------------------------------------------- Generic Random Early Detection Il n'y a pas grand chose de connu sur GRED. Il ressemble * GRED avec plusieurs files d'attente internes, celles-ci *tant choisies en se basant sur le champ tcindex de Diffserv. Selon une diapositive trouv*e [216]ici, il poss*de les capacit*s Distributed Weighted RED de Cisco, ainsi que les capacit*s RIO de Clark. Chaque file d'attente virtuelle peut avoir ses propres "Drop Parameters". FIXME: Demandez * Jamal or Werner de nous en dire plus -------------------------------------------------------------------------- Emulation VC/ATM Ceci est l'effort principal de Werner Almesberger pour vous autoriser * construire des circuits virtuels au-dessus des sockets TCP/IP. Le circuit virtuel est un concept venant de la th*orie des r*seaux ATM. Pour plus d'informations, voir la [217]page ATM sur Linux. -------------------------------------------------------------------------- Weighted Round Robin (WRR) Ce gestionnaire de mise en file d'attente n'est pas inclus dans les noyaux standards, mais peut *tre t*l*charg*e * partir de [218]ce lien. Ce gestionnaire de mise en file d'attente n'a *t* test* qu'avec les noyaux 2.2, mais marchera probablement *galement avec les noyaux 2.4/2.5. La file d'attente WRR partage la bande passante entre ses classes en utilisant la technique du tourniquet pond*r*. Ceci est similaire * la file d'attente CBQ qui contient des classes sur lesquelles l'on peut associer arbitrairement des files d'attente. Toutes les classes qui ont suffisamment de demandes obtiendront la bande passante proportionnellement au poids associ* des classes. Les poids peuvent *tre configur*s manuellement en utilisant le programme tc. Ils peuvent *galement *tre configur*s pour d*cro*tre automatiquement pour les classes transf*rant moins de donn*es. La file d'attente a un classificateur int*gr* qui assigne les paquets venant ou allant vers diff*rentes machines * diff*rentes classes. On peut utiliser soit l'adresse MAC soit l'adresse IP de l'adresse source ou de destination. L'adresse MAC ne peut cependant *tre utilis*e que quand la boite Linux est un pont ethernet. Les classes sont automatiquement assign*es aux machines en fonction des paquets vus. Ce gestionnaire de mise en file d'attente peut *tre tr*s utile au site comme les r*sidences *tudiantes o* des individus sans liens particuliers partagent une connexion Internet. Un ensemble de scripts pour configurer un tel cas de figure pour ce genre de site est propos* dans la distribution WRR. -------------------------------------------------------------------------- Chapitre 15. Recettes de cuisine Cette section contient des <<*recettes de cuisine*>> qui peuvent vous aider * r*soudre vos probl*mes. Un livre de cuisine ne remplace cependant pas une r*elle compr*hension, essayez donc d'assimiler ce qui suit. -------------------------------------------------------------------------- Faire tourner plusieurs sites avec diff*rentes SLA (autorisations) Vous pouvez faire cela de plusieurs mani*res. Apache poss*de un module qui permet de le supporter, mais nous montrerons comment Linux peut le faire pour d'autres services. Les commandes ont *t* reprises d'une pr*sentation de Jamal Hadi, dont la r*f*rence est fournie ci-dessous. Disons que nous avons deux clients avec : http, ftp et du streaming audio. Nous voulons leur vendre une largeur de bande passante limit*e. Nous le ferons sur le serveur lui-m*me. Le client A doit disposer d'au moins 2 m*gabits, et le client B a pay* pour 5 m*gabits. Nous s*parons nos clients en cr*ant deux adresses IP virtuelles sur notre serveur. # ip address add 188.177.166.1 dev eth0 # ip address add 188.177.166.2 dev eth0 C'est * vous d'associer les diff*rents serveurs * la bonne adresse IP. Tous les d*mons courants supportent cela. Nous pouvons tout d'abord attacher une mise en file d'attente CBQ * eth0 : # tc qdisc add dev eth0 root handle 1: cbq bandwidth 10Mbit cell 8 avpkt 1000 \ mpu 64 Nous cr*ons ensuite les classes pour nos clients : # tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 10Mbit rate \ 2MBit avpkt 1000 prio 5 bounded isolated allot 1514 weight 1 maxburst 21 # tc class add dev eth0 parent 1:0 classid 1:2 cbq bandwidth 10Mbit rate \ 5Mbit avpkt 1000 prio 5 bounded isolated allot 1514 weight 1 maxburst 21 Nous ajoutons les filtres pour nos deux classes : ##FIXME: Pourquoi cette ligne, que fait-elle ? Qu'est-ce qu'un diviseur ? ##FIXME: Un diviseur est li* * une table de hachage et au nombre de seaux -ahu # tc filter add dev eth0 parent 1:0 protocol ip prio 5 handle 1: u32 divisor 1 # tc filter add dev eth0 parent 1:0 prio 5 u32 match ip src 188.177.166.1 flowid 1:1 # tc filter add dev eth0 parent 1:0 prio 5 u32 match ip src 188.177.166.2 flowid 1:2 Et voil* qui est fait. FIXME: Pourquoi pas un filtre token bucket ? Y a t-il un retour par d*faut * pfifo_fast quelque part ? -------------------------------------------------------------------------- Prot*ger votre machine des inondations SYN D'apr*s la documentation iproute d'Alexey adapt*e * netfilter. Si vous utilisez ceci, prenez garde d'ajuster les nombres avec des valeurs raisonnables pour votre syst*me. Si vous voulez prot*ger tout un r*seau, oubliez ce script, qui est plus adapt* * un h*te seul. Il appara*t que la toute derni*re version de l'outil iproute2 est n*cessaire pour que ceci fonctionne avec le noyau 2.4.0. #! /bin/sh -x # # script simple utilisant les capacit*s de Ingress. # Ce script montre comment on peut limiter le flux entrant des SYN. # Utile pour la protection des TCP-SYN. Vous pouvez utiliser IPchains # pour b*n*ficier de puissantes fonctionnalit*s sur les SYN. # # chemins vers les divers utilitaires # * changer en fonction des v*tres # TC=/sbin/tc IP=/sbin/ip IPTABLES=/sbin/iptables INDEV=eth2 # # marque tous les paquets SYN entrant * travers $INDEV avec la valeur 1 ############################################################ $iptables -A PREROUTING -i $INDEV -t mangle -p tcp --syn \ -j MARK --set-mark 1 ############################################################ # # installe la file d'attente ingress sur l'interface associ*e ############################################################ $TC qdisc add dev $INDEV handle ffff: ingress ############################################################ # # Les paquets SYN ont une taille de 40 octets (320 bits), donc trois SYN # ont une taille de 960 bits (approximativement 1Kbit) ; nous limitons donc # les SYNs entrants * 3 par seconde (pas vraiment utile, mais sert * # montrer ce point -JHS ############################################################ $TC filter add dev $INDEV parent ffff: protocol ip prio 50 handle 1 fw \ police rate 1kbit burst 40 mtu 9k drop flowid :1 ############################################################ # echo "---- qdisc parameters Ingress ----------" $TC qdisc ls dev $INDEV echo "---- Class parameters Ingress ----------" $TC class ls dev $INDEV echo "---- filter parameters Ingress ----------" $TC filter ls dev $INDEV parent ffff: #supprime la file d'attente ingress #$TC qdisc del $INDEV ingress -------------------------------------------------------------------------- Limiter le d*bit ICMP pour emp*cher les d*nis de service R*cemment, les attaques distribu*es de d*ni de service sont devenues une nuisance importante sur Internet. En filtrant proprement et en limitant le d*bit de votre r*seau, vous pouvez * la fois *viter de devenir victime ou source de ces attaques. Vous devriez filtrer vos r*seaux de telle sorte que vous n'autorisiez pas les paquets avec une adresse IP source non locale * quitter votre r*seau. Cela emp*che les utilisateurs d'envoyer de mani*re anonyme des cochonneries sur Internet. La limitation de d*bit peut faire encore mieux, comme vu plus haut. Pour vous rafra*chir la m*moire, revoici notre diagramme ASCII : [Internet] ------ [routeur Linux] --- [Bureau+FAI] eth1 eth0 Nous allons d'abord configurer les parties pr*-requises : # tc qdisc add dev eth0 root handle 10: cbq bandwidth 10Mbit avpkt 1000 # tc class add dev eth0 parent 10:0 classid 10:1 cbq bandwidth 10Mbit rate \ 10Mbit allot 1514 prio 5 maxburst 20 avpkt 1000 Si vous avez des interfaces de 100 Mbits ou plus, ajustez ces nombres. Maintenant, vous devez d*terminer combien de trafic ICMP vous voulez autoriser. Vous pouvez r*aliser des mesures avec tcpdump, en *crivant les r*sultats dans un fichier pendant un moment, et regarder combien de paquets ICMP passent par votre r*seau. Ne pas oublier d'augmenter la longueur du "snapshot". Si la mesure n'est pas possible, vous pouvez consacrer par exemple 5% de votre bande passante disponible. Configurons notre classe : # tc class add dev eth0 parent 10:1 classid 10:100 cbq bandwidth 10Mbit rate \ 100Kbit allot 1514 weight 800Kbit prio 5 maxburst 20 avpkt 250 \ bounded Cela limite le d*bit * 100 Kbits sur la classe. Maintenant, nous avons besoin d'un filtre pour assigner le trafic ICMP * cette classe : # tc filter add dev eth0 parent 10:0 protocol ip prio 100 u32 match ip protocol 1 0xFF flowid 10:100 -------------------------------------------------------------------------- Donner la priorit* au trafic interactif Si beaucoup de donn*es arrivent * votre lien ou en partent, et que vous essayez de faire de la maintenance via telnet ou ssh, cela peut poser probl*me : d'autres paquets bloquent vos frappes clavier. Cela ne serait-il pas mieux si vos paquets interactifs pouvaient se faufiler dans le trafic de masse ? Linux peut faire cela pour vous. Comme pr*c*demment, nous avons besoin de manipuler le trafic dans les deux sens. Evidemment, cela marche mieux s'il y a des machines Linux aux deux extr*mit*s du lien, bien que d'autres UNIX soient capables de faire la m*me chose. Consultez votre gourou local Solaris/BSD pour cela. Le gestionnaire standard pfifo_fast a trois "bandes" diff*rentes. Le trafic de la bande 0 est transmis en premier, le trafic des bandes 1 et 2 *tant trait* apr*s. Il est vital que votre trafic interactif soit dans la bande 0 ! Ce qui suit est adapt* du (bient*t obsol*te) Ipchains-HOWTO : Il y a quatre bits rarement utilis*s dans l'en-t*te IP, appel*s bits de Type de Service (TOS). Ils affectent la mani*re dont les paquets sont trait*s. Les quatre bits sont "D*lai Minimum", "D*bit Maximum", "Fiabilit* Maximum" et "Co*t Minimum". Seul un de ces bits peut *tre positionn*. Rob van Nieuwkerk, l'auteur du code TOS-mangling dans ipchains, le configure comme suit : Le "D*lai Minimum" est particuli*rement important pour moi. Je le positionne * 1 pour les paquets interactifs sur mon routeur (Linux) qui envoie le trafic vers l'ext*rieur. Je suis derri*re un modem * 33,6 Kbps. Linux r*partit les paquets dans trois files d'attente. De cette mani*re, j'obtiens des performances acceptables pour le trafic interactif tout en t*l*chargeant en m*me temps. L'utilisation la plus commune est de configurer les connexions telnet et ftp * "D*lai Minimum" et les donn*es FTP * "D*bit Maximum". Cela serait fait comme suit, sur mon routeur : # iptables -A PREROUTING -t mangle -p tcp --sport telnet \ -j TOS --set-tos Minimize-Delay # iptables -A PREROUTING -t mangle -p tcp --sport ftp \ -j TOS --set-tos Minimize-Delay # iptables -A PREROUTING -t mangle -p tcp --sport ftp-data \ -j TOS --set-tos Maximize-Throughput En fait, cela ne marche que pour les donn*es venant d'un telnet ext*rieur vers votre ordinateur local. Dans l'autre sens, *a se fait tout seul : telnet, ssh, et consorts configurent le champ TOS automatiquement pour les paquets sortants. Si vous avez un client incapable de le faire, vous pouvez toujours le faire avec netfilter. Sur votre machine locale : # iptables -A OUTPUT -t mangle -p tcp --dport telnet \ -j TOS --set-tos Minimize-Delay # iptables -A OUTPUT -t mangle -p tcp --dport ftp \ -j TOS --set-tos Minimize-Delay # iptables -A OUTPUT -t mangle -p tcp --dport ftp-data \ -j TOS --set-tos Maximize-Throughput -------------------------------------------------------------------------- Cache web transparent utilisant netfilter, iproute2, ipchains et squid Cette section a *t* envoy*e par le lecteur Ram Narula de "Internet for Education" (Internet pour l'*ducation) (Thailande). La technique habituelle pour r*aliser ceci dans Linux est probablement l'utilisation d'ipchains APRES s'*tre assur* que le trafic sortant du port 80 (web) est rout* * travers le serveur faisant fonctionner squid. Il y a 3 m*thodes communes pour *tre s*r que le trafic sortant du port 80 est rout* vers le serveur faisant fonctionner squid et une quatri*me est introduite ici. La passerelle le fait. Si vous pouvez dire * votre passerelle que les paquets sortants * destination du port 80 doivent *tre envoy*s vers l'adresse IP du serveur squid. MAIS Ceci am*nerait une charge suppl*mentaire sur le routeur et des routeurs commerciaux peuvent m*me ne pas supporter ceci. Utiliser un commutateur Couche 4. Les commutateurs Couche 4 peuvent manipuler ceci sans aucun probl*me. MAIS Le co*t pour un tel *quipement est en g*n*ral tr*s *lev*. Typiquement, un commutateur couche 4 co*te normalement plus cher qu'un serveur classique + un bon serveur linux. Utiliser le serveur cache comme passerelle r*seau Vous pouvez forcer TOUT le trafic * travers le serveur cache MAIS Ceci est plut*t risqu* dans la mesure o* Squid utilise beaucoup de ressources CPU, ce qui peut conduire * une baisse des performances de tout le r*seau. Le serveur peut *galement ne plus fonctionner et personne sur le r*seau ne pourra acc*der * Internet si cela a lieu. Routeur Linux+NetFilter. En utilisant Netfilter, une autre technique peut *tre impl*ment*e. Celle-ci consiste * utiliser Netfilter pour "marquer" les paquets * destination du port 80 et * utiliser iproute2 pour router les paquets "marqu*s" vers le serveur Squid. |----------------| | Impl*mentation | |----------------| Adresses utilis*es 10.0.0.1 naret (serveur NetFilter) 10.0.0.2 silom (serveur Squid) 10.0.0.3 donmuang (routeur connect* * Internet) 10.0.0.4 kaosarn (un autre serveur sur le r*seau) 10.0.0.5 RAS 10.0.0.0/24 r*seau principal 10.0.0.0/19 r*seau total |----------------| |Sch*ma du r*seau| |----------------| Internet | donmuang | ------------hub/commutateur---------- | | | | naret silom kaosarn RAS etc. Premi*rement, faire en sorte que tout le trafic passe par naret en *tant s*r que c'est la passerelle par d*faut, * l'exception de silom. La passerelle par d*faut de silom doit *tre donmuang (10.0.0.3) ou ceci cr*erait une boucle du trafic web. (Tous les serveurs sur mon r*seau avaient 10.0.0.1 comme passerelle par d*faut qui *tait l'ancienne adresse du routeur donmuang. Cela m'a conduit * attribuer 10.0.0.3 comme adresse IP * donmuang et * donner 10.0.0.1 comme adresse IP * naret.) Silom ----- -configurer squid et ipchains Pour la configuration du serveur Squid sur silom, soyez s*r que celui-ci supporte le cache/proxy transparent (transparent caching/proxying). Le port par d*faut pour squid est en g*n*ral 3128. Tout le trafic pour le port 80 doit donc *tre redirig* localement vers le port 3128. Ceci peut *tre fait en utilisant ipchains comme suit : silom# ipchains -N allow1 silom# ipchains -A allow1 -p TCP -s 10.0.0.0/19 -d 0/0 80 -j REDIRECT 3128 silom# ipchains -I input -j allow1 Ou, avec netfilter: silom# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128 (note: vous pouvez avoir *galement d'autres entr*es) Pour plus d'informations sur la configuration du serveur Squid, se r*f*rer * la page FAQ Squid sur [219]http://squid.nlanr.net). Soyez s*r que l"ip forwarding" est actif sur votre serveur et que la passerelle par d*faut pour ce serveur est donmuand (PAS naret). Naret ----- - configurer squid et ipchains - d*sactiver les messages icmp REDIRECT (si besoin) 1. "Marquer" les paquets * destination du port 80 avec la valeur 2 naret# iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 80 \ -j MARK --set-mark 2 2. Configurer iproute2 de sorte qu'il route les paquets avec la marque 2 vers silom naret# echo 202 www.out >> /etc/iproute2/rt_tables naret# ip rule add fwmark 2 table www.out naret# ip route add default via 10.0.0.2 dev eth0 table www.out naret# ip route flush cache Si donmuang et naret sont sur le m*me r*seau, naret ne doit pas envoyer de messages icmp REDIRECT. Ceux-ci doivent *tre d*sactiv*s par : naret# echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects naret# echo 0 > /proc/sys/net/ipv4/conf/default/send_redirects naret# echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects La configuration est termin*e, v*rifions-la. Sur naret: naret# iptables -t mangle -L Chain PREROUTING (policy ACCEPT) target prot opt source destination MARK tcp -- anywhere anywhere tcp dpt:www MARK set 0x2 Chain OUTPUT (policy ACCEPT) target prot opt source destination naret# ip rule ls 0: from all lookup local 32765: from all fwmark 2 lookup www.out 32766: from all lookup main 32767: from all lookup default naret# ip route list table www.out default via 203.114.224.8 dev eth0 naret# ip route 10.0.0.1 dev eth0 scope link 10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.1 127.0.0.0/8 dev lo scope link default via 10.0.0.3 dev eth0 (soyez s*r que silom appartiens * l'une des lignes ci-dessus. Dans ce cas, c'est la ligne avec 10.0.0.0/24) |------| |-FAIT-| |------| -------------------------------------------------------------------------- Sch*ma du trafic apr*s l'impl*mentation |---------------------------------------| |Sch*ma du trafic apr*s l'impl*mentation| |---------------------------------------| INTERNET /\ || \/ -----------------routeur donmuang--------------------- /\ /\ || || || || || \/ || naret silom || *trafic * destination du port 80=====>(cache) || /\ || || || \/ \/ \\===================================kaosarn, RAS, etc. Noter que le r*seau est asym*trique car il y a un saut suppl*mentaire sur le chemin sortant. Voici le cheminement d'un paquet traversant le r*seau de kaosarn allant et venant d'Internet. Pour le trafic web/http : requ*te http kaosarn->naret->silom->donmuang->Internet r*ponse http de Internet->donmuang->silom->kaosarn Pour les requ*tes non web/http (par ex. telnet) : donn*es sortantes kaosarn->naret->donmuang->Internet donn*es entrantes d'Internet->donmuang->kaosarn -------------------------------------------------------------------------- Circonvenir aux probl*mes de la d*couverte du MTU de chemin en configurant un MTU par routes Pour envoyer de grande quantit* de donn*es, Internet fonctionne g*n*ralement mieux quand de grands paquets sont utilis*s. Chaque paquet implique une d*cision de routage. Le transfert d'un fichier de 1Mo peut entra*ner soit l'envoi de 700 paquets, en maximisant la taille des paquets, soit de 4000 paquets en utilisant la plus petite taille possible. Cependant, tous les *l*ments d'Internet ne supportent pas une capacit* utile (payload) de 1460 octets par paquet. Il est de plus n*cessaire d'essayer de trouver le plus grand paquet qui "conviendra" le mieux, dans le but d'optimiser la connexion. Ce processus est appel* "D*couverte du MTU de chemin", o* MTU signifie 'Maximum Transfert Unit' (Unit* de transfert maximum). Quand un routeur rencontre un paquet qui est trop gros pour *tre envoy* en un seul morceau, ET que celui-ci a *t* marqu* avec le bit "Don't Fragment", il retourne un message ICMP indiquant qu'il a *t* oblig* de rejeter le paquet. L'h*te *metteur prend acte de cette indication en envoyant des paquets plus petits et, par it*ration, peut trouver la taille optimum du paquet pour une connexion * travers un chemin particulier. Ceci fonctionnait correctement jusqu'* ce que Internet soit d*couvert par des vandales qui s'efforcent de perturber les communications. Ceci a conduit les administrateurs *, soit bloquer, soit mettre en forme le trafic ICMP lors d'essais malencontreux dans le but d'am*liorer la s*curit* ou la robustesse de leurs services Internet. La cons*quence, maintenant, est que la d*couverte du MTU de chemin fonctionne de moins en moins bien, et *choue pour certaines routes, conduisant * d'*tranges sessions TCP/IP qui tombent peu de temps apr*s. Bien que je n'aie pas de preuves de ceci, deux sites avec qui j'avais l'habitude d'avoir des probl*mes faisaient fonctionner * la fois Alteon et Acedirectors avant les syst*mes affect*s. Peut-*tre quelqu'un avec plus de connaissances peut fournir des indices quant * la raison de ce qui se passe. -------------------------------------------------------------------------- Solution Quand vous rencontrez des sites qui pr*sentent ce probl*me, vous pouvez d*sactiver la d*couverte du MTU de chemin en le configurant manuellement. Koos van den Hout a * peu pr*s *crit : Le probl*me suivant : j'ai configur* le mtu et mru de ma ligne d*di*e fonctionnant avec ppp * 296 dans la mesure o* le d*bit est de seulement 33k6 et que je ne peux pas influencer la file d'attente de l'autre c*t*. A 296, la r*ponse * l'appui d'une touche intervient dans un d*lai raisonnable. Et, de mon c*t*, j'ai un routeur avec translation d'adresse (masquage) fonctionnant (bien s*r) sous Linux. R*cemment, j'ai s*par* le serveur du routeur de sorte que la plupart des applications fonctionnent sur une machine diff*rente de celle qui r*alise le routage. J'ai alors eu des probl*mes en me connectant sur l'irc. Grosse panique ! Je vous assure que certains essais trouvaient que j'*tais connect* * l'irc, me montrant m*me comme connect* sur l'irc mais je ne recevais pas le "motd" (message of the day, message du jour) de l'irc. J'ai v*rifi* ce qui pouvait *tre erron* et ai not* que j'avais d*j* eu des soucis li*s au MTU en contactant certains sites web. Je n'avais aucun souci pour les atteindre quand le MTU *tait * 1500, le probl*me n'apparaissant que lorsque le MTU *tait configur* * 296. Puisque les serveurs irc bloquent tout le trafic dont il n'ont pas besoin pour leurs op*rations imm*diates, ils bloquent aussi l'icmp. J'ai manoeuvr* pour convaincre les responsables d'un serveur web que ceci *tait la cause d'un probl*me, mais les responsables du serveur irc n'avaient pas l'intention de r*parer ceci. Donc, je devais *tre s*r que le trafic masqu* sortant partait avec le mtu faible du lien externe. Mais, je voulais que le trafic ethernet local ait le MTU normal (pour des choses comme le trafic nfs). Solution : ip route add default via 10.0.0.1 mtu 296 (10.0.0.1 *tant ma passerelle par d*faut, l'adresse interne de mon routeur masquant) En g*n*ral, il est possible d'outrepasser la d*couverte du MTU de chemin en configurant des routes sp*cifiques. Par exemple, si seuls certains r*seaux posent probl*mes, ceci devrait aider : ip route add 195.96.96.0/24 via 10.0.0.1 mtu 1000 -------------------------------------------------------------------------- Circonvenir aux probl*mes de la d*couverte du MTU de chemin en imposant le MSS (pour les utilisateurs de l'ADSL, du cble, de PPPoE & PPtP) Comme expliqu* au-dessus, la d*couverte du MTU de chemin ne marche pas aussi bien que cela devrait *tre. Si vous savez qu'un saut de votre r*seau a un MTU limit* (<1500), vous ne pouvez pas compter sur la d*couverte du MTU de chemin pour le d*couvrir. Outre le MTU, il y a encore un autre moyen de configurer la taille maximum du paquet, par ce qui est appel* le MSS (Maximum Segment Size, Taille Maximum du Segment). C'est un champ dans les options TCP du paquet SYN. Les noyaux Linux r*cents, et quelques pilotes de p*riph*rique PPPoE (notamment, l'excellent Roaring Penguin) impl*mentent la possibilit* de 'fixer le MSS'. Le bon c*t* de tout ceci est que, en positionnant la valeur MSS, vous d*tes * l'h*te distant de mani*re *quivoque "n'essaie pas de m'envoyer des paquets plus grands que cette valeur". Aucun trafic ICMP n'est n*cessaire pour faire fonctionner cela. Malheureusement, c'est de la bidouille *vidente -- *a d*truit la propri*t* *bout-en-bout* de la connexion en modifiant les paquets. Ayant dit cela, nous utilisons cette astuce dans beaucoup d'endroit et cela fonctionne comme un charme. Pour que tout ceci fonctionne, vous aurez besoin au moins de iptables-1.2.1a et de Linux 2.4.3 ou plus. La ligne de commande basique est : # iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu Ceci calcule le MSS appropri* pour votre lien. Si vous vous sentez courageux ou que vous pensez *tre le mieux plac* pour juger, vous pouvez aussi faire quelque chose comme ceci : # iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 128 Ceci configure le MSS du paquet SYN * 128. Utilisez ceci si vous avez de la voix sur IP (VoIP) avec de tous petits paquets, et de grands paquets http qui provoquent des coupures dans vos communications vocales. -------------------------------------------------------------------------- Le Conditionneur de Trafic Ultime : Faible temps de latence, T*l*chargement vers l'amont et l'aval rapide Note : ce script a r*cemment *t* mis * niveau et il ne marchait avant qu'avec les clients Linux de votre r*seau ! Vous devriez donc le mettre * jour si vous avez des machines Windows ou des Macs dans votre r*seau qui n'*taient pas capables de t*l*charger plus rapidement pendant que d'autres *taient en train de t*l*charger vers l'amont. J'ai essay* de cr*er le Saint Graal : Maintenir * tout moment un faible temps de latence pour le trafic interactif Ceci signifie que la r*cup*ration ou la transmission de fichiers ne doivent pas perturber SSH ou m*me telnet. Ceci est la chose la plus importante, car m*me un temps de latence de 200ms est important pour pouvoir travailler confortablement. Autoriser le 'surf' * des vitesses raisonnables pendant que l'on t*l*charge vers l'amont ou vers l'aval M*me si http est un trafic de masse, les autres trafics ne doivent pas trop le noyer. Etre s*r que le t*l*chargement vers l'amont ne va pas faire du tort aux t*l*chargements vers l'aval et aux autres *l*ments autour Le principal ph*nom*ne observ* est la forte r*duction de la vitesse de t*l*chargement vers l'aval quand il y a du trafic montant. Il s'av*re que tout ceci est possible, au prix d'une minuscule r*duction de la bande passante. La pr*sence de grandes files d'attente sur les dispositifs d'acc*s domestiques, comme le cble ou les modems DSL, explique pourquoi les t*l*chargements vers l'amont, vers l'aval et ssh se p*nalisent mutuellement. La prochaine partie explique en profondeur ce qui provoque les retards, et comment nous pouvons les corriger. Vous pouvez sans danger la passer et aller directement au script si vous vous fichez de la fa*on dont la magie op*re. -------------------------------------------------------------------------- Pourquoi cela ne marche t-il pas bien par d*faut ? Les FAI savent que leurs performances ne sont seulement jug*es que sur la vitesse * laquelle les personnes peuvent t*l*charger vers l'aval. En plus de la bande passante disponible, la vitesse de t*l*chargement est lourdement influenc*e par la perte des paquets, qui g*ne s*rieusement les performances de TCP/IP. Les grandes files d'attente peuvent aider * pr*venir la perte des paquets, et augmenter les t*l*chargements. Les FAI configurent donc de grandes files d'attente. Ces grandes files d'attente endommagent cependant l'interactivit*. Une frappe doit d'abord parcourir la file d'attente du flux montant, ce qui peut prendre plusieurs secondes, et aller jusqu'* l'h*te distant. Elle est alors trait*e, conduisant * un paquet de retour qui doit traverser la file d'attente du flux descendant, localis*e chez votre FAI, avant qu'elle n'apparaisse sur l'*cran. Cet HOWTO nous enseigne plusieurs mani*res de modifier et traiter la file d'attente mais, malheureusement, toutes les files d'attente ne nous sont pas accessibles. Les files d'attente du FAI sont sans limites et la file d'attente du flux montant r*side probablement dans votre modem cble ou votre p*riph*rique DSL. Il se peut que vous soyez capable ou non de le configurer. La plupart du temps, ce ne sera pas le cas. Et apr*s ? Etant donn* que nous ne pouvons pas contr*ler ces files d'attente, elles doivent dispara*tre et *tre transf*r*es sur notre routeur Linux. Heureusement, ceci est possible. Limiter la vitesse de t*l*chargement vers l'amont (upload) En limitant notre vitesse de t*l*chargement vers l'amont * une vitesse l*g*rement plus faible que la vitesse r*elle disponible, il n'y a pas de files d'attente mises en place dans notre modem. La file d'attente est maintenant transf*r*e vers Linux. Limiter la vitesse de t*l*chargement vers l'aval (download) Ceci est l*g*rement plus rus* dans la mesure o* nous ne pouvons pas vraiment influencer la vitesse * laquelle Internet nous envoie les donn*es. Nous pouvons cependant rejeter les paquets qui arrivent trop vite, ce qui provoque le ralentissement de TCP/IP jusqu'au d*bit d*sir*. Comme nous ne voulons pas supprimer inutilement du trafic, nous configurons une vitesse de rafale ('burst') plus grande. Maintenant que nous avons fait ceci, nous avons *limin* totalement la file d'attente du flux descendant (sauf pour de courtes rafales de donn*es), et obtenu la possibilit* de g*rer la file d'attente du flux montant avec toute la puissance Linux. Il nous reste * nous assurer que le trafic interactif se retrouve au d*but de la file d'attente du flux montant. Pour *tre s*r que le flux montant ne va pas p*naliser le flux descendant, nous d*pla*ons *galement les paquets ACK au d*but de la file d'attente. C'est ce qui provoque normalement un *norme ralentissement quand du trafic de masse est g*n*r* dans les deux sens. Les paquets ACK du trafic descendant rentrent en concurrence avec le trafic montant et sont donc ralentis. Si nous avons fait tout ceci, nous obtenons les mesures suivantes en utilisant l'excellente connexion ADSL de xs4all, en Hollande : Temps de latence de base : round-trip min/avg/max = 14.4/17.1/21.7 ms Sans le conditionneur de trafic, lors d'un t*l*chargement vers l'aval : round-trip min/avg/max = 560.9/573.6/586.4 ms Sans le conditionneur de trafic, lors d'un t*l*chargement vers l'amont : round-trip min/avg/max = 2041.4/2332.1/2427.6 ms Avec le conditionneur, lors d'un t*l*chargement vers l'amont * 220kbit/s : round-trip min/avg/max = 15.7/51.8/79.9 ms Avec le conditionneur, lors d'un t*l*chargement vers l'aval * 850kbit/s : round-trip min/avg/max = 20.4/46.9/74.0 ms Lors d'un t*l*chargement vers l'amont, les t*l*chargements vers l'aval s'effectuent * environ 80 % de la vitesse maximale disponible et 90% pour les t*l*chargements vers l'amont. Le temps de latence augmente alors jusqu'* 850 ms ; je n'ai pas encore d*termin* la raison de ce ph*nom*ne. Ce que vous pouvez attendre de ce script d*pend largement de votre vitesse de lien r*elle. Quand vous t*l*chargez vers l'amont * pleine vitesse, il y aura toujours un paquet devant votre frappe de clavier. Ceci est la limite basse de votre temps de latence. Pour la calculer, divisez votre MTU par la vitesse du flux montant. Les valeurs classiques seront un peu plus *lev*es que *a. Diminuez votre MTU pour un meilleur effet ! Voici deux versions de ce script, une avec l'excellent HTB de Devik, et l'autre avec CBQ qui est pr*sent dans chaque noyau Linux, contrairement * HTB. Les deux ont *t* test*s et marchent correctement. -------------------------------------------------------------------------- Le script (CBQ) Marche avec tous les noyaux. A l'int*rieur du gestionnaire de mise en file d'attente CBQ, nous pla*ons deux SFQ pour *tre s*r que de multiples flux de masse ne vont pas mutuellement se p*naliser. Le trafic descendant est r*glement* en utilisant un filtre tc contenant un Token Bucket Filter. Vous pourriez am*liorer ce script en ajoutant 'bounded' aux lignes qui d*marrent avec 'tc class add .. classid 1:20'. Si vous avez diminu* votre MTU, diminuez aussi les nombres allot & avpkt ! #!/bin/bash # La configuration ultime pour votre connexion Internet domestique # # Configurez les valeurs suivantes avec des valeurs l*g*rement inf*rieures que # vos vitesses de flux montant et descendant. Exprim* en kilobits. DOWNLINK=800 UPLINK=220 DEV=ppp0 # Nettoie les gestionnaires de sortie et d'entr*s, cache les erreurs tc qdisc del dev $DEV root 2> /dev/null > /dev/null tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null ###### Flux montant (uplink) # installe CBQ * la racine tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 10mbit # Le trafic est mis en forme * une vitesse de $UPLINK. Ceci *vite # d'*normes files d'attente dans votre modem DSL qui p*nalisent le temps de # latence. # Classe principale tc class add dev $DEV parent 1: classid 1:1 cbq rate ${UPLINK}kbit \ allot 1500 prio 5 bounded isolated # classe de priorit* sup*rieure 1:10: tc class add dev $DEV parent 1:1 classid 1:10 cbq rate ${UPLINK}kbit \ allot 1600 prio 1 avpkt 1000 # la classe par d*faut et pour le trafic de masse 1:20. Re*oit l*g*rement # moins que le trafic et a une priorit* plus faible : # bulk and default class 1:20 - gets slightly less traffic, # and a lower priority: tc class add dev $DEV parent 1:1 classid 1:20 cbq rate $[9*$UPLINK/10]kbit \ allot 1600 prio 2 avpkt 1000 # Les deux sont g*r*es par SFQ : tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10 tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10 # D*marrage des filtres # le bit D*lai Minimum du champ TOS (ssh, PAS scp) est dirig* vers # 1:10 : tc filter add dev $DEV parent 1:0 protocol ip prio 10 u32 \ match ip tos 0x10 0xff flowid 1:10 # ICMP (ip protocol 1) est dirig* vers la classe interactive 1:10 de telle # sorte que nous pouvons r*aliser des mesures et impressionner nos # amis : tc filter add dev $DEV parent 1:0 protocol ip prio 11 u32 \ match ip protocol 1 0xff flowid 1:10 # Pour acc*l*rer les t*l*chargements vers l'aval lors de la pr*sence d'un # flux montant, les paquets ACK sont plac*s dans la classe # interactive : tc filter add dev $DEV parent 1: protocol ip prio 12 u32 \ match ip protocol 6 0xff \ match u8 0x05 0x0f at 0 \ match u16 0x0000 0xffc0 at 2 \ match u8 0x10 0xff at 33 \ flowid 1:10 # Le reste est consid*r* 'non-interactif' cad 'de masse' et fini dans 1:20 tc filter add dev $DEV parent 1: protocol ip prio 13 u32 \ match ip dst 0.0.0.0/0 flowid 1:20 ########## Flux descendant (downlink) ############# # Ralentir le flux descendant * une valeur l*g*rement plus faible que votre # vitesse r*elle de mani*re * *viter la mise en file d'attente chez notre # FAI. Faites des tests pour voir la vitesse maximum * laquelle vous pouvez # le configurer. Les FAI ont tendance * avoir *d'*normes* files d'attente # pour s'assurer de la rapidit* des gros t*l*chargements. # # attache la r*glementation d'entr*e (ingress policer) : tc qdisc add dev $DEV handle ffff: ingress # Filtre *tout* (0.0.0.0/0), rejette tout ce qui arrive trop # rapidement : tc filter add dev $DEV parent ffff: protocol ip prio 50 u32 match ip src \ 0.0.0.0/0 police rate ${DOWNLINK}kbit burst 10k drop flowid :1 Si vous voulez que ce script soit ex*cut* par ppp * la connexion, copiez-le dans /etc/ppp/ip-up.d. Si les deux derni*res lignes conduisent * une erreur, mettez * jour l'outil tc avec la derni*re version ! -------------------------------------------------------------------------- Le script (HTB) Le script suivant nous permet d'atteindre tous nos buts en utilisant la merveilleuse file d'attente HTB. Voir le chapitre correspondant. Cela vaut la peine de mettre * jour votre noyau ! #!/bin/bash # La configuration ultime pour votre connexion Internet domestique # # Configurez les valeurs suivantes avec des valeurs l*g*rement inf*rieures que # vos vitesses de flux montant et descendant. Exprim* en kilobits. DOWNLINK=800 UPLINK=220 DEV=ppp0 #Nettoie les gestionnaires de sortie et d'entr*s, cache les erreurs tc qdisc del dev $DEV root 2> /dev/null > /dev/null tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null ###### Flux montant (uplink) # installe HTB * la racine, le trafic ira par d*faut vers 1:20 : tc qdisc add dev $DEV root handle 1: htb default 20 # Le trafic est mis en forme * une vitesse de $UPLINK. Ceci *vite # d'*normes files d'attente dans votre modem DSL qui p*nalisent le temps de # latence. tc class add dev $DEV parent 1: classid 1:1 htb rate ${UPLINK}kbit burst 6k # la classe de haute priorit* 1:10 : tc class add dev $DEV parent 1:1 classid 1:10 htb rate ${UPLINK}kbit \ burst 6k prio 1 # bulk & default class 1:20 - gets slightly less traffic, # and a lower priority: tc class add dev $DEV parent 1:1 classid 1:20 htb rate $[9*$UPLINK/10]kbit \ burst 6k prio 2 # Les deux sont g*r*es par SFQ : tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10 tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10 # le bit D*lai Minimum du champ TOS (ssh, PAS scp) est dirig* vers # 1:10 : tc filter add dev $DEV parent 1:0 protocol ip prio 10 u32 \ match ip tos 0x10 0xff flowid 1:10 # ICMP (ip protocol 1) est dirig* vers la classe interactive 1:10 de telle # sorte que nous pouvons r*aliser des mesures et impressionner nos # amis : tc filter add dev $DEV parent 1:0 protocol ip prio 10 u32 \ match ip protocol 1 0xff flowid 1:10 # Pour acc*l*rer les t*l*chargements vers l'aval lors de la pr*sence d'un # flux montant, les paquets ACK sont plac*s dans la classe # interactive : tc filter add dev $DEV parent 1: protocol ip prio 10 u32 \ match ip protocol 6 0xff \ match u8 0x05 0x0f at 0 \ match u16 0x0000 0xffc0 at 2 \ match u8 0x10 0xff at 33 \ flowid 1:10 # Le reste est consid*r* 'non-interactif' cad 'de masse' et fini dans 1:20 ########## Flux descendant (downlink) ############# # Ralentir le flux descendant * une valeur l*g*rement plus faible que votre # vitesse r*lle de mani*re * *viter la mise en file d'attente chez notre # FAI. Faites des tests pour voir la vitesse maximum * laquelle vous pouvez # le configurer. Les FAI ont tendance * avoir *d'*normes* files d'attente # pour s'assurer de la rapidit* des gros t*l*chargements. # # attache la r*glementation d'entr*e (ingress policer) : tc qdisc add dev $DEV handle ffff: ingress # Filtre *tout* (0.0.0.0/0), rejette tout ce qui arrive trop # rapidement : tc filter add dev $DEV parent ffff: protocol ip prio 50 u32 match ip src \ 0.0.0.0/0 police rate ${DOWNLINK}kbit burst 10k drop flowid :1 Si vous voulez que ce script soit ex*cut* par ppp * la connexion, copiez-le dans /etc/ppp/ip-up.d. Si les deux derni*res lignes conduisent * une erreur, mettez * jour l'outil tc avec la derni*re version ! -------------------------------------------------------------------------- Limitation du d*bit pour un h*te ou un masque de sous-r*seau Bien que ceci soit d*crit en d*tail ailleurs et dans nos pages de manuel, cette question est souvent pos*e. Heureusement, il y a une r*ponse simple qui ne n*cessite pas la compr*hension compl*te du contr*le de trafic. Ce script de trois lignes met en place la limitation du d*bit : tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 10mbit tc class add dev $DEV parent 1: classid 1:1 cbq rate 512kbit \ allot 1500 prio 5 bounded isolated tc filter add dev $DEV parent 1: protocol ip prio 16 u32 \ match ip dst 195.96.96.97 flowid 1:1 La premi*re ligne installe un gestionnaire de mise en file d'attente bas* sur des classes sur votre interface, et indique au noyau que, pour ses calculs, il peut la consid*rer comme une interface * 10 Mbits/s. Cependant, il n'y aura pas de grands dommages si vous indiquez une valeur erron*e. Donner la vraie valeur permettra d'avoir des choses plus pr*cises. La seconde ligne cr*e une classe de 512kbit/s avec des valeurs par d*faut raisonnables. Pour les d*tails, voir les pages de manuel cbq et [220]Chapitre 9>. La derni*re ligne indique quel trafic devra passer par la classe r*alisant la mise en forme. Le trafic qui n'est s*lectionn* par cette r*gle n'est PAS mis en forme. Pour avoir des s*lections plus compliqu*es (sous-r*seaux, ports sources ou de destinations), voir [221]la section intitul*e Toutes les commandes de filtres dont vous aurez normalement besoin dans Chapitre 9>. Si vous avez chang* quelque chose et que vous vouliez recharger le script, ex*cutez la commande tc qdisc del dev $DEV root pour supprimer votre configuration actuelle. Le script peut *tre am*lior* en ajoutant une derni*re ligne optionnelle tc qdisc add dev $DEV parent 1:1 sfq perturb 10. Voir [222]la section intitul*e Mise en file d'attente stochastiquement *quitable (Stochastic Fairness Queueing) dans Chapitre 9> pour savoir ce que cela fait. -------------------------------------------------------------------------- Exemple d'une solution de translation d'adresse avec de la QoS Je m'appelle Pedro Larroy <[223]piotr%member.fsf.org> . Je d*cris ici une configuration dans le cas o* de nombreux utilisateurs seraient connect*s * Internet * travers un routeur Linux qui poss*de une adresse publique et qui r*alise de la translation d'adresse (NAT). J'utilise cette configuration QoS pour fournir l'acc*s * 198 utilisateurs dans une cit* universitaire dans laquelle je vis et o* j'administre le r*seau. Les utilisateurs sont de gros consommateurs de programmes "peer to peer" et un contr*le de trafic correct est n*cessaire. J'esp*re que ceci servira d'exemples pratiques * tous les lecteurs int*ress*s par le lartc. Dans un premier temps, la configuration sera r*alis*e pas * pas et, * la fin, j'expliquerai comment rendre ce processus automatique au d*marrage. Le r*seau utilis* pour cet exemple est un r*seau local connect* * Internet * travers un routeur Linux ayant une adresse publique. L'ajout d'un ensemble de r*gles iptables permettrait facilement l'extension * plusieurs adresses IP publiques. Les *l*ments suivants sont n*cessaires : Linux 2.4.18 ou une version du noyau sup*rieure install*e Si vous utilisez le noyau 2.4.18, vous devrez appliquer la mise * jour HTB. iproute Soyez *galement s*r que le binaire "tc" est compatible avec HTB. Un binaire pr* compil* est distribu* avec HTB. iptables -------------------------------------------------------------------------- Commen*ons l'optimisation de cette rare bande passante Tout d'abord, nous allons configurer des gestionnaires de mise en file d'attente dans lesquels nous allons classifier le trafic. Nous cr*ons un gestionnaire htb compos* de 6 classes avec des priorit*s croissantes. Nous avons alors des classes qui obtiendront le d*bit allou* et qui pourront, de plus, utiliser la bande passante dont les autres classes n'ont pas besoin. Rappelons que les classes de plus hautes priorit*s (correspondant aux nombres prio les plus faibles) obtiendront en premier l'exc*s de bande passante. Notre liaison ADSL * un flux descendant de 2Mbits/s et un flux montant de 300 kbits/s. J'utilise un d*bit de seuil (ceil rate) de 240 kbits/s car, au-del* de cette limite, les probl*mes de latence commence * prendre de l'ampleur. Ceci est d* au remplissage d'un tampon plac* quelque part entre nous et les h*tes distants. Ajuster la variable CEIL * 75% de votre bande passante montante maximum et ajuster le nom de l'interface (eth0 dans la suite) * celle qui a l'adresse publique Internet. Ex*cutez ce qui suit dans un shell root : CEIL=240 tc qdisc add dev eth0 root handle 1: htb default 15 tc class add dev eth0 parent 1: classid 1:1 htb rate ${CEIL}kbit ceil ${CEIL}kbit tc class add dev eth0 parent 1:1 classid 1:10 htb rate 80kbit ceil 80kbit prio 0 tc class add dev eth0 parent 1:1 classid 1:11 htb rate 80kbit ceil ${CEIL}kbit prio 1 tc class add dev eth0 parent 1:1 classid 1:12 htb rate 20kbit ceil ${CEIL}kbit prio 2 tc class add dev eth0 parent 1:1 classid 1:13 htb rate 20kbit ceil ${CEIL}kbit prio 2 tc class add dev eth0 parent 1:1 classid 1:14 htb rate 10kbit ceil ${CEIL}kbit prio 3 tc class add dev eth0 parent 1:1 classid 1:15 htb rate 30kbit ceil ${CEIL}kbit prio 3 tc qdisc add dev eth0 parent 1:12 handle 120: sfq perturb 10 tc qdisc add dev eth0 parent 1:13 handle 130: sfq perturb 10 tc qdisc add dev eth0 parent 1:14 handle 140: sfq perturb 10 tc qdisc add dev eth0 parent 1:15 handle 150: sfq perturb 10 Nous avons juste cr** une arborescence htb avec un seul niveau de profondeur. Quelque chose comme ceci : +-----------+ | racine 1: | +-----------+ | +---------------------------------------+ | classe 1:1 | +---------------------------------------+ | | | | | | +----+ +----+ +----+ +----+ +----+ +----+ |1:10| |1:11| |1:12| |1:13| |1:14| |1:15| +----+ +----+ +----+ +----+ +----+ +----+ classid 1:10 htb rate 80kbit ceil 80kbit prio 0 Ceci est la classe de priorit* la plus *lev*e. Les paquets de cette classe auront le plus faible d*lai et obtiendront en premier l'exc*s de bande passante. C'est donc une bonne id*e de limiter le d*bit de seuil de cette classe. Nous enverrons dans cette classe les paquets qui ont un avantage * avoir un faible d*lai, tel que le trafic interactif : ssh, telnet, dns, quake3, irc, et les paquets avec le bit SYN activ*. classid 1:11 htb rate 80kbit ceil ${CEIL}kbit prio 1 Nous avons ici la premi*re classe dans laquelle nous commen*ons * mettre du trafic de masse. Dans mon exemple, j'ai le trafic provenant de mon serveur web local et les requ*tes pour les pages web : respectivement le port source 80 et le port destination 80. classid 1:12 htb rate 20kbit ceil ${CEIL}kbit prio 2 Dans cette classe, je mettrai le trafic configur* avec le champ TOS "D*bit Maximum" activ*, ainsi que le reste du trafic provenant des processus locaux de mon routeur vers Internet. Les classes suivantes ne recevront donc que du trafic rout* par cette machine. classid 1:13 htb rate 20kbit ceil ${CEIL}kbit prio 2 Cette classe est pour le trafic des autres machines "NAT*es" (NdT : b*n*ficiant du service de translation d'adresse) qui ont besoin d'une priorit* plus grande dans leur trafic de masse. classid 1:14 htb rate 10kbit ceil ${CEIL}kbit prio 3 Le trafic mail (SMTP, pop3,...) et les paquets configur*s avec le champ TOS "Co*t Minimum" seront envoy*s dans cette classe. classid 1:15 htb rate 30kbit ceil ${CEIL}kbit prio 3 Finalement, nous avons ici le trafic de masse des machines "NAT*es" se trouvant derri*re le routeur. Les paquets li*s * kazaa, edonkey et autres iront ici pour ne pas interf*rer avec les autres services. -------------------------------------------------------------------------- Classification des paquets Nous avons configur* le gestionnaire de mise en file d'attente, mais aucune classification de paquets n'a encore *t* faite. Pour l'instant, tous les paquets sortants passent par la classe 1:15 (car, nous avons utilis* : tc qdisc add dev eth0 root handle 1: htb default 15). Nous devons donc maintenant indiquer o* doivent aller les paquets. Ceci est la partie la plus importante. Nous allons maintenant configurer les filtres de tel sorte que nous puissions classifier les paquets avec iptables. Je pr*f*re vraiment le faire avec iptables car celui-ci est tr*s souple et que nous avons un compteur de paquets pour chaque r*gle. De plus, avec la cible RETURN, les paquets n'ont pas besoin de traverser toutes les r*gles. Nous ex*cutons les commandes suivantes : tc filter add dev eth0 parent 1:0 protocol ip prio 1 handle 1 fw classid 1:10 tc filter add dev eth0 parent 1:0 protocol ip prio 2 handle 2 fw classid 1:11 tc filter add dev eth0 parent 1:0 protocol ip prio 3 handle 3 fw classid 1:12 tc filter add dev eth0 parent 1:0 protocol ip prio 4 handle 4 fw classid 1:13 tc filter add dev eth0 parent 1:0 protocol ip prio 5 handle 5 fw classid 1:14 tc filter add dev eth0 parent 1:0 protocol ip prio 6 handle 6 fw classid 1:15 Nous indiquons simplement au noyau que les paquets qui ont une valeur FWMARK sp*cifique (handle x fw) vont dans la classe sp*cifi*e (classid x:x). Voyons maintenant comment marquer les paquets avec iptables. Tout d'abord, nous devons comprendre comment les paquets traversent les filtres avec iptables : +------------+ +---------+ +-------------+ Paquets-| PREROUTING |--- D*cision----| FORWARD |-------+-------| POSTROUTING |- Paquets entrant +------------+ de routage +-*-------+ | +-------------+ sortants | | +-------+ +--------+ | INPUT |-- Processus locaux-| OUTPUT | +-------+ +--------+ Je suppose que toutes vos tables ont leur politique par d*faut configur*e * ACCEPT (-P ACCEPT), ce qui devrait *tre le cas si vous n'avez pas encore touch* * iptables. Notre r*seau priv* est une classe B avec l'adresse 172.17.0.0/16 et notre adresse publique est 212.170.21.172. Nous indiquons au noyau de faire de la translation d'adresse NAT; les clients du r*seau priv* peuvent alors commencer * dialoguer avec l'ext*rieur. echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A POSTROUTING -s 172.17.0.0/255.255.0.0 -o eth0 -j SNAT --to-source 212.170.21.172 V*rifions maintenant que les paquets transitent bien * travers 1:15 : tc -s class show dev eth0 Vous pouvez commencer * marquer les paquets en ajoutant les r*gles dans la cha*ne PREROUTING de la table mangle. iptables -t mangle -A PREROUTING -p icmp -j MARK --set-mark 0x1 iptables -t mangle -A PREROUTING -p icmp -j RETURN Vous devriez maintenant *tre capable de voir l'*volution du compteur de paquets quand vous pinguez des sites sur Internet depuis les machines du r*seau priv*. V*rifiez que le compteur de paquets augmente dans 1:10 : tc -s class show dev eth0 Nous avons mis -j RETURN de mani*re * ce que les paquets ne traversent pas toutes les r*gles. Les paquets icmp ne scruteront pas les autres r*gles d*finies sous RETURN. Gardez ceci * l'esprit. Nous commen*ons maintenant * ajouter d'autres r*gles pour g*rer les champs TOS : iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j MARK --set-mark 0x1 iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j RETURN iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j MARK --set-mark 0x5 iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j RETURN iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j MARK --set-mark 0x6 iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j RETURN Donnons la priorit* aux paquets SSH : iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 22 -j MARK --set-mark 0x1 iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 22 -j RETURN Une bonne id*e est de donner la priorit* aux paquets initiant une connexion tcp, * savoir ceux qui ont le bit SYN activ* : iptables -t mangle -I PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 0x1 iptables -t mangle -I PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN Et ainsi de suite. Apr*s la mise en place des r*gles dans la cha*ne PREROUTING de la table "mangle", nous terminons par : iptables -t mangle -A PREROUTING -j MARK --set-mark 0x6 Ainsi, le trafic non marqu* est dirig* vers 1:15. En fait, cette derni*re *tape n'est pas n*cessaire puisque la classe par d*faut est 1:15. Un marquage est quand m*me r*alis* de mani*re * avoir une coh*rence pour l'ensemble de la configuration. De plus, il est utile d'avoir une comptabilit* pour cette r*gle. C'est une bonne id*e de faire de m*me avec la cha*ne OUTPUT. R*p*tez ces commandes avec -A OUTPUT * la place de PREROUTING (s/PREROUTING/OUTPUT/). Le trafic g*n*r* localement (sur le routeur Linux) sera alors *galement classifi*. Je termine la cha*ne OUTPUT par -j MARK --set-mark 0x3 de tel sorte que le trafic local ait une priorit* plus grande. -------------------------------------------------------------------------- Am*liorer notre configuration Toute notre configuration est maintenant op*rationnelle. Prenez du temps pour regarder les graphes et observer o* votre bande passante est la plus utilis*e et cela correspond * vos souhaits. J'ai fait ceci pendant de nombreuses heures, ce qui m'a permis d'avoir une connexion Internet fonctionnant tr*s bien. Autrement, vous serez confront* en permanence * des "timeout" et des allocations de bande passante presque nulles pour les nouvelles connexions tcp. Si vous rep*rez des classes qui sont pleines la plupart du temps, ce peut *tre une bonne id*e de leur attacher un autre gestionnaire de mise en file d'attente de mani*re * ce que le partage de la bande passante soit plus *quitable : tc qdisc add dev eth0 parent 1:13 handle 130: sfq perturb 10 tc qdisc add dev eth0 parent 1:14 handle 140: sfq perturb 10 tc qdisc add dev eth0 parent 1:15 handle 150: sfq perturb 10 -------------------------------------------------------------------------- Rendre tout ceci actif au d*marrage Il est certain que ceci peut *tre fait de diff*rentes fa*ons. Dans mon cas, j'ai un shell script /etc/init.d/packetfilter qui accepte les arguments [start | stop | stop-tables | start-tables | reload-tables]. Celui-ci configure les gestionnaires de mise en file d'attente et charge les modules du noyau n*cessaires et se comporte donc comme une d*mon. Le m*me script charge les r*gles iptables * partir de /etc/network/iptables-rules. Je vais l'embellir un peu et le rendrait disponible sur ma page web [224]ici -------------------------------------------------------------------------- Chapitre 16. Construire des ponts et des pseudo ponts avec du Proxy ARP Les ponts sont des p*riph*riques qui peuvent *tre install*s dans un r*seau sans aucune reconfiguration. Un commutateur r*seau est basiquement un pont multi-ports. Un pont est souvent un commutateur avec 2 ports. Cependant, Linux supporte tr*s bien plusieurs interfaces dans un pont, le conduisant * fonctionner comme un vrai commutateur. Les ponts sont souvent d*ploy*s quand on est confront* * un r*seau d*faillant qui a besoin d'*tre r*par* sans aucune modification. Dans la mesure o* un pont est un *quipement de niveau 2, la couche sous la couche IP, les routeurs et serveurs ne sont pas conscients de son existence. Ceci signifie que vous pouvez bloquer ou modifier certains paquets de mani*re transparente ou mettre en forme le trafic. Un autre *l*ment positif est qu'un pont peut souvent *tre remplac* par un cble crois* ou un hub quand il tombe en panne. L'aspect n*gatif est que la mise en place d'un pont peut engendrer beaucoup de confusion, * moins qu'il ne soit tr*s bien configur*. Le pont n'appara*t pas dans les traceroute, mais pourtant des paquets disparaissent sans raison ou sont chang*s en allant d'un point A * un point B ('ce r*seau est HANTE !). Vous devriez *galement vous demander si une organisation qui "ne veut rien changer" fait le bon choix. Le pont Linux 2.4/2.5 est document* sur [225]cette page. -------------------------------------------------------------------------- Etat des ponts et iptables Au moment de Linux 2.4.20, le pont et iptables ne se "voient" pas l'un l'autre sans une aide. Si vous "pontez" les paquets de eth0 * eth1, ils ne "passent" pas par iptables. Ceci signifie que vous ne pouvez pas faire de filtrage, de translation d'adresse (NAT), de d*sossage ou quoique ce soit d'autres. Ceci a *t* corrig* dans les versions 2.5.45 et sup*rieures. Vous devriez *galement regarder 'ebtables', qui est encore un autre projet. Il vous permettra de faire des choses vraiment terribles comme MACNAT et 'brouting'. C'est vraiment effroyable. -------------------------------------------------------------------------- Pont et mise en forme Ca marche comme dans les r*clames. Soyez s*r du c*t* attribu* * chaque interface. Autrement, il se peut que vous mettiez en forme le trafic sortant au niveau de votre interface interne, ce qui ne marchera pas. Utilisez tcpdump si n*cessaire. -------------------------------------------------------------------------- Pseudo-pont avec du Proxy-ARP Si vous voulez juste impl*menter un pseudo pont, allez jusqu'* la section "Impl*mentez-le". Cependant, il est sage de lire un peu la fa*on dont il fonctionne en pratique. Un pseudo pont travaille de mani*re un peu diff*rente. Par d*faut, un pont transmet les paquets sans les alt*rer d'une interface * une autre. Il ne regarde que l'adresse mat*rielle des paquets pour d*terminer o* ils doivent aller. Ceci signifie que vous pouvez "pontez" un trafic que Linux ne comprend pas, aussi longtemps qu'il y a une adresse mat*rielle. Un "pseudo pont" travaille diff*remment et ressemble plus * un routeur cach* qu'* un pont. Mais, comme un pont, il a un impact faible sur l'architecture du r*seau. Le fait qu'il ne soit pas un pont pr*sente l'avantage que les paquets traversent r*ellement le noyau, et peuvent *tre filtr*s, modifi*s, redirig*s ou rerout*s. Un pont r*el peut *galement r*aliser ces tours de force, mais il a besoin d'un code sp*cial, comme le Ethernet Frame Diverter ou la mise * jour mentionn*e au-dessus. Un autre avantage d'un pseudo pont est qu'il ne transmet pas les paquets qu'il ne comprend pas, nettoyant ainsi votre r*seau de beaucoup de cochonneries. Dans le cas o* vous auriez besoin de ces cochonneries (comme les paquets SAP ou Netbeui), utilisez un vrai pont. -------------------------------------------------------------------------- ARP & Proxy-ARP Quand un h*te veut dialoguer avec un autre h*te sur le m*me segment physique, il envoie un paquet du Protocole de R*solution d'Adresse (ARP) qui, en simplifiant quelque peu, est lu comme ceci : "Qui a 10.0.0.1, le dire * 10.0.0.7". En r*ponse * ceci, 10.0.0.1 renvoie un petit paquet "ici". 10.0.0.7 envoie alors des paquets * l'adresse mat*rielle mentionn*e dans le paquet "ici". Il met dans un cache cette adresse mat*rielle pour un temps relativement long et, apr*s l'expiration du cache, repose sa question. Quand on construit un pseudo pont, on configure le pont pour qu'il r*ponde * ces paquets ARP, les h*tes du r*seau envoyant alors leurs paquets au pont. Le pont traite alors ces paquets et les envoie * l'interface adapt*e. Donc, en r*sum*, quand un h*te d'un c*t* du pont demande l'adresse mat*rielle d'un h*te se situant de l'autre c*t*, le pont r*pond avec un paquet qui dit "transmets le moi". De cette fa*on, tout le trafic de donn*es est transmis * la bonne place et il traverse toujours le pont. -------------------------------------------------------------------------- Impl*mentez-le Les versions anciennes du noyau linux permettait de faire du proxy ARP uniquement * une granularit* sous r*seaux. Ainsi, pour configurer un pseudo pont, il fallait sp*cifier les bonnes routes vers les deux c*t*s du pont, et *galement cr*er les r*gles proxy-ARP correspondantes. C'*tait p*nible, d*j* par la quantit* de texte qu'il fallait taper, puis parce qu'il *tait facile de se tromper et cr*er des configurations erron*es, o* le pont r*pondait * des requ*tes pour des r*seaux qu'il ne savait pas router. Avec Linux 2.4 (et peut-*tre bien le 2.2), cette possibilit* a *t* retir*e et a *t* remplac*e par une option dans le r*pertoire /proc, appel*e "proxy-arp". La proc*dure pour construire un pseudo pont est maintenant : 1. Assigner une adresse * chaque interface, la "gauche" et la "droite" 2. Cr*er des routes pour que votre machine connaisse quels h*tes r*sident * gauche et quels h*tes r*sident * droite 3. Activer le proxy-ARP sur chaque interface echo 1 > /proc/sys/net/ipv4/conf/ethL/proxy_arp echo 1 > /proc/sys/net/ipv4/conf/ethR/proxy_arp o* L et R d*signent les num*ros de l'interface du c*t* gauche (Left) et de celle du c*t* droit (Right) N'oubliez pas *galement d'activer l'option ip_forwarding ! Quand on convertit un vrai pont, il se peut que vous trouviez cette option d*sactiv*e dans la mesure o* il n'y en a pas besoin pour un pont. Une autre chose que vous devriez consid*rer lors de la conversion est que vous aurez besoin d'effacer le cache arp des ordinateurs du r*seau. Le cache arp peut contenir d'anciennes adresses mat*rielles du pont qui ne sont plus correctes. Sur un Cisco, ceci est r*alis* en utilisant la commande 'clear arp-cache' et, sous linux, en utilisant 'arp -d ip.adresse'. Vous pouvez aussi attendre l'expiration manuelle du cache, ce qui peut *tre plut*t long. Il se peut que vous d*couvriez *galement que votre r*seau *tait mal configur* si vous avez/aviez l'habitude de sp*cifier les routes sans les masques de sous-r*seau. Dans le pass*, certaines versions de route pouvaient correctement deviner le masque ou, au contraire, se tromper sans pour autant vous le notifier. Quand vous faites du routage chirurgical comme d*crit plus haut, il est *vital* que vous v*rifiez vos masques de sous-r*seau. -------------------------------------------------------------------------- Chapitre 17. Routage Dynamique - OSPF et BGP Si votre r*seau commence * devenir vraiment gros ou si vous commencez * consid*rer Internet comme votre propre r*seau, vous avez besoin d'outils qui routent dynamiquement vos donn*es. Les sites sont souvent reli*s entre eux par de multiples liens, et de nouveaux liens surgissent en permanence. L'Internet utilise la plupart du temps les standards OSPF (RFC 2328) et BGP4 (RFC 1771). Linux supporte les deux, par le biais de gated et zebra. Ce sujet est pour le moment hors du propos de ce document, mais laissez-nous vous diriger vers des travaux de r*f*rence : Vue d'ensemble : Cisco Systems [226]Cisco Systems Designing large-scale IP Internetworks Pour OSPF : Moy, John T. "OSPF. The anatomy of an Internet routing protocol" Addison Wesley. Reading, MA. 1998. Halabi a aussi *crit un tr*s bon guide sur la conception du routage OSPF, mais il semble avoir *t* effac* du site Web de Cisco. Pour BGP : Halabi, Bassam "Internet routing architectures" Cisco Press (New Riders Publishing). Indianapolis, IN. 1997. Il existe aussi Cisco Systems [227]Using the Border Gateway Protocol for Interdomain Routing Bien que les exemples soient sp*cifiques * Cisco, ils sont remarquablement semblables au langage de configuration de Zebra :-) -------------------------------------------------------------------------- Configurer OSPF avec Zebra [228]Contactez-moi si les informations qui suivent ne sont pas exactes ou si vous avez des suggestions. [229]Zebra est un formidable logiciel de routage dynamique *crit par Kunihiro Ishiguro, Toshiaki Takada et Yasuhiro Ohara. Configurer OSPF avec zebra est simple et rapide mais, en pratique, il y a de nombreux param*tres dans le cas o* vous auriez des besoins sp*cifiques. OSPF est l'abr*viation de Open Shortest Path First et quelques une de ses fonctionnalit*s sont : hi*rarchique Les r*seaux sont regroup*s par zones (areas), qui sont interconnect*es par une zone *pine dorsale qui sera appel*e zone 0. Tout le trafic passe par la zone 0 et tous les routeurs de cette zone ont les informations de routage de toutes les autres zones. convergence rapide Les routes sont propag*es tr*s rapidement, compar* * RIP par exemple. *conomie de bande passante Utilise la multi-distribution * la place de la diffusion, ce qui *vite de submerger les autres h*tes avec des informations de routage sans int*r*t pour eux. La multi-distribution r*duit ainsi le d*bit sur le r*seau. De m*me, les routeurs internes (ceux dont toutes les interfaces sont situ*es dans la m*me zone) n'obtiennent pas d'informations sur les autres zones. Les routeurs avec des interfaces dans plus d'une zone sont appel*s Area Border Routers. Ils poss*dent les informations de topologie sur les zones auxquelles ils sont connect*s. Utilisation intensive de CPU OSPF est bas* sur l'algorithme de Dijkstra [230]Shortest Path First, qui est co*teux en temps de calcul compar* aux autres algorithmes de routage. Ce n'est pas forc*ment mauvais, dans la mesure o* le plus court chemin est calcul* uniquement pour chaque zone. Donc, pour les r*seaux de petite * moyenne taille, ce ne sera pas un probl*me ; vous ne vous en rendrez pas compte. Information d'*tat de lien OSPF prend en compte les caract*ristiques sp*cifiques des r*seaux et interfaces, telles que la bande passante, les d*fauts de liens et le co*t mon*taire. Protocole ouvert et logiciel sous license GPL OSPF est un protocole ouvert et Zebra est un logiciel sous license GPL, ce qui repr*sente un avantage *vident par rapport aux protocoles et logiciels propri*taires. -------------------------------------------------------------------------- Pr*requis Noyau Linux : Compil* avec CONFIG_NETLINK_DEV and CONFIG_IP_MULTICAST (Je ne sais pas si d'autres *l*ments sont *galement n*cessaires). Iproute Zebra R*cup*rez-le avec votre gestionnaire de paquet favori ou * partir de [231]http://www.zebra.org. -------------------------------------------------------------------------- Configurer Zebra Prenons le r*seau suivant comme exemple : ---------------------------------------------------- | 192.168.0.0/24 | | | | Zone 0 100BaseTX Commut* | | Epine dorsale Ethernet | ---------------------------------------------------- | | | | | | | | |eth1 |eth1 |eth0 | |100BaseTX |100BaseTX |100BaseTX |100BaseTX |.1 |.2 |.253 | --------- ------------ ----------- ---------------- |R Omega| |R Atlantis| |R Legolas| |R Frodo | --------- ------------ ----------- ---------------- |eth0 |eth0 | | | | | | | | |2MbDSL/ATM |100BaseTX |10BaseT |10BaseT |10BaseT ------------ ------------------------------------ ------------------------------- | Internet | | 172.17.0.0/16 Zone 1 | | 192.168.1.0/24 wlan Zone 2 | ------------ | R*seau etudiant (dortoir) | | Sans fil de Barcelone | ------------------------------------ ------------------------------- Ne soyez pas effray* par ce diagramme, Zebra r*alise la plus grande partie du travail automatiquement ; ce qui ne demandera aucun travail de saisie des routes avec Zebra. Il serait p*nible de maintenir toutes ces routes * la main au quotidien. La chose la plus importante * ma*triser clairement, c'est la topologie du r*seau. Faites particuli*rement attention * la zone 0, puisque c'est la plus importante. Dans un premier temps, configurez Zebra en *ditant zebra.conf et en l'adaptant * vos besoins : hostname omega password xxx enable password xxx ! ! Interface's description. ! !interface lo ! description test of desc. ! interface eth1 multicast ! ! Static default route ! ip route 0.0.0.0/0 212.170.21.129 ! log file /var/log/zebra/zebra.log Debian n*cessite *galement l'*dition de /etc/zebra/daemons pour qu'ils soient lanc*s au d*marrage : zebra=yes ospfd=yes Nous devons maintenant editer ospfd.conf si vous utilisez encore IPV4 ou ospf6d.conf si vous travaillez avec IPV6. Mon fichier ospfd.conf ressemble * ceci : hostname omega password xxx enable password xxx ! router ospf network 192.168.0.0/24 area 0 network 172.17.0.0/16 area 1 ! ! log stdout log file /var/log/zebra/ospfd.log Ceci indique * ospf la topologie de notre r*seau. -------------------------------------------------------------------------- Ex*cuter Zebra Nous devons maintenant d*marrer Zebra soit * la main en tapant "zebra -d", soit avec un script comme "/etc/init.d/zebra start". En regardant attentivement les logs de ospdfd, on peut voir les *l*ments suivants : 2002/12/13 22:46:24 OSPF: interface 192.168.0.1 join AllSPFRouters Multicast group. 2002/12/13 22:46:34 OSPF: SMUX_CLOSE with reason: 5 2002/12/13 22:46:44 OSPF: SMUX_CLOSE with reason: 5 2002/12/13 22:46:54 OSPF: SMUX_CLOSE with reason: 5 2002/12/13 22:47:04 OSPF: SMUX_CLOSE with reason: 5 2002/12/13 22:47:04 OSPF: DR-Election[1st]: Backup 192.168.0.1 2002/12/13 22:47:04 OSPF: DR-Election[1st]: DR 192.168.0.1 2002/12/13 22:47:04 OSPF: DR-Election[2nd]: Backup 0.0.0.0 2002/12/13 22:47:04 OSPF: DR-Election[2nd]: DR 192.168.0.1 2002/12/13 22:47:04 OSPF: interface 192.168.0.1 join AllDRouters Multicast group. 2002/12/13 22:47:06 OSPF: DR-Election[1st]: Backup 192.168.0.2 2002/12/13 22:47:06 OSPF: DR-Election[1st]: DR 192.168.0.1 2002/12/13 22:47:06 OSPF: Packet[DD]: Negotiation done (Slave). 2002/12/13 22:47:06 OSPF: nsm_change_status(): scheduling new router-LSA origination 2002/12/13 22:47:11 OSPF: ospf_intra_add_router: Start Ignorez le message SMUX_CLOSE pour l'instant dans la mesure o* il concerne SNMP. Nous pouvons voir que 192.168.0.1 est routeur d*sign* (Designated Router) et que 192.168.0.2 est le le routeur d*sign* de sauvegarde (Backup Designated Router). Nous pouvons *galement interagir avec zebra et ospfd en ex*cutant : $ telnet localhost zebra $ telnet localhost ospfd Voyons comment les routes se sont propag*es en se connectant * zebra : root@atlantis:~# telnet localhost zebra Trying 127.0.0.1... Connected to atlantis. Escape character is '^]'. Hello, this is zebra (version 0.92a). Copyright 1996-2001 Kunihiro Ishiguro. User Access Verification Password: atlantis> show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, B - BGP, > - selected route, * - FIB route K>* 0.0.0.0/0 via 192.168.0.1, eth1 C>* 127.0.0.0/8 is directly connected, lo O 172.17.0.0/16 [110/10] is directly connected, eth0, 06:21:53 C>* 172.17.0.0/16 is directly connected, eth0 O 192.168.0.0/24 [110/10] is directly connected, eth1, 06:21:53 C>* 192.168.0.0/24 is directly connected, eth1 atlantis> show ip ospf border-routers ============ OSPF router routing table ============= R 192.168.0.253 [10] area: (0.0.0.0), ABR via 192.168.0.253, eth1 [10] area: (0.0.0.1), ABR via 172.17.0.2, eth0 ou directement avec iproute : root@omega:~# ip route 212.170.21.128/26 dev eth0 proto kernel scope link src 212.170.21.172 192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.1 172.17.0.0/16 via 192.168.0.2 dev eth1 proto zebra metric 20 default via 212.170.21.129 dev eth0 proto zebra root@omega:~# Nous pouvons voir les routes Zebra, qui n'*taient pas pr*sentes auparavant. Il est vraiment agr*able de voir appara*tre les routes quelques secondes apr*s le lancement de zebra et ospfd. Vous pouvez v*rifier la connectivit* avec les autres h*tes en utilisant ping. Les routes zebra sont automatiques. Vous pouvez ajouter un autre routeur au r*seau, configurez Zebra et voil* ! Astuce : vous pouvez utiliser : tcpdump -i eth1 ip[9] == 89 pour analyser les paquets OSPF. Le num*ro du protocole OSPF est 89 et le champ du protocole est le 9i*me octet de l'en-t*te ip. OSPF poss*de de nombreux param*tres, sp*cialement pour les grands r*seaux. Dans de prochains d*veloppements du HOWTO, nous montrerons des m*thodes de r*glages fins d'OSPF. -------------------------------------------------------------------------- Configurer BGP4 avec Zebra Le Border Gateway Protocol Version 4 (BGP4) est un protocole de routage dynamique d*crit dans la RFC 1771. Il permet la distribution des informations de connectivit*, c'est * dire les tables de routage, vers d'autres noeuds BGP4 actifs. Il peut *tre utilis* comme un EGP ou un IGP. Dans le mode EGP, chaque noeud doit avoir son propre num*ro de syst*me autonome ( utonomous System (AS)). BGP4 supporte ????????? et l'aggr*gation de routes (r*unir plusieurs routes en une seule). > The Border Gateway Protocol Version 4 (BGP4) is a dynamic routing > protocol described in RFC 1771. It allows the distribution of > reachability information, i.e. routing tables, to other BGP4 > enabled nodes. It can either be used as EGP or IGP, in EGP mode > each node must have its own Autonomous System (AS) number. > BGP4 supports Classless Inter Domain Routing (CIDR) and route > aggregation (merge multiple routes into one). -------------------------------------------------------------------------- sch*ma r*seau (Exemple) Le sch*ma r*seau suivant est utilis* pour les exemples * suivre. AS 1 et 50 ont plusieurs voisins mais nous avons seulement besoin de configurer 1 et 50 comme nos voisins. Les noeuds communiquent entre eux par des tunnels dans cet exemple, mais ce n'est pas une obligation. Note : les num*ros AS utilis*s dans cet exemple sont r*serv*s. Veuillez obtenir vos propres num*ros AS du RIPE si vous installez des liens officiels. -------------------- | 192.168.23.12/24 | | AS: 23 | -------------------- / \ / \ / \ ------------------ ------------------ | 192.168.1.1/24 |-------| 10.10.1.1/16 | | AS: 1 | | AS: 50 | ------------------ ------------------ -------------------------------------------------------------------------- Configuration (Exemple) La configuration suivante est *crite pour le noeud 192.168.23.12/24 et elle sera facile * adapter pour les autres noeuds. Elle commence par des *l*ments g*n*raux comme le nom de l'h*te, les mots de passe et les options de debug : ! hostname hostname anakin ! login password password xxx ! enable password (super user mode) enable password xxx ! path to logfile log file /var/log/zebra/bgpd.log ! debugging: be verbose (can be removed afterwards) debug bgp events debug bgp filters debug bgp fsm debug bgp keepalives debug bgp updates La liste de contr*le d'acc*s (Access list) est utilis*e pour limiter la redistribution aux r*seaux priv*s (RFC 1918). ! RFC 1918 networks access-list local_nets permit 192.168.0.0/16 access-list local_nets permit 172.16.0.0/12 access-list local_nets permit 10.0.0.0/8 access-list local_nets deny any L'etape suivante consiste * configurer chaque AS : ! Own AS number router bgp 23 ! IP address of the router bgp router-id 192.168.23.12 ! announce our own network to other neighbors network 192.168.23.0/24 ! advertise all connected routes (= directly attached interfaces) redistribute connected ! advertise kernel routes (= manually inserted routes) redistribute kernel Chaque section 'router bgp' contient une liste de voisins auquels le routeur est connect* : neighbor 192.168.1.1 remote-as 1 neighbor 192.168.1.1 distribute-list local_nets in neighbor 10.10.1.1 remote-as 50 neighbor 10.10.1.1 distribute-list local_nets in -------------------------------------------------------------------------- V*rification de la configuration Note : vtysh est un multiplexeur qui connecte toutes les interfaces utilisateur de zebra ensemble. anakin# sh ip bgp summary BGP router identifier 192.168.23.12, local AS number 23 2 BGP AS-PATH entries 0 BGP community entries Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd 10.10.0.1 4 50 35 40 0 0 0 00:28:40 1 192.168.1.1 4 1 27574 27644 0 0 0 03:26:04 14 Total number of neighbors 2 anakin# anakin# sh ip bgp neighbors 10.10.0.1 BGP neighbor is 10.10.0.1, remote AS 50, local AS 23, external link BGP version 4, remote router ID 10.10.0.1 BGP state = Established, up for 00:29:01 .... anakin# Voyons quelles routes nous avons obtenues de nos voisins : anakin# sh ip ro bgp Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, B - BGP, > - selected route, * - FIB route B>* 172.16.0.0/14 [20/0] via 192.168.1.1, tun0, 2d10h19m B>* 172.30.0.0/16 [20/0] via 192.168.1.1, tun0, 10:09:24 B>* 192.168.5.10/32 [20/0] via 192.168.1.1, tun0, 2d10h27m B>* 192.168.5.26/32 [20/0] via 192.168.1.1, tun0, 10:09:24 B>* 192.168.5.36/32 [20/0] via 192.168.1.1, tun0, 2d10h19m B>* 192.168.17.0/24 [20/0] via 192.168.1.1, tun0, 3d05h07m B>* 192.168.17.1/32 [20/0] via 192.168.1.1, tun0, 3d05h07m B>* 192.168.32.0/24 [20/0] via 192.168.1.1, tun0, 2d10h27m anakin# -------------------------------------------------------------------------- Chapitre 18. Autres possibilit*s Ce chapitre est une liste des projets ayant une relation avec le routage avanc* et la mise en forme du trafic sous Linux. Certains de ces liens m*riteraient des chapitres sp*cifiques, d'autres sont tr*s bien document*s, et n'ont pas besoin de HOWTO en plus. Impl*mentation VLAN 802.1Q pour Linux [232](site) VLAN est une fa*on tr*s sympa de diviser vos r*seaux d'une mani*re plus virtuelle que physique. De bonnes informations sur les VLAN pourront *tre trouv*es [233]ici. Avec cette impl*mentation, votre boite Linux pourra dialoguer VLAN avec des machines comme les Cisco Catalyst, 3Com: {Corebuilder, Netbuilder II, SuperStack II switch 630}, Extreme Ntwks Summit 48, Foundry: {ServerIronXL, FastIron}. Impl*mentation alternative VLAN 802.1Q pour Linux[234](site) Une impl*mentation alternative de VLAN pour Linux. Ce projet a d*marr* suite au d*saccord avec l'architecture et le style de codage du projet VLAN '*tabli', avec comme r*sultat une structure de l'ensemble plus clair. Mise * jour : a *t* inclus dans le noyau 2.4.14 (peut-*tre dans le 2.4.13). Un bon HOWTO * propos des VLAN peut *tre trouv* [235]ici. Mise * jour : a *t* inclue dans le noyau * partir de la version 2.4.14 (peut-*tre 13). Serveur Linux Virtuel (Linux Virtual Server )[236](site) Ces personnes sont tr*s talentueuses. Le Serveur Virtuel Linux est un serveur * haute disponibilit*, hautement *volutif, construit autour d'une grappe (cluster) de serveurs, avec un *quilibreur de charge tournant sur le syst*me d'exploitation Linux. L'architecture du cluster est transparente pour les utilisateurs finaux, qui ne voient qu'un simple serveur virtuel. En r*sum*, que vous ayez besoin d'*quilibrer votre charge ou de contr*ler votre trafic, LVS aura une mani*re de le faire. Certaines de leurs techniques sont positivement diaboliques !. Par exemple, ils permettent * plusieurs machines d'avoir une m*me adresse IP, mais en d*sactivant l'ARP dessus. Seule la machine LVS qui a, elle, l'ARP actif, d*cide de l'h*te qui manipulera le paquet entrant. Celui-ci est envoy* avec la bonne adresse MAC au serveur choisi. Le trafic sortant passe directement par le routeur, et non par la machine LVS, qui, par cons*quent n'a pas besoin de voir vos 5Gbit/s de donn*es allant sur Internet. Cette machine LVS ne peut alors pas *tre un goulot d'*tranglement. L'impl*mentation de LVS n*cessite une mise * jour pour les noyaux 2.0 et 2.2, alors qu'un module Netfilter est disponible dans le 2.4. Il n'y a donc pas besoin de mise * jour pour cette version du noyau. Le support 2.4 est encore en d*veloppement. Battez-vous donc avec et envoyez vos commentaires ou vos mises * jour. CBQ.init [237](site) Configurer CBQ peut *tre un peu intimidant, sp*cialement si votre seul souhait est de mettre en forme le trafic d'ordinateurs plac*s derri*re un routeur. CBQ.init peut vous aider * configurer Linux * l'aide d'une syntaxe simplifi*e. Par exemple, si vous voulez que tous les ordinateurs de votre r*seau 192.168.1.0/24 (sur eth1 10 Mbits) aient leur vitesse de t*l*chargement limit*e * 28 Kbits, remplissez le fichier de configuration de CBQ.init avec ce qui suit : DEVICE=eth1,10Mbit,1Mbit RATE=28Kbit WEIGHT=2Kbit PRIO=5 RULE=192.168.1.0/24 Utiliser simplement ce programme si le 'comment et pourquoi' ne vous int*resse pas. Nous utilisons CBQ.init en production et il marche tr*s bien. On peut m*me faire des choses plus avanc*es, comme la mise en forme d*pendant du temps. La documentation est directement int*gr*e dans le script, ce qui explique l'absence d'un fichier README. Scripts faciles de mise en forme Chronox[238](site) Stephan Mueller (smueller@chronox.de) a *crit deux scripts utiles, "limit.conn" et "shaper". Le premier vous permet de ma*triser une session de t*l*chargement, comme ceci : # limit.conn -s SERVERIP -p SERVERPORT -l LIMIT Il fonctionne avec Linux 2.2 et 2.4. Le second script est plus compliqu* et peut *tre utilis* pour mettre en place des files d'attente diff*rentes bas*es sur les r*gles iptables. Celles-ci sont utilis*es pour marquer les paquets qui sont alors mis en forme. Impl*mentation du Protocole Redondant Routeur Virtuel [239](site) Ceci est purement pour la redondance. Deux machines avec leurs propres adresses IP et MAC cr*ent une troisi*me adresse IP et MAC virtuelle. Bien que destin* * l'origine uniquement aux routeurs, qui ont besoin d'adresses MAC constantes, cela marche *galement pour les autres serveurs. La beaut* de cette approche est l'incroyable facilit* de la configuration. Pas de compilation de noyau ou de n*cessit* de mise * jour, tout se passe dans l'espace utilisateur. Lancer simplement ceci sur toutes les machines participant au service : # vrrpd -i eth0 -v 50 10.0.0.22 Et vous voil* op*rationnel ! 10.0.0.22 est maintenant g*r* par l'un de vos serveurs, probablement le premier * avoir lanc* le d*mon vrrp. D*connectez maintenant cet ordinateur du r*seau et tr*s rapidement, l'adresse 10.0.0.22 et l'adresse MAC seront g*r*es par l'un des autres ordinateurs. J'ai essay* ceci et il a *t* actif et op*rationnel en 1 minute. Pour une raison *trange, ma passerelle par d*faut a *t* supprim*e. Cependant, l'option -n permet de pr*venir cela. Voici une d*faillance en "direct" : 64 bytes from 10.0.0.22: icmp_seq=3 ttl=255 time=0.2 ms 64 bytes from 10.0.0.22: icmp_seq=4 ttl=255 time=0.2 ms 64 bytes from 10.0.0.22: icmp_seq=5 ttl=255 time=16.8 ms 64 bytes from 10.0.0.22: icmp_seq=6 ttl=255 time=1.8 ms 64 bytes from 10.0.0.22: icmp_seq=7 ttl=255 time=1.7 ms Pas *un* paquet ping n'a *t* perdu ! Apr*s 4 paquets, j'ai d*connect* mon P200 du r*seau, et mon 486 a pris le relais, ce qui est visible par l'augmentation du temps de latence. -------------------------------------------------------------------------- Chapitre 19. Lectures suppl*mentaires [240]http://snafu.freedom.org/linux2.2/iproute-notes.html Contient beaucoup d'informations techniques, et de commentaires sur le noyau. [241]http://www.davin.ottawa.on.ca/ols/ Transparents de Jamal Hadi Salim, un des auteurs du contr*leur de trafic de Linux. [242]http://defiant.coinet.com/iproute2/ip-cref/ Version HTML de la documentation LaTeX d'Alexeys ; explique une partie d'iproute2 en d*tails. [243]http://www.aciri.org/floyd/cbq.html Sally Floyd a une bonne page sur CBQ, incluant ses publications originales. Aucune n'est sp*cifique * Linux, mais il y a un travail de discussion sur la th*orie et l'utilisation de CBQ. Contenu tr*s technique, mais une bonne lecture pour ceux qui sont int*ress*s. Differentiated Services on Linux This [244]document par Werner Almesberger, Jamal Hadi Salim et Alexey Kuznetsov. D*crit les fonctions DiffServ du noyau Linux, entre autres les gestionnaires de mise en file d'attente TBF, GRED, DSMARK et le classificateur tcindex. [245]http://ceti.pl/~ekravietz/cbq/NET4_tc.html Un autre HOWTO, en polonais ! Vous pouvez cependant copier/coller les lignes de commandes, elles fonctionnent de la m*me fa*on dans toutes les langues. L'auteur travaille en collaboration avec nous et sera peut *tre bient*t un auteur de sections de cet HOWTO. [246]IOS Committed Access Rate Des gens de Cisco qui ont pris la louable habitude de mettre leur documentation en ligne. La syntaxe de Cisco est diff*rente mais les concepts sont identiques, sauf qu'on fait mieux, et sans mat*riel coutant le prix d'une voiture :-) TCP/IP Illustrated, volume 1, W. Richard Stevens, ISBN 0-201-63346-9 Sa lecture est indispensable si vous voulez r*ellement comprendre TCP/IP, et de plus elle est divertissante. -------------------------------------------------------------------------- Chapitre 20. Remerciements Notre but est de faire la liste de toutes les personnes qui ont contribu* * ce HOWTO, ou qui nous ont aid*s * expliquer le fonctionnement des choses. Alors qu'il n'existe pas actuellement de tableau d'honneur Netfilter, nous souhaitons saluer les personnes qui apportent leur aide. * Junk Alins <[247]juanjo@mat.upc.es> * Joe Van Andel * Michael T. Babcock <[248]mbabcock@fibrespeed.net> * Christopher Barton <[249]cpbarton%uiuc.edu> * Peter Bieringer <[250]pb:bieringer.de> * Ard van Breemen <[251]ard%kwaak.net> * Ron Brinker <[252]service%emcis.com> * ?ukasz Bromirski <[253]l.bromirski@mr0vka.eu.org> * Lennert Buytenhek <[254]buytenh@gnu.org> * Esteve Camps <[255]esteve@hades.udg.es> * Ricardo Javier Cardenes <[256]ricardo%conysis.com> * Stef Coene <[257]stef.coene@docum.org> * Don Cohen <[258]don-lartc%isis.cs3-inc.com> * Jonathan Corbet <[259]lwn%lwn.net> * Gerry N5JXS Creager <[260]gerry%cs.tamu.edu> * Marco Davids <[261]marco@sara.nl> * Jonathan Day <[262]jd9812@my-deja.com> * Martin aka devik Devera <[263]devik@cdi.cz> * Hannes Ebner <[264]he%fli4l.de> * Derek Fawcus <[265]dfawcus%cisco.com> * David Fries <[266]dfries%mail.win.org> * Stephan "Kobold" Gehring <[267]Stephan.Gehring@bechtle.de> * Jacek Glinkowski <[268]jglinkow%hns.com> * Andrea Glorioso <[269]sama%perchetopi.org> * Thomas Graaf <[270]tgraf%suug.ch> * Sandy Harris <[271]sandy%storm.ca> * Nadeem Hasan <[272]nhasan@usa.net> * Erik Hensema <[273]erik%hensema.xs4all.nl> * Vik Heyndrickx <[274]vik.heyndrickx@edchq.com> * Spauldo Da Hippie <[275]spauldo%usa.net> * Koos van den Hout <[276]koos@kzdoos.xs4all.nl> * Stefan Huelbrock * Ayotunde Itayemi <[277]aitayemi:metrong.com> * Alexander W. Janssen * Andreas Jellinghaus * Gareth John * Dave Johnson <[278]dj@www.uk.linux.org> * Martin Josefsson * Andi Kleen * Andreas J. Koenig * Pawel Krawczyk * Amit Kucheria * Edmund Lau * Philippe Latu * Arthur van Leeuwen * Jose Luis Domingo Lopez <[279]jdomingo@24x7linux.com> * Robert Lowe <[280]robert.h.lowe@lawrence.edu> * Jason Lunz * Stuart Lynne * Alexey Mahotkin * Predrag Malicevic * Patrick McHardy * Andreas Mohr * James Morris * Andrew Morton * Wim van der Most * Stephan Mueller * Togan Muftuoglu * Chris Murray * Patrick Nagelschmidt * Ram Narula * Jorge Novo * Patrik * P?l Osgy?ny * Lutz Preßler * Jason Pyeron * Rod Roark * Pavel Roskin * Rusty Russell * Mihai RUSU * Rob Pitman * Jamal Hadi Salim * Ren? Serral * David Sauer * Sheharyar Suleman Shaikh * Stewart Shields * Nick Silberstein * Konrads Smelkov * William Stearns <[281]wstearns@pobox.com> * Andreas Steinmetz * Matthew Strait * Jason Tackaberry * Charles Tassell * Glen Turner * Tea Sponsor: Eric Veldhuyzen * Thomas Walpuski * Song Wang * Chris Wilson <[282]chris@netservers.co.uk> * Lazar Yanackiev <[283]Lyanackiev%gmx.net> * Pedro Larroy <[284]piotr%member.fsf.org> * Chaptitre 15, section 10: Exemple d'une solution de translation d'adresse avec de la QoS * Chaptitre 17, section 1: Configurer OSPF avec Zebra