Login Logout

Howto OpenBGPD

Documentation

BGP est un protocole de routage, permettant d’échanger des routes entre les opérateurs pour… constituer Internet. On peut faire tourner un routeur BGP sous BSD (OpenBGPD), Linux (Quagga), Cisco, Juniper, etc.

Liens utiles

Configuration

OpenBGPD fait partie du système de base, il est donc présent par défaut sous OpenBSD. On le configure via le fichier /etc/bgpd.conf.

Pour lancer bgpd(8) en mode « verbeux » :

# bgpd -d
# bgpctl log verbose

Pour lancer définitivement :

# rcctl enable bgpd
# rcctl start bgpd

Pour examiner sa configuration « optimisée » :

# bgpd -nv | less

En production

On vérifie la configuration et si c’est ok, on reload :

# bgpd -n && bgpctl reload

Exemple de configuration « pour jouer »

Prenons 2 machines, que l’on définit comme étant 2 routeurs pour 2 opérateurs différents, annonçant chacun un préfixe (ou bloc d’adresses).

Voici le bgpd.conf sur le routeur avec l’adresse IP 10.0.0.2 :

AS 65001
router-id 10.0.0.2
listen on 10.0.0.2
holdtime 180
holdtime min 3
fib-update yes
network 192.0.32.0/24

group "peering AS65002" {
        remote-as 65002
        neighbor 10.0.0.3 {
                descr   "AS 65002 peer 1"
                announce all
                tcp md5sig password mekmitasdigoat
        }
}

deny from any
allow from any inet prefixlen 8 - 24

Et voici le bgpd.conf sur le routeur avec l’adresse IP 10.0.0.3 :

AS 65002
router-id 10.0.0.3
listen on 10.0.0.3
holdtime 180
holdtime min 3
fib-update yes
network 192.0.33.0/24

group "peering AS65001" {
        remote-as 65001
        neighbor 10.0.0.2 {
                descr   "AS 65001 peer 1"
                announce all
                tcp md5sig password mekmitasdigoat
        }
}

deny from any
allow from any inet prefixlen 8 - 24

Utilisation (observer)

Pour voir les réseaux annoncés

# bgpctl network show

Voir un résumé concernant les sessions configurées

# bgpctl show
Neighbor                   AS    MsgRcvd    MsgSent  OutQ Up/Down  State/PrfRcvd
AS 65001 peer 1         65001         18         18     0 00:13:18      1

Voir un résumé des informations relatives aux voisins

# bgpctl show neighbor
BGP neighbor is 10.0.0.2, remote AS 65001
 Description: AS 65001 peer 1
  BGP version 4, remote router-id 10.0.0.2
  BGP state = Established, up for 00:13:40
  Last read 00:00:41, holdtime 180s, keepalive interval 60s
  Neighbor capabilities:
    Multiprotocol extensions: IPv4 unicast
    Route Refresh
    4-byte AS numbers

  Message statistics:
                  Sent       Received  
  Opens                    2          2
  Notifications            0          1
  Updates                  1          1
  Keepalives              15         14
  Route Refresh            0          0
  Total                   18         18

  Update statistics:
                  Sent       Received  
  Updates                  4          1
  Withdraws                0          0

  Local host:              10.0.0.3, Local port:    179
  Remote host:             10.0.0.2, Remote port: 40598

Voir la FIB (Forwarding Information Base) IPv4

# bgpctl show fib ipv4
flags: * = valid, B = BGP, C = Connected, S = Static
       N = BGP Nexthop reachable via this route
       r = reject route, b = blackhole route

flags prio destination          gateway
*S       8 0.0.0.0/0            10.0.0.1
*CN      4 10.0.0.0/24          link#1
*C       0 127.0.0.0/8          link#0
*S r     8 127.0.0.0/8          127.0.0.1
*        4 127.0.0.1/32         127.0.0.1
*B      48 192.0.33.0/24        10.0.0.3
*S r     8 224.0.0.0/4          127.0.0.1

On notera principalement la présence de la ligne \*B 48 192.0.33.0/24 10.0.0.3 qui signifie la présence de cette route grâce à BGP. On voit donc que l’on peut joindre un IP du réseau 192.0.33.0/24 via 10.0.0.3 :

# route get 192.0.33.1
   route to: 33-1.lax.icann.org
destination: 192.0.33.0
       mask: 255.255.255.0
    gateway: 10.0.0.3
  interface: em0
 if address: routeur0
   priority: 48 (bgp)
      flags: <UP,GATEWAY,DONE>
     use       mtu    expire
       0         0         0

Voir la RIB (Routing Information Base)

# bgpctl show rib
flags: * = Valid, > = Selected, I = via IBGP, A = Announced
origin: i = IGP, e = EGP, ? = Incomplete

flags destination          gateway          lpref   med aspath origin
AI*>  192.0.32.0/24        0.0.0.0            100     0 i
*>    192.0.33.0/24        10.0.0.3           100     0 65002 i

Voir l’utilisation de la mémoire (et le nombre de routes dans la RIB)

# bgpctl show rib memory
RDE memory statistics
    620348 IPv4 unicast network entries using 23.7M of memory
     35457 IPv6 unicast network entries using 1.9M of memory
   1311354 rib entries using 80.0M of memory
   3117006 prefix entries using 190M of memory
    585678 BGP path attribute entries using 67.0M of memory
    184244 BGP AS-PATH attribute entries using 8.7M of memory,
           and holding 585678 references
     27293 BGP attributes entries using 1.0M of memory
           and holding 640852 references
     27292 BGP attributes using 615K of memory
RIB using 373M of memory

Voir les préfixes annoncés par un voisin

# bgpctl show rib neighbor "AS 65001 peer 1" in

Voir le détail concernant le routage vers une IP

# bgpctl show rib detail 1.2.3.4

BGP routing table entry for 1.2.0.0/19
    65002 43100 1234
    Nexthop 192.0.34.1 (via 192.0.34.1) from AS 65002 peer 1 (192.0.35.254)
    Origin IGP, metric 0, localpref 100, external, valid, best
    Last update: 06:04:53 ago
    Communities: 65002:6600

Utilisation (agir)

Faire une modification à chaud pour privilégier un opérateur en sortie

On modifie les paramètres associés aux neighbors, par exemple :

set metric 1
set localpref 120

Puis on recharge le démon :

# bgpctl reload
reload request sent.
request processed

On pourra ensuite constater les changements en examinant la table de routage via bgpctl show rib

Faire une modification à chaud pour privilégier un opérateur en entrée

C’est beaucoup plus délicat car on ne peut qu’influencer/aimanter le trafic entrant. Et si un opérateur a des règles de son côté également (localpref), on peut ne pas pouvoir influencer le trafic… sauf arrêter d’annoncer sur l’opérateur à ne pas privilégier !!

La méthode la plus classique est de faire du prepend (augmenter artificiellement le nombre de saut de routeurs).

Cela se positionne soit dans son annonce de réseau (network XXXX set {}) mais alors global… ou de façon plus précise dans des règles match to.

Exemple d’une règle qui prepend un transit BGP :

match to <IP peer> set { prepend-self 1 }
match from <IP peer> set { prepend-neighbor 3 }

Puis on recharge le démon :

# bgpctl reload
reload request sent.
request processed

On pourra ensuite constater les changements via bgpd -nv.

Basculer à chaud une route (en sortie) vers un préfixe via un autre opérateur

On ajoute une règle du type :

match from <IP peer> prefix <préfixe> set localpref 200
match from <IP peer> AS <AS number> set localpref 200

Ici on souhaite sortir via <IP peer> pour joindre l'AS <AS number>

Puis on recharge le démon :

# bgpctl reload

Faire des modifications à chaud sur ses préfixes annoncés

Pour ses propres préfixes, les modifications ne sont pas prises en compte à chaud par bgpctl reload (Note : à voir si ce n’est pas corrigé maintenant !). Il faut donc, en plus de la configuration, les modifier à chaud :

# bgpctl network add 192.0.32.0/24 localpref 120 community 65002:6004
request sent.

# bgpctl network add 192.0.32.0/24 localpref 120
request sent.

Supprimer à chaud un réseau annoncé

Dans le cas de multi-homing (ou autre ?), on peut voir stopper l’annonce d’un préfixe :

# bgpctl network delete 192.10.32.0/24
request sent.

Désactiver / réactiver un transit/peer

En cas de souci avec un « voisin », on peut complètement le désactiver à chaud :

# bgpctl neighbor "Foo peer v4" down
request processed

# bgpctl neighbor show | grep Foo
Foo peer v4              1234     760965      16283     0 00:00:26 Idle

Pour le réactiver :

# bgpctl neighbor "Foo peer v4" up
request processed

Utiliser RTBH (Remote triggered blackhole)

En cas d’attaque DDoS sur une IP, on peut utiliser le RTBH (RFC 3882)

On pourra alors annoncer un préfix /32, via une communauté BGP, à bloquer en amont. Considérons l’IP 192.0.33.10 attaquée. L’idée ici est de pouvoir annoncer au routeur de l’AS 65001 de rediriger tout le trafic à destination de la cible vers un trou noir.

Sur la machine avec l’adresse IP 10.0.0.2, on crée une règle avec une communauté BGP de notre choix assignée au blackhole dans bgpd.conf

allow from group "peering AS65002" community 65001:666 prefixlen = 32 set nexthop blackhole

puis on recharge la configuration:

# bgpctl reload

Sur la machine avec l’adresse IP 10.0.0.3, on blackhole l’IP ciblée par l’attaque

# bgpctl network add 192.0.33.10/32 community 65001:666

Après l’attaque on supprime l’annonce

# bgpctl network delete 192.0.33.10/32 community 65001:666

Remonter une sessions après avoir atteint la limite max-prefix

Il est nécessaire de rajouter des directives max-prefix afin qu’OpenBGPD coupe automatiquement la session en cas de fuite d’un peer. Il est intéressant d’augmenter régulièrement la limite afin que la session ne soit jamais coupée.

Si une session est coupée il suffit d’augmenter la valeur max-prefix pour le peer en question. Puis on reload la configuration

# bgpd -nf /etc/bgpd.conf
# bgpctl reload

Cela ne suffit pas, il faut manuellement couper et remonter la session en question

bgplg : Looking Glass

On ajoute à la configuration d’OpenBGPD :

socket "/var/www/logs/bgpd.rsock" restricted

on recharge le démon :

# bgpctl reload

puis on ajoute les droits pour les binaires nécessaires :

# chmod 555 /var/www/cgi-bin/bgplg
# chmod 555 /var/www/bin/bgpctl
# mkdir /var/www/etc
# cp /etc/resolv.conf /var/www/etc

Et on configure httpd(8) via /etc/httpd.conf

ext_addr="0.0.0.0"

server "lg.example.net" {
	listen on $ext_addr port 80
	location "/cgi-bin/*" {
		fastcgi
		root ""
	}
}

On active et démarre les démons httpd(8) et slowcgi(8) :

# rcctl enable httpd
# rcctl start httpd
# rcctl enable slowcgi
# rcctl start slowcgi

Looking glass utiles

Bonus : peering