Présentation d’un point d’échange
Sur Internet, il y a globalement deux façons de parler aux autres
opérateurs : soit en passant par du peering, soit en passant par un
transitaire.
Un transitaire est un opérateur branché à beaucoup de monde qui se charge
d’acheminer nos paquets vers le reste d’Internet et de relayer nos
annonces BGP. Le contrat que l’on passe avec ce type d’opérateur est très
généralement payant.
Un peering est un contrat entre deux opérateurs permettant de
s’échanger du trafic entre eux (et éventuellement leurs clients), mais
seulement. Bien que l’on atteint beaucoup moins de monde avec cette session
BGP, l’intérêt est que ce type de contrat est très généralement gratuit
pour les deux parties (si on oublie les frais annexes, comme la
cross-connection). Pour que cela soit possible, ils faut que les deux
opérateurs aient un câble entre eux. Comme il est très compliqué de se
brancher avec tout le monde, il est très courant de voir des structure se
chargeant de brancher beaucoup de monde entre eux, c’est que l’on appelle
un point d’échange internet, souvent abrégé en IX ou IXP pour Internet
eXchange Point.
Mais là, nous rencontrons un autre problème, le nombre de sessions BGP pour que tout le monde s’échange des routes. Soit on a un serveur de routes central, qui reçoit les annonces de tout le monde et les redistribue, ce qui permet à chaque participant à l’IX de ne monter une session BGP qu’avec le serveur de routes. Soit, il faudra que chaque participant monte une session avec chaque autre ; dans ce cas le nombre de sessions augmente au carré du nombre de participants, ce n’est pas envisageable sur le long terme.
Notez bien que je ne parle ici que du serveur de routes, quand on en arrive là, c’est que l’on a déjà reçu ses ressources RIPE afin d’adresser votre LAN d’interconnexion et surtout que l’on a du monde à brancher.
Notre serveur de route avec bird
Ici, bird ne va servir qu’à recevoir des routes et à les redistribuer, il
est complètement inutile de les installer dans la table de routage du
kernel. Un serveur de route n’est pas un routeur.
Toute la configuration de bird se fait dans /etc/bird.conf
en IPv4 et dans /etc/bird6.conf
. Cette configuration est tirée
de ce que j’ai fait pour BreizhIX,
l’ASN est 206165, le range IPv4 est 185.1.89.0/24 et le range IPv6 est
2001:7f8:b1::/64.
Configuration globale
Ici, c’est ce que nous retrouvons dans quasi toutes les configurations bird.
# Configure logging
log syslog { warning, error, fatal, bug };
# Turn on global debugging of all protocols
# debug protocols all;
# Override router ID and store ASN
router id 185.1.89.1;
define myasn = 206165;
#####################
# GENERAL PROTOCOLS #
#####################
# This pseudo-protocol watches all interface up/down events.
protocol device {
# Scan interfaces every 5 seconds
scan time 5;
}
Fonctions pour les filtres
Ces fonctions seront utilisées plus tard afin de filtrer les préfixes reçus par chaque pair BGP.
function check_import(int peeras; ip nexthop)
prefix set martians;
int set reserved_asn;
prefix set our_prefixes;
{
martians = [ 10.0.0.0/8+, 100.64.0.0/10+,
127.0.0.0/8+, 169.254.0.0/16+, 172.16.0.0/12+,
192.0.0.0/24+, 192.0.2.0/24+, 192.168.0.0/16+,
198.18.0.0/15+, 198.51.100.0/24+, 203.0.113.0/24+,
224.0.0.0/4+, 240.0.0.0/4+, 255.255.255.255/32 ];
reserved_asn = [ 0, 64297..131071, 4200000000..4294967294, 4294967295 ];
# Avoid too short and too long prefixes
if (net.len < 8) || (net.len > 24) then return false;
# Avoid 0.0.0.0/X (default route + 0.0.0.0/8)
if net.ip = 0.0.0.0 then return false;
# Avoid reserved networks
if net ~ martians then return false;
# Remove our prefixes. Only us can announce them
# Remove also our interconnection prefixes. We are directly connected.
if net ~ 185.1.89.0/24 then return false;
# Check that the next AS is our neighbour's.
# Same for next-hop
if bgp_path.first != peeras then return false;
if bgp_next_hop != nexthop then return false;
# AS_PATH too long (2 because a member could re-annonce its clients on the
# IXP)
if bgp_path.len > 2 then return false;
# Don't accept if path contains a reserved AS
# Disabled because it removes legit prefixes
# if bgp_path ~ reserved_asn then return false;
return true;
}
# In; each prefix annonced by peer
# Out: prefixes specified (drop all the rest)
function bgp_filter_customer_in (prefix set customer_prefix) {
return (net ~ customer_prefix);
}
Gabarit de configuration
Ce bout de configuration nous évitera de le répéter pour chaque pair alors
qu’il ne changera jamais.
Ce qui change par rapport à un pair BGP classique est le rs
client
qui indique à bird de ne pas insérer l’ASN du pair dans l’AS
path lors de l’export de la route à un autre pair.
template bgp PEERS {
local as myasn;
import keep filtered;
import all;
export all;
import limit 100 action restart;
rs client;
source address 185.1.89.1;
}
Définition des pairs
Je ne prends qu’un routeur de grifon en exemple, mais nous retrouvons une configuration de ce type pour chaque pair. L’ASN est 204092, l’IP d’interconnexion est 185.1.89.10 et le réseau annoncé est 89.234.186.0/24.
filter bgp_filter_grifon_nominoe_in {
if (check_import(204092, 185.1.89.10) &&
bgp_filter_customer_in([ 89.234.186.0/24 ])) then {
accept;
} else {
reject "Prefix filtered for Grifon";
}
}
protocol bgp bgp_grifon_nominoe from PEERS {
description "Grifon nominoe";
neighbor 185.1.89.10 as 204092;
import filter bgp_filter_grifon_nominoe_in;
}
Résultat final
De cette façon, nous avons bien un échange de route entre les pairs, sans les installer dans notre noyau.
panoramix ~ # birdc sh pr all
BIRD 1.6.3 ready.
name proto table state since info
device1 Device master up 2017-03-19
Preference: 240
Input filter: ACCEPT
Output filter: REJECT
Routes: 0 imported, 0 exported, 0 preferred
Route change stats: received rejected filtered ignored accepted
Import updates: 0 0 0 0 0
Import withdraws: 0 0 --- 0 0
Export updates: 0 0 0 --- 0
Export withdraws: 0 --- --- --- 0
bgp_awedia BGP master up 19:32:18 Established
Description: awedia
Preference: 100
Input filter: ACCEPT
Output filter: ACCEPT
Import limit: 100
Action: restart
Routes: 2 imported, 0 filtered, 1 exported, 2 preferred
Route change stats: received rejected filtered ignored accepted
Import updates: 4 0 0 2 2
Import withdraws: 0 0 --- 0 0
Export updates: 3 2 0 --- 1
Export withdraws: 0 --- --- --- 0
BGP state: Established
Neighbor address: 185.1.89.11
Neighbor AS: 61198
Neighbor ID: 89.234.151.5
Neighbor caps: refresh AS4
Session: external route-server AS4
Source address: 185.1.89.1
Route limit: 2/100
Hold timer: 153/180
Keepalive timer: 50/60
bgp_grifon_nominoe BGP master up 2017-03-19 Established
Description: Grifon nominoe
Preference: 100
Input filter: bgp_filter_grifon_nominoe_in
Output filter: ACCEPT
Import limit: 100
Action: restart
Routes: 1 imported, 0 filtered, 3 exported, 0 preferred
Route change stats: received rejected filtered ignored accepted
Import updates: 3 0 1 0 2
Import withdraws: 1262772 0 --- 1262772 1
Export updates: 15 1 0 --- 14
Export withdraws: 9 --- --- --- 9
BGP state: Established
Neighbor address: 185.1.89.10
Neighbor AS: 204092
Neighbor ID: 89.234.186.7
Neighbor caps: refresh enhanced-refresh restart-aware AS4
Session: external route-server AS4
Source address: 185.1.89.1
Route limit: 1/100
Hold timer: 205/240
Keepalive timer: 44/80
bgp_grifon_budic BGP master up 2017-03-19 Established
Description: Grifon budic
Preference: 100
Input filter: bgp_filter_grifon_budic_in
Output filter: ACCEPT
Import limit: 100
Action: restart
Routes: 1 imported, 0 filtered, 2 exported, 1 preferred
Route change stats: received rejected filtered ignored accepted
Import updates: 3 0 0 0 3
Import withdraws: 1262752 0 --- 1262752 0
Export updates: 9 3 0 --- 6
Export withdraws: 4 --- --- --- 4
BGP state: Established
Neighbor address: 185.1.89.13
Neighbor AS: 204092
Neighbor ID: 89.234.186.6
Neighbor caps: refresh enhanced-refresh restart-aware AS4
Session: external route-server AS4
Source address: 185.1.89.1
Route limit: 1/100
Hold timer: 164/240
Keepalive timer: 30/80
panoramix ~ # birdc sh route all
BIRD 1.6.3 ready.
154.43.33.0/24 via 185.1.89.11 on eth2 [bgp_awedia 19:32:18] * (100) [AS61198i]
Type: BGP unicast univ
BGP.origin: IGP
BGP.as_path: 61198
BGP.next_hop: 185.1.89.11
BGP.local_pref: 100
89.234.186.0/24 via 185.1.89.13 on eth2 [bgp_grifon_budic 19:06:23] * (100) [AS204092i]
Type: BGP unicast univ
BGP.origin: IGP
BGP.as_path: 204092
BGP.next_hop: 185.1.89.13
BGP.local_pref: 100
via 185.1.89.10 on eth2 [bgp_grifon_nominoe 19:04:29] (100) [AS204092i]
Type: BGP unicast univ
BGP.origin: IGP
BGP.as_path: 204092
BGP.next_hop: 185.1.89.10
BGP.local_pref: 100
89.234.151.0/24 via 185.1.89.11 on eth2 [bgp_awedia 19:32:18] * (100) [AS61198i]
Type: BGP unicast univ
BGP.origin: IGP
BGP.as_path: 61198
BGP.next_hop: 185.1.89.11
BGP.local_pref: 100
panoramix ~ # ip route list
default via 89.234.186.209 dev eth0 metric 2
89.234.186.208/28 dev eth0 proto kernel scope link src 89.234.186.213
172.16.0.0/24 dev eth3 proto kernel scope link src 172.16.0.2
185.1.89.0/24 dev eth2 proto kernel scope link src 185.1.89.1
Et vu du côté d’un participant à l’IX, nous allons bien voir l’autre participant directement, sans avoir l’ASN de l’IX dans notre chemin :
alarig@nominoe:~ % birdc show route all protocol bgp_breizhix
BIRD 1.5.0 ready.
154.43.33.0/24 via 185.1.89.11 on em0.22 [bgp_breizhix 19:33:49 from 185.1.89.1] * (100) [AS61198i]
Type: BGP unicast univ
BGP.origin: IGP
BGP.as_path: 61198
BGP.next_hop: 185.1.89.11
BGP.local_pref: 100
89.234.151.0/24 via 185.1.89.11 on em0.22 [bgp_breizhix 19:33:49 from 185.1.89.1] * (100) [AS61198i]
Type: BGP unicast univ
BGP.origin: IGP
BGP.as_path: 61198
BGP.next_hop: 185.1.89.11
BGP.local_pref: 100