Routage dynamique avec BGP

Stéphane Bortzmeyer

AFNIC


  Immeuble International
  78181
  Saint-Quentin-en-Yvelines
  France
  

Gitoyen

Une grande partie de ce cours a pu être faite grâce
à l'expérience acquise en concevant et en déployant le réseau
de l'opérateur Internet Gitoyen.


$Id: bgp-partial.db,v 1.1 2003/09/09 14:04:24 bortzmeyer Exp $

Ce document est fourni pour vous permettre de comprendre et de configurer BGP. Le ou les auteurs ne sont évidemment pas responsables des dégâts que vous causerez à votre réseau.

BGP étant un protocole de routage entre entités administratives distinctes, toute erreur de manipulation peut être vue à l'extérieur de votre organisation, voire dans tout l'Internet. Prudence !

Ce document est distribué sous les termes de la GNU Free Documentation License. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.

Résumé

Ce document explique la conception et la configuration d'un réseau TCP/IP d'opérateur, interconnecté avec d'autres opérateurs et utilisant le routage dynamique, en l'occurrence avec le protocole BGP.

Il se veut pratique : l'accent est mis sur une configuration simple qui devrait couvrir la plupart des cas. Il ne remplace donc pas un cours complet sur BGP.


Table des matières

Introduction
Premier réseau et première configuration
Configurations plus riches
Déboguage
Bibliographie
Bibliographie

Introduction

Dois-je utiliser BGP ?

BGP est nécessaire si :

  • Vous voulez vous connecter à plusieurs fournisseurs de connectivité de manière propre[1].

  • Vous voulez vous connecter à un point d'échange entre opérateurs. De tels points d'échange sont un outil essentiel pour la connectivité Internet d'un pays : ils permettent aux opérateurs d'un pays d'échanger du trafic directement, sans passer par les États-Unis ou bien l'Europe.

Petit rappel IP

[Important]Important

Ce texte n'est qu'un rappel, ce cours nécessite une bonne connaissance d'IP.

Le protocole IP (que cela soit IPv4 ou bien IPv6) repose sur la notion d'adresse. Une machine a une ou plusieurs adresses qui s'écrivent, en IPv4, avec quatre chiffres séparés par des points, comme 80.67.160.1[2] et en IPv6 par plusieurs groupes de chiffres séparés par des deux-points, comme 2001:910::5043:a001[3].

Dans une adresse, les chiffres binaires les plus à gauche identifient le réseau (d'où le nom de préfixe), les chiffres les plus à droite la machine. Le nombre de chiffres pour chaque rôle dépend de la longueur du préfixe. Celle-ci s'indique par un chiffre suivant une barre oblique. Par exemple, 80.67.160.1/27 indique que l'adresse IP en question identifie une machine dans un réseau où les 27 premiers bits désignent le réseau et les 5 derniers la machine (les adresses IPv4 comptent 32 bits). De la même façon, fec0:1:0:ff00::1/64 est une adresse IPv6 sur un réseau où il y a 64 bits pour le réseau et 64 pour la machine (les adresses IPv6 comptent 128 bits).

Il est important de noter que la longueur du préfixe dépend de l'endroit où on se trouve. Du fait de l'agrégation des préfixes, le réseau 80.67.160.0/27 se trouve par exemple annoncé sur Internet comme une partie de 80.67.160.0/19.

Il existe des outils pour faciliter les calculs sur les adresses. En IPv4, netmask permet, par exemple :

% netmask 80.67.168.6/191
    80.67.160.0/19
% netmask -s 80.67.168.6/272
    80.67.168.0/255.255.255.224
% netmask -r 80.67.168.6/27 3
    80.67.168.0-80.67.168.31    (32)
	
1

Quelle est l'adresse du réseau correspondant à cette adresse et cette longueur de préfixe ?

2

IPv4 utilise encore beaucoup une vieille notation : au lieu de la longueur du préfixe, on affiche un masque où tous les bits "réseau" valent 1 et tous les bits "machine" valent 0.

3

Quelles sont les adresses IP dans ce réseau ?

En IPv6, il n'existe malheureusement pas d'outils équivalents mais ipv6calc permet certaines choses.

Petit rappel routage

Pour transmettre un paquet, une machine IP suit sa table de routage. On peut l'afficher sur quasiment tous les Unix avec netstat -rn, qui est la commande la plus portable, ou bien avec route -n sur Linux, route -n show sur NetBSD, show ip route sur IOS, etc. La table de routage est une série d'entrées, et elle fait correspondre à un préfixe, l'adresse IP du routeur où envoyer le paquet. Par exemple, si un routeur a la table de routage suivante :

147.94.0.4      194.68.129.102  255.255.255.252 UG    0      0        0 eth1
213.223.128.0   194.68.129.244  255.255.255.248 UG    0      0        0 eth1
192.54.202.641   194.68.129.102  255.255.255.240 UG    0      0        0 eth1
194.6.149.64    194.68.129.244  255.255.255.224 UG    0      0        0 eth1
194.6.145.0     194.68.129.244  255.255.255.224 UG    0      0        0 eth1
213.56.168.160  194.68.129.224  255.255.255.224 UG    0      0        0 eth1
195.141.72.128  194.68.129.213  255.255.255.224 UG    50     0        0 eth1
1

Les paquets à destination de 192.54.202.66 (netmask 192.54.202.66/255.255.255.240 donne 192.54.202.64) seront envoyés à 194.68.129.102. traceroute permet de vérifier cela :

traceroute to 192.54.202.66 (192.54.202.66), 30 hops max, 40 byte packets
 1  194.68.129.102  1 ms  0 ms  0 ms
 2  193.51.179.158  1 ms  1 ms  1 ms
...
	

Il y a une légère différence en IPv6 : il existe des adresses spécifiques à un lien (link local), leur préfixe est fe80::/10 et ce sont ces adresses qui sont utilisées dans la table de routage.

rachel:~ % netstat -r -n -finet6
...
Destination                        Gateway                        Flags     Refs     Use    Mtu  Interface
default                            fe80::201:96ff:fe96:dc60%epic0 UG          0        0      -  epic0
      
[Important]Important

Pour une adresse IP de destination, il peut exister plusieurs entrées dans la table de routage. Si les longueurs de préfixe sont différentes, le routeur choisira la plus spécifique (le préfixe le plus long). Si les longueurs de préfixe sont égales, le résultat dépend du routeur. Avec Linux, si le noyau a été compilé avec l'option IP: equal cost multipath (CONFIG_IP_ROUTE_MULTIPATH)[4], les deux chemins pourront être utilisés, répartissant ainsi la charge.

Les tables de routage peuvent être construites manuellement (l'ingénieur système ajoute des commandes dans un fichier de configuration) ou automatiquement par un système de routage dynamique. Dans ce dernier cas, les routeurs échangent de l'information entre eux ("Je suis connecté à un lien qui porte les préfixes 2001:910::/32 et FEC0:1::/32", "J'ai une liaison point-à-point avec 82.3.67.98") et, sur la base de ces informations, construisent chacun sa table de routage.

En anglais, on appelle le routage effectif des paquets forwarding et la construction des tables de routage routing. Tout routeur IP fait du forwarding mais le routage pouvant être statique, tous ne font pas du routing. Ces deux fonctions sont typiquement mises en oeuvre par des parties très distinctes du routeur[5].

Et si ça ne marche pas ?

Si votre configuration TCP/IP ne fonctionne pas, il est utile de demander de l'aide. D'innombrables listes de diffusion[6] existent à cette fin. Mais beaucoup de personnes ont du mal à donner sur une liste de diffusion les informations nécessaires pour érsoudre le problème.

Pour toute liste, les conseils suivants sont utiles :

  • Donnez les vraies informations. Il n'existe aucune raison sérieuse[7]de dissimuler les noms et les adresses IP utilisées. Au contraire, si vous indiquez les vraies adresses, les lecteurs pourront les essayer plus facilement.

    Sauf si vous soumettez un problème purement théorique, auquel cas vous devez utiliser des adresses RFC 1918, donnez les vraies adresses.

  • Donnez le maximum de détails sur votre environnement : système d'exploitation utilisé, version, type de réseau (Ethernet ? FDDI ?). N'oubliez pas que vos lecteurs ne sont pas dans votre tête : pour vous, il est évident que votre machine 192.168.7.34 est un routeur Extreme mais les autres ne le savent pas.

  • Faites des schémas. Un bon croquis vaut souvent mieux que bien des discours. Comme il n'existe pas de norme largement répandue pour transmettre des dessins[8], le mieux est d'utiliser l'ASCII art. Avec le mode picture de l'éditeur Emacs, c'est assez facile. En voici un exemple, avec indication des noms des routeurs (ce qui facilite beaucoup les discussions ultérieures) et des interfaces :

        TO THE INTERNET
      +--------------------+         Management network 192.168.173.0/28
      |SuperNet            |         +-------------
      |(upstream provider) |         |      
      +--------------------+         |      
             |                       |      
             | Serial0               | eth1 (.1)  
      +---------------+             +----------------+        
      | nelson        |             |    steve       |        
      |(cisco router) |             | (linux router) |        
      +---------------+             +----------------+                
         / |  | Ethernet0 (.65)            | eth0  (.68)           
        /  |  +----------------------------------------------      
       /   |                    Backbone  192.168.173.64/26
      PtP links                                             
     to customers            
      192.168.173.32/27           
        

  • Soyez factuel : donnez les commandes exactes que vous avez utilisées, les résultats exacts de ces commandes. Faites du copier/coller, pas de la traduction ou du résumé.

Introduction à BGP

BGP, (Border Gateway Protocol) est le protocole standard de l'Internet pour les interconnexions entre opérateurs[9]. Il fait partie de la famille des EGP (Exterior Gateway Protocol) dont il est aujourd'hui le seul membre.

BGP ne sert donc que si vous êtes vous-même opérateur, c'est-à-dire si vous avez votre propre politique de routage à l'extérieur de votre AS (Autonomous System). La connaissance de BGP est nécessaire si vous travaillez chez un opérateur ou bien si vous gérez un point d'échange entre opérateurs. Elle peut aussi aider à mieux comprendre le routage dans l'Internet mais ce cours se concentre sur l'aspect pratique, plus que sur une compréhension en profondeur.

Qu'est-ce qui différencie les protocoles EGP, comme BGP, des protocoles utilisés à l'intérieur des AS, les IGP (Interior Gateway Protocol) comme OSPF ? La différence essentielle n'est pas technique. Elle est administrative.

On n'utilise les IGP qu'à l'intérieur d'une entité (entreprise, association, etc), où des décisions (comme la suppression ou bien l'ajout d'une ligne) peuvent être prises par un service unique. Le but des IGP est donc de trouver la route la plus efficace, en faisant confiance aux autres routeurs.

Au contraire, les EGP comme BGP s'utilisent entre entités distinctes (et même souvent concurrentes). Il n'y a plus de possibilité de prendre une décision qui s'imposera à tous. On n'est souvent même pas prévenu de ce que vont faire les pairs avec lequels on parle BGP. En conséquence de quoi, les EGP reposent sur l'idée de méfiance : le but n'est pas de trouver la meilleure route mais au contraire d'empêcher les routeurs de choisir une route dont on ne voudrait pas.

Cette différence a de nombreuses conséquences pratiques. Par exemple, il n'y a aucun moyen en OSPF de dire que l'on veut envoyer des informations à tel routeur mais pas à tel autre. OSPF nécessite que tous les routeurs d'une zone aient la même base. Au contraire, cette capacité à filtrer l'information envoyée est une des fonctions les plus utilisées de BGP.

La définition d'un AS (Autonomous System) est donc administrative. Un AS, l'unité de routage pour BGP, est une entité où le pouvoir de décision est centralisé. Elle communique avec d'autres entités, ayant leurs propres AS et qui n'ont pas de relations hiérarchiques. Les autres entités sont parfois vos fournisseurs de connectivité, parfois vos clients, parfois des pairs mais, dans tous les cas, vous ne pouvez pas leur dicter leur politique de routage.

Avec les autres opérateurs, vous allez pouvoir échanger du trafic. Cela peut se faire sur plusieurs bases contractuelles différentes. On distingue en général le transit, où vous payez un fournisseur pour vous annoncer des routes (et pour acheminer ensuite votre trafic) du peering où la relation se fait entre pairs, entre (presque) égaux, et où il n'y a pas en général d'échange d'argent.

Outre votre AS, le monde est rempli d'autres opérateurs. Ils ne sont pas égaux entre eux. Le classement se fait en fonction de l'achat de transit qu'ils effectuent. Si un opérateur est suffisamment grand et a une envergure internationale, il n'achète plus du tout de transit : on parle de Tier-1. Tous les autres opérateurs, tout en ayant des clients et en échangeant avec leurs pairs, sont obligés d'acheter du transit pour combler les limites de leur réseau. Par exemple, un opérateur purement européen va devoir acheter du transit à un Tier-1 pour permettre à ses clients d'accèder au Japon ou au Brésil.

Quel matériel et logiciel choisir ?

BGP tourne aujourd'hui sur les routeurs de haut de gamme[10] ainsi que sur toute machine Unix.

L'inclinaison personnelle de l'auteur le porte vers les logiciels libres donc la majorité des exemples concerneront le couple Unix+Zebra avec lequel l'auteur a le plus d'expérience. (Zebra a désormais un successeur, Quagga, Zebra ne semblant plus maintenu.) Ce couple permet de faire du BGP avec un simple PC, et un Unix libre comme Debian ou bien FreeBSD.

Le système le plus utilisé pour les routeurs BGP est sans doute IOS (Internetwork Operating System) de Cisco. Les commandes sont très proches de celles de Zebra.

Les routeurs de Juniper, plus orientés vers le haut de gamme, ont un langage de commandes très différent.

Parmi les autres marques de routeurs BGP qui mettent beaucoup de documentations en ligne, citons Riverstone.

Petit rappel sur l'utilisation des routeurs IP

[Important]Important

Ce texte n'est qu'un rappel sommaire, ce cours nécessite une bonne connaissance des environnements utilisés. Par exemple, si votre routeur est une machine Unix, il faut connaitre le shell, le système des journaux, etc. Par exemple, lorsque j'écris "envoyez le signal HUP au démon", je considère acquis que vous savez envoyer un signal à un démon[11].

Quagga

Quagga est issu du programme Zebra, qui ne semble plus maintenu mais que vous trouverez encore fréquemment en production.

Quagga est composé de plusieurs démons qui acceptent chacun des connexions TCP. Vous pouvez donc utiliser telnet pour vous connecter à chaque démon et effectuer sa configuration[12].

Si cette connexion aux démons est très pratique pour déboguer ou surveiller un routeur, je ne la trouve pas efficace pour écrire ou modifier la configuration du routeur. Je recommande plutôt de modifier les fichiers de configuration avec un éditeur, ce qui permet d'utiliser un bon outil d'édition, de gérer les configurations avec CVS, de préserver les commentaires, etc.

L'emplacement des fichiers de configuration de Quagga dépend de votre Unix et de la manière dont Quagga a été compilé[13]. J'utiliserai les emplacements du système Debian. Tous les fichiers sont alors dans /etc/zebra. On trouve notamment :

  • zebra.conf, la configuration générale[14],

  • ospfd.conf, la configuration du protocole OSPF,

  • ospf6d.conf, la configuration du protocole OSPFv6,

  • bgpd.conf, la configuration du protocole BGP.

Normalement, sur Unix, une fois qu'on a modifié un fichier de configuration, on envoit le signal HUP au démon[15]. Dans certaines versions de Quagga, avec certains protocoles (notamment BGP), ce signal a des effets négatifs (comme de couper toutes les sessions BGP) ou nuls. Il est donc recommandé d'utiliser la démarche suivante pour changer la configuration.

  1. Tapez les commandes dans la fenêtre de la console du démon.

  2. Si elles sont acceptées et produisent bien le résultat attendu, copiez les commandes dans le fichier de configuration, avec les commentaires appropriés.

Une variante, surtout si on connait bien les commandes, est de les mettre dans le fichier d'abord, puis de copier/coller les nouvelles commandes dans la console.

Venons en maintenant à la console d'administration du démon. On l'atteint en faisant un telnet routeur démon[16]. Le nom du démon (ou, plus exactement, le port sur lequel il écoute) est zebra, ospfd, ospf6d ou bien bgp[17].

Une fois connecté à la console du démon, vous avez une invite (configurable) et vous pouvez taper des commandes :

monrouteur> show ip ospf route
	

Il n'est pas nécessaire de connaitre toutes ces commandes par coeur. La touche ? vous fera apparaitre une aide contextuelle[18]. Par exemple, si vous avez déjà tapé show ip ospf et que vous tapez un ?, vous avez la liste :

  border-routers  for this area
  database        Database summary
  interface       Interface information
  neighbor        Neighbor list
  route           OSPF routing table
  <cr>
	

des commandes valides à ce stade (<cr> signifie Carriage Return et désigne la touche Entrée).

Vous pouvez également compléter une commande en cours de saisie avec la touche Tabulation.

Ce mécanisme de console en ligne de commande se prête bien à l'automatisation. Par exemple, le programme Python suivant se connecte à un routeur pour afficher la liste des routes[19] :

from telnetlib import Telnet
tn = Telnet(router, 2601) # 2601 is the port of the Quagga console

def write_after_prompt (prompt, text):
    (index, match, read) = tn.expect([prompt], 4)
    if not match:
            raise "Text \"" + prompt + "\" not found"
    # Eat it
    tn.read_until(prompt, 0)
    tn.write(text + '\r\n')

write_after_prompt ("Password:", password)
write_after_prompt (prompt, 'terminal length 0')
write_after_prompt (prompt, 'show ip route')
	

Certaines commandes nécessitent plus de privilège, puisqu'elles modifient l'état du routeur. La commande enable permet de passer dans cet état privilégié. Par exemple, pour changer la configuration du routeur ou bien pour réinitialiser une session BGP, vous devrez être en mode enable.

IOS

[Important]Important

IOS est un logiciel commercial et il est donc recommandé de s'adresser au vendeur pour toute question.

Je suis bien conscient que le vendeur n'est souvent pas très efficace pour le support mais les partisans du logiciel commercial expliquent toujours que l'avantage de ce dernier est la qualité du support : c'est donc l'occasion de tester.

Le langage de commandes d'IOS a été largement imité et ne surprendra donc pas les utilisateurs de Quagga. Comme pour Unix, je recommande d'éditer les fichiers de configuration sur une machine qui puisse les gérer avec un outil comme CVS. Si on gère plusieurs routeurs, il est recommandé d'utiliser un outil comme COSI ou Rancid. Une fois le fichier édité, on peut le charger sur le Cisco avec configure network[20].

SNMP

SNMP (Simple Network Management Protocol) est un protocole de gestion de réseau. C'est une norme (RFC 1157 et RFC 2578) donc il fonctionnera quel que soit le type de vos routeurs. Vous trouverez énormément d'informations sur SNMP sur le Simple Web.

SNMP permet à un gérant (manager) d'interroger un agent (qui se trouve, dans notre cas, sur un routeur ou un commutateur) et d'obtenir des informations. Par exemple, ici, on utilise le gérant Net-SNMP sur Unix pour demander à un routeur combien il a d'interfaces[21], puis combien d'octets sont passés sur la première interface depuis le démarrage du routeur :

% snmpget 192.134.7.246 password interfaces.ifNumber.0
interfaces.ifNumber.0 = 5

% snmpget 192.134.7.246 password interfaces.ifTable.ifEntry.ifInOctets.1
interfaces.ifTable.ifEntry.ifInOctets.1 = Counter32: 34254759
	



[1] BGP nécessite certaines ressources virtuelles, mais rares comme des adresses IP et ne peut donc pas être à votre portée, même si vous souhaitez vous connecter à plusieurs opérateurs. Vous serez alors amenés à utiliser des bricolages plus ou moins propres (par exemple le source routing).

[2] Plus de détails sur l'adressage IPv4 dans RFC 791 (RFC signifie Request For Comments. Ce sont les textes fondamentaux de l'Internet. Toutes les normes Internet sont des RFC, l'inverse n'est pas forcément vrai. Tous les RFC sont librement disponibles en ligne sur le serveur de l'IETF, l'organisme qui les édite.).

[3] Plus de détails sur l'adressage IPv6 dans RFC 2373.

[4] qui nécessite l'option IP: advanced router

[5] Sur Unix, le noyau effectue le forwarding, alors que le routing est confié à un programme extérieur comme Quagga.

[6] Par exemple, en France, la liste IP ou bien en Afrique la liste d'AFNOG, destinée aux opérateurs mais qui voit en pratique beaucoup de questions de base sur IP.

[7] Et surtout pas de raisons de sécurité.

[8] Je fonde beaucoup d'espoirs sur SVG mais qui est très peu répandu encore.

[9] En toute rigueur, il faut signaler que certains gros clients, connectés à plusieurs opérateurs, utilisent également BGP.

[10] Sur les routeurs commerciaux, BGP peut ne pas faire partie de la licence de base et peut nécessiter l'achat d'une licence spéciale.

[11] man kill

[12] Il existe aussi un système, le vtysh pour se connecter de manière unifiée à tous les démons mais il n'est pas décrit ici.

[13] Rappelez-vous que Quagga se nommait Zebra précédemment et beaucoup de fichiers n'ont pas encore changé de nom.

[14] Ce fichier est vide la plupart du temps. Il contient des définitions d'interfaces et de routes statiques mais, sur Unix, on les fait typiquement en dehors de Quagga. Le noyau Unix informera ensuite Quagga. On ne remplit ce fichier que pour contourner des bogues du noyau (par exemple avec les adresses multicast sur NetBSD).

[15] Debian facilite le choses en créant pour chaque démon un script /etc/init.d/démon qui accepte toujours les mêmes options, comme reload pour recharger une configuration, ce qui permet de gérer de manière uniforme tous les démons, même ceux qui ne suivent pas parfaitement la convention. D'autres systèmes d'exploitation ont un mécanisme analogue, par exemple FreeBSD dans ses toutes dernières versions (5).

[16] telnet ne chiffrant pas les communications, il est très fortement recommandé de taper cette commande depuis le routeur lui-même, pour limiter les risques d'écoute.

[17] Si aucun de ces noms ne marche, par exemple si vous obtenez tcp/zebra: unknown service, c'est que ces noms n'ont pas été mis dans /etc/services. Là encore, il est recommandé d'utiliser un système de paquetages qui vous épargne ce genre d'oublis.

[18] C'est-à-dire que les commandes ou options affichées sont celles qui sont réellement disponibles à ce stade. C'est d'autant plus utile que les commandes ne sont pas les mêmes pour chaque démon.

[19] SNMP permet souvent la même chose.

[20] Il faudra avoir configuré un serveur TFTP avant.

[21] Cette information étant un scalaire, il faut terminer l'identificateur de l'objet SNMP par un 0. La seconde information est un vecteur, on termine l'identificateur par l'index.