Phase 6 (bonus) : bird-lab, BGP+BFD entre namespaces (rtnetlink/Bird)

- Topologie en étoile : racine (AS 65000) en transit entre bird-a
  (AS 65010) et bird-b (AS 65011), namespaces créés par tripoli-netctl
  (Phase 4). Chaque feuille origine une route factice, jamais
  installée dans la table de routage réelle (export none partout) -
  labo pédagogique, ne pilote aucun trafic de production.
- Vérifié en conditions réelles : sessions BGP Established dans les
  deux sens, route de bird-b vue par bird-a avec next-hop = racine
  (transit confirmé, pas un peering direct), sessions BFD Up
  (200ms/200ms), coupure de lien détectée en < 5ms.
- Découverte : les namespaces n'ont aucun pare-feu propre, mais ufw
  côté racine bloquait le retour des paquets BFD (chaque bout envoie
  indépendamment, conntrack ne le reconnaît pas comme un flux BGP/TCP
  existant) - même schéma que Caddy -> tripoli-edge en Phase 2. Règle
  ufw ajoutée par run.sh, retirée par teardown.sh : rien de permanent.
- Pas de service systemd : labo lancé, vérifié, puis proprement démonté
  (processus Bird, namespaces et règle ufw temporaire tous supprimés).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-09-17 01:17:15 +02:00
parent db306433d5
commit 7802c59931
7 changed files with 269 additions and 1 deletions

47
bird-lab/run.sh Executable file
View file

@ -0,0 +1,47 @@
#!/usr/bin/env bash
# Labo BGP/BFD un-seul-poste : deux namespaces (bird-a, bird-b) créés par
# tripoli-netctl, chacun relié au namespace racine, trois instances Bird
# qui échangent des routes par BGP avec BFD pour la détection rapide de
# panne. Racine = AS 65000, transit entre bird-a (AS 65010) et bird-b
# (AS 65011) - une topologie en étoile, pas un maillage complet.
#
# À exécuter en root. Ne touche à AUCUN service de production : les
# routes échangées ici ne sont jamais installées dans la table de
# routage réelle du noyau (voir `export none;` dans chaque config).
set -euo pipefail
NETCTL=/opt/tripoli-src/target/debug/tripoli-netctl
CONFIG_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/config" && pwd)"
mkdir -p /var/log/bird-lab /run/bird-lab /etc/bird-lab
cp "$CONFIG_DIR"/*.conf /etc/bird-lab/
echo "--- création des namespaces (tripoli-netctl) ---"
"$NETCTL" create bird-a --subnet-id 10
"$NETCTL" create bird-b --subnet-id 11
# Les namespaces bird-a/bird-b n'ont aucun pare-feu (netfilter y est
# vierge - seul le namespace racine a une politique ufw), mais leurs
# paquets BFD, une fois arrivés côté racine, ne sont PAS reconnus comme
# le retour d'une connexion existante par conntrack (chaque bout envoie
# sur son propre port éphémère, ce n'est pas un flux TCP bidirectionnel
# comme BGP) : ufw les bloque par défaut, exactement comme il avait
# fallu une règle dédiée pour laisser Caddy joindre tripoli-edge en
# Phase 2. Règle temporaire, retirée par teardown.sh.
ufw allow from 10.200.0.0/16 to any port 3784 proto udp comment 'bird-lab : BFD (labo, temporaire)'
echo "--- démarrage des instances Bird ---"
bird -c /etc/bird-lab/root.conf -s /run/bird-lab/root.ctl
ip netns exec bird-a bird -c /etc/bird-lab/bird-a.conf -s /run/bird-lab/bird-a.ctl
ip netns exec bird-b bird -c /etc/bird-lab/bird-b.conf -s /run/bird-lab/bird-b.ctl
sleep 3
echo "--- sessions BGP (racine) ---"
birdc -s /run/bird-lab/root.ctl show protocols all bird_a
birdc -s /run/bird-lab/root.ctl show protocols all bird_b
echo "--- routes vues par bird-a (doit inclure 10.99.11.0/24, apprise via la racine) ---"
birdc -s /run/bird-lab/bird-a.ctl show route
echo "--- routes vues par bird-b (doit inclure 10.99.10.0/24, apprise via la racine) ---"
birdc -s /run/bird-lab/bird-b.ctl show route