Historique des versions | ||
---|---|---|
Version $Revision: 1112 $ | $Date: 2007-04-21 16:52:00 +0200 (sam, 21 avr 2007) $ | $Author: latu $ |
IPSEC, OSPF & BGP |
Résumé
Une approche pratique d'iproute2, de la mise en forme du trafic et un peu de netfilter.
Table des matières
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 à 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 Autres possibilités, et lisez ce qui concerne CBQ.init.
Voici d'autres références qui pourront vous aider à en apprendre plus :
Très bonne introduction, expliquant ce qu'est un réseau, et comment on le connecte à d'autres réseaux.
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é
en ligne
L'adresse canonique de cet HOWTO est 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.
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 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.
Nous nous focaliserons principalement sur ce qu'il est possible de faire en combinant netfilter et iproute2.
Vous pouvez aussi essayer 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.
L'outil ip est central, et nous allons lui demander de nous montrer les interfaces.
[ahu@home ahu]$ ip link list 1: lo: <LOOPBACK,UP> mtu 3924 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: dummy: <BROADCAST,NOARP> mtu 1500 qdisc noop link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff 3: eth0: <BROADCAST,MULTICAST,PROMISC,UP> mtu 1400 qdisc pfifo_fast qlen 100 link/ether 48:54:e8:2a:47:16 brd ff:ff:ff:ff:ff:ff 4: eth1: <BROADCAST,MULTICAST,PROMISC,UP> mtu 1500 qdisc pfifo_fast qlen 100 link/ether 00:e0:4c:39:24:78 brd ff:ff:ff:ff:ff:ff 3764: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP> mtu 1492 qdisc pfifo_fast qlen 10 link/ppp
ip nous montre bien, cependant, l'adresse MAC, l'identifiant matériel de nos interfaces ethernet.
[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
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 est le Protocole de Résolution d'Adresse
(Address Resolution Protocol).
Il est décrit dans le
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.
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 paquet iproute2 de votre distribution].
[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
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
# 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
# ip route add default via 195.96.98.253 dev ppp2 table John # ip route flush cache
________ +--------------+ / | | | +-------------+ 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.
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 T2Rien 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 $IP2Indiquez maintenant votre préférence pour votre route par défaut :
ip route add default via $P1Vous 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 T2Cet 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 |
ip route add default scope global nexthop via $P1 dev $IF1 weight 1 \ nexthop via $P2 dev $IF2 weight 1Ceci 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 à http://www.ssi.bg/~ja/#routes Elles rendront le travail plus facile.
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).
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.
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.
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
Dans Linux, vous aurez besoin du module ip_gre.o.
Dans un premier temps, intéressons-nous au tunnel IPv4 :
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
.
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
.
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
La deuxième ligne active le périphérique.
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.
Voir la section 6 pour une courte description des adresses IPv6.
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
Par Marco Davids <marco@sara.nl>
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.
De petites choses à propos des adresses IPv6 :
Un exemple :
2002:836b:9820:0000:0000:0000:836b:9886
C'est dans cette situation que l'on monte un tunnel.
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: <LOOPBACK,UP> mtu 3924 qdisc noqueue inet6 ::1/128 scope host 3: eth0: <BROADCAST,MULTICAST,UP> 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.
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 un site officiel et également 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, des personnes se sont inquiétées de la qualité du code. Pour configurer FreeS/WAN, de nombreuses documentations sont 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 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 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 |
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.
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 <net/route.h> dans deux fichiers. Je fournis une 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. |
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 Section 2.3, « 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 grâce à 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 password2Sur 10.0.0.216 :
10.0.0.11 password2Soyez 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=0Nous 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
$ openssl req -new -nodes -newkey rsa:1024 -sha1 -keyform PEM -keyout \ laptop.private -outform PEM -out request.pemDes 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 keyLe 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é !
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 Section 2.2, « Exemple »). Lancez alors racoon et tout devrait fonctionner.
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.
#!/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 ! |
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 sur cette page.
isakpmd est différent de racoon mentionné au-dessus, mais de nombreuses personnes l'apprécient. Il peut être trouvé ici. D'autres éléments de lecture sur le CVS d'OpenBSD ici. Thomas a également créé un 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 ici.
ip route add 224.0.0.0/4 dev eth0
Maintenant, dire à Linux de transmettre les paquets...
echo 1 > /proc/sys/net/ipv4/ip_forward
ping -c 2 224.0.0.1
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
priomap
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
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
1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1
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 <même chose que requête> (presque)
txqueuelen
Notez que, dans l'implémentation réelle, les jetons correspondent à des octets, et non des paquets.
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).
Les astuces suivantes peuvent vous aider à choisir la file d'attente à utiliser. Elles mentionnent certaines files d'attente décrites dans le chapitre 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 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 !
Ce qui suit est lâchement inspiré du texte
draft-ietf-diffserv-model-06.txt
,
An Informal Management Model for Diffserv Routers.
Il peut être trouvé à l'adresse
http://www.ietf.org/internet-drafts/draft-ietf-diffserv-model-04.txt
.
Lisez-le pour les définitions strictes des termes utilisés.
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).
Un gestionnaire de mise en file d'attente qui n'a pas de subdivisions internes configurables.
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.
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.
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.
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.
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.
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.
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).
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).
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.
Nous évoquerons bientôt, plus à propos, CBQ et ses alternatives.
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
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
.
Les paramètres suivants sont reconnus par tc :
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 ...
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:
.
# 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.
Voici les paramètres que vous pouvez spécifier pour configurer la mise en forme :
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)
# 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 boundedCette 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.
# 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
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
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
# 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.
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 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 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.
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.
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
Comme expliqué dans le chapitre 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
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.
Source: match ip sport 80 0xffff
et
destination : match ip dport ?? 0xffff
# 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
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
Pour plus de commandes de filtrage, voir le chapitre Filtres avancés pour la classification des paquets.
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:10Dans 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 imqIl 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 site imq.
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.
Jusqu'à maintenant, nous avons vu comment iproute travaille, et netfilter a été mentionné plusieurs fois. Vous ne perdrez pas votre temps à consulter Rusty's Remarkably Unreliable Guides. Le logiciel Netfilter peut être trouvé 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, grâce à 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 traduction 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 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 Section 5, « Cache web transparent utilisant netfilter, iproute2, ipchains et squid » dans le chapitre Recettes de cuisine.
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 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 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
.
tc filter add dev IF [ protocol PROTO ] [ (preference|priority) PRIO ] [ parent CBQ ]
Les options décrites s'appliquent à tous les filtres, pas seulement à
u32
.
# 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
# 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
match [ u32 | u16 | u8 ] PATTERN MASK [ at OFFSET | nexthdr+OFFSET]
# tc filter add dev ppp14 parent 1:0 prio 10 u32 \ match u8 64 0xff at 8 \ flowid 1:4
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
FIXME: emplacement de la table - la table est dans un fichier séparé "selector.html"
FIXME: C'est encore en Polonais :-(
# 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 :
# tc filter add dev ppp0 parent 1:0 prio 10 u32 \ match tcp dport 53 0xffff \ match ip protocol 0x6 0xff \ flowid 1:2
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 route
# ip route add Host/Network via Gateway dev Device realm RealmNumber
# ip route add 192.168.10.0/24 via 192.168.10.1 dev eth1 realm 10
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 \ route to 10 classid 1:10
# 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
Utilisez les paramètres suivants :
Ceux-ci se comportent la plupart du temps de manière identique à ceux
décrits dans la section 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.
Le seul vrai exemple connu est mentionné dans la section 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.
# 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
# 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.
# 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
# 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:
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 ?
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
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
# 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
# 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
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.
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
# echo 1 >/proc/sys/net/ipv4/conf/<interfacename>/log_martians
FIXME: Est-ce que la configuration des fichiers dans .../conf/{default,all} suffit ? - martijn
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 http://ipsysctl-tutorial.frozentux.net/.
Plusieurs éléments de la liste suivante proviennent du fichier
/usr/src/linux/Documentation/networking/ip-sysctl.txt
,
écrit par
<
kuznet@ms2.inr.ac.ru>
et <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 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 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.
/proc/sys/net/ipv4/conf/DEV/accept_redirects
/proc/sys/net/ipv4/conf/DEV/accept_source_route
/proc/sys/net/ipv4/conf/DEV/bootp_relay
/proc/sys/net/ipv4/conf/DEV/forwarding
/proc/sys/net/ipv4/conf/DEV/log_martians
/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 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
/proc/sys/net/ipv4/neigh/DEV/anycast_delay
/proc/sys/net/ipv4/neigh/DEV/app_solicit
/proc/sys/net/ipv4/neigh/DEV/base_reachable_time
/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
/proc/sys/net/ipv4/neigh/DEV/locktime
/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
/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
/proc/sys/net/ipv4/neigh/DEV/ucast_solicit
/proc/sys/net/ipv4/neigh/DEV/unres_qlen
Livre traitant des sujets liés à la qualité de service. Bien pour comprendre les concepts de base.
/proc/sys/net/ipv4/route/error_burst
/proc/sys/net/ipv4/route/error_cost
/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
Voir aussi 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.
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.
Documents sources :
Exemples de la distribution iproute2.
White Paper-QoS protocols and architectures et Foires Aux Questions IP QoS, les deux par Quality of Service Forum.
Avant tout, il serait préférable de lire les RFC écrits sur ce sujet (RFC2474, RFC2475, RFC2597 et RFC2598) sur le site web du groupe de travail DiffServ IETF et sur le site web de Werner Almesberger (Il a écrit le code permettant le support des Services Différenciés sous Linux).
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 ?
Ce gestionnaire de mise en file d'attente réalisera les étapes suivantes :
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
tc class change dev eth0 classid 1:1 dsmark mask 0x3 value 0xb8Cela 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.
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.
Lire l'article sur la file d'attente RED par Sally Floyd et Van Jacobson pour les informations techniques.
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 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
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 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.
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.
# ip address add 188.177.166.1 dev eth0 # ip address add 188.177.166.2 dev eth0
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
Si vous voulez protéger tout un réseau, oubliez ce script, qui est plus adapté à un hôte seul.
#! /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
[Internet] ---<E3, T3, n'importe quoi>--- [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
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.
# 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
# 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
|----------------| | 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 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)
"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
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| |---------------------------------------| 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
# 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.
J'ai essayé de créer le Saint Graal :
Même si http est un trafic de masse, les autres trafics ne doivent pas trop le noyer.
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.
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 trafic descendant est réglementé en utilisant un filtre tc contenant un Token Bucket Filter.
#!/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 :1Si 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 !
#!/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 :1Si 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 !
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 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 Chapitre 9, Gestionnaires de mise en file d'attente pour l'administration de la bande passante.
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 Section 6.2, « Toutes les commandes de filtres dont vous aurez normalement besoin ».
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 Section 2.3, « Mise en file d'attente stochastiquement équitable (Stochastic Fairness Queueing) » pour savoir ce que cela fait.
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 :
Si vous utilisez le noyau 2.4.18, vous devrez appliquer la mise à jour HTB.
Soyez également sûr que le binaire "tc" est compatible avec HTB. Un binaire pré compilé est distribué avec HTB.
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 10Nous 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| +----+ +----+ +----+ +----+ +----+ +----+
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é.
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.
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.
Cette classe est pour le trafic des autres machines «NATées» (NdT : bénéficiant du service de traduction d'adresse) qui ont besoin d'une priorité plus grande dans leur trafic de masse.
Le trafic mail (SMTP, pop3,...) et les paquets configurés avec le champ TOS "Coût Minimum" seront envoyés dans cette classe.
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.
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:15Nous 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 traduction 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.172Vé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 RETURNVous 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 eth0Nous 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 RETURNDonnons 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 RETURNUne 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 RETURNEt 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 0x6Ainsi, 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.
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
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
ici
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 câble 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 cette page.
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.
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 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
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 :-)
Contactez-moi si les informations qui suivent ne sont pas exactes ou si vous avez des suggestions. 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 :
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.
Les routes sont propagées très rapidement, comparé à RIP par exemple.
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.
OSPF est basé sur l'algorithme de Dijkstra 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.
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.
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.
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.logDebian nécessite également l'édition de
/etc/zebra/daemons
pour qu'ils
soient lancés au démarrage :
zebra=yes ospfd=yesNous 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.logCeci indique à ospf la topologie de notre réseau.
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: StartIgnorez 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 :
Voyons comment les routes se sont propagées en se connectant à zebra :$
telnet localhost zebra$
telnet localhost ospfd
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, eth0ou 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] == 89pour 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.
! 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
! 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
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#
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 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}.
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é ici.
Mise à jour : a été inclue dans le noyau à partir de la version 2.4.14 (peut-être 13).
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.
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.
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.
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.
Contient beaucoup d'informations techniques, et de commentaires sur le noyau.
Transparents de Jamal Hadi Salim, un des auteurs du contrôleur de trafic de Linux.
Version HTML de la documentation LaTeX d'Alexeys ; explique une partie d'iproute2 en détails.
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.
This 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.
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.
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 :-)
Sa lecture est indispensable si vous voulez réellement comprendre TCP/IP, et de plus elle est divertissante.
Stefan Huelbrock <shuelbrock%datasystems.de>
Alexander W. Janssen <yalla%ynfonatic.de>
Andreas Jellinghaus <aj%dungeon.inka.de>
Gareth John <gdjohn%zepler.org>
Martin Josefsson <gandalf%wlug.westbo.se>
Andi Kleen <ak%suse.de>
Andreas J. Koenig <andreas.koenig%anima.de>
Pawel Krawczyk <kravietz%alfa.ceti.pl>
Amit Kucheria <amitk@ittc.ku.edu>
Edmund Lau <edlau%ucf.ics.uci.edu>
Philippe Latu <philippe.latu%linux-france.org>
Arthur van Leeuwen <arthurvl%sci.kun.nl>
Jason Lunz <j@cc.gatech.edu>
Stuart Lynne <sl@fireplug.net>
Alexey Mahotkin <alexm@formulabez.ru>
Predrag Malicevic <pmalic@ieee.org>
Patrick McHardy <kaber@trash.net>
Andreas Mohr <andi%lisas.de>
James Morris <jmorris@intercode.com.au>
Andrew Morton <akpm%zip.com.au>
Wim van der Most
Stephan Mueller <smueller@chronox.de>
Togan Muftuoglu <toganm%yahoo.com>
Chris Murray <cmurray@stargate.ca>
Patrick Nagelschmidt <dto%gmx.net>
Ram Narula <ram@princess1.net>
Jorge Novo <jnovo@educanet.net>
Patrik <ph@kurd.nu>
P?l Osgy?ny <oplab%westel900.net>
Lutz Preßler <Lutz.Pressler%SerNet.DE>
Jason Pyeron <jason%pyeron.com>
Rod Roark <rod%sunsetsystems.com>
Pavel Roskin <proski@gnu.org>
Rusty Russell <rusty%rustcorp.com.au>
Mihai RUSU <dizzy%roedu.net>
Rob Pitman <rob%pitman.co.za>
Jamal Hadi Salim <hadi%cyberus.ca>
Ren? Serral <rserral%ac.upc.es>
David Sauer <davids%penguin.cz>
Sheharyar Suleman Shaikh <sss23@drexel.edu>
Stewart Shields <MourningBlade%bigfoot.com>
Nick Silberstein <nhsilber%yahoo.com>
Konrads Smelkov <konrads@interbaltika.com>
Andreas Steinmetz <ast%domdv.de>
Matthew Strait <straitm%mathcs.carleton.edu>
Jason Tackaberry <tack@linux.com>
Charles Tassell <ctassell%isn.net>
Glen Turner <glen.turner%aarnet.edu.au>
Tea Sponsor: Eric Veldhuyzen <eric%terra.nu>
Thomas Walpuski <thomas%bender.thinknerd.de>
Song Wang <wsong@ece.uci.edu>
Chaptitre 15, section 10: Exemple d'une solution de traduction d'adresse avec de la QoS
Chaptitre 17, section 1: Configurer OSPF avec Zebra