---
layout: page
title: Wie werden BGP Routen ausgewählt aus und wie kann man dies beeinflussen?
permalink: /blog/bgp-route-selection-de/
keywords: bgp,bgp route selection,bird route selection,path prepending,multiple exit discriminator,med,routing route selection,bird,networking,network,dn42
description: Wie werden in BGP Routen ausgewählt? Wie kann man diese Auswahl beeinflussen? Hier erkläre ich die Kriterien sowie Möglichkeiten zur Manipulation wie Path Prepending, BGP local preference und Multiple Exit Discriminator (MED).
lang: de
date: 2023-03-05 00:00:00 +0100
feed: true
---

## Wie werden BGP Routen ausgewählt?

Folgendes sind Kriterien in bird:

1. Es wird die Route mit dem **höchsten** Gewicht präferiert. Dafür gibt es in bird den Wert `preference`. Dieser wird zum Beispiel zur Bevorzugung von IGP über EGP benutzt - so wird beispielsweise Babel über BGP bevorzugt.
2. Es wird die Route mit der **höchsten** lokalen Präferenz ausgewählt. Dies kann man im Import-Filter mit der Variable `bgp_local_pref` beeinflussen. Die Standardpräferenz ist 100.
3. Die Route mit dem **kürzesten** AS Pfad wird bevorzugt. Dies ist in allen Implementierungen ein entscheidenes Kriterium. Der Pfad gibt grundsätzlich (Ausnahme: Path Prepending) an, wie viele autonome Systeme durchquert werden müssen, um das Ziel zu erreichen.
4. Danach wird ein sehr selten benutzter Wert überprüft: der Ursprung. Über IGP empfangende Routen werden präferiert. In bird wird mittlerweile jedoch `preference` benutzt.
5. Falls man mehrere Peerings mit demselben autonomen System hat, wird der **kleinste**  Multiple Exit Discriminator (MED) bevorzugt. Falls man beispielsweise einmal dezidiert und einmal über einen IXP verbunden ist, so möchte man im Allgemeinen die dezidierte Leitung bevorzugen, da diese nicht geteilt werden muss. Daher bekommen Routen, welche darüber empfangen wurde, eine kleinere MED.
6. Routen, welche über eBGP empfangen werden, werden über Routen von iBGP bevorzugt. Dies bedeutet, bird neigt dazu, die Routen zu einem externen autonomen System zu benutzten, anstatt sie weiter in das eigene autonome System zu leiten.
7. Es werden Routen mit der **geringsten** internen Entfernung zu einem Boundary-Router bevorzugt. Es werden also die Routen bevorzugt, welche von Routern kommen, welche nach außen mit anderen autonomen System verbunden sind.
8. Es wird die Route vom Router mit der **niedrigsten** Router ID bevorzugt.

Man sollte jedoch beachten, dass die Kriterien Implementationsspezifisch sind. So sind die Kriterien und die Reihenfolge bei FRR beispielsweise teilweise anders.

## Wie kann man die Routen-Auswahl beeinflussen?

### Path Prepending

Path Prepending ist eine beliebte Taktik, um einen Weg unattraktiver zu machen. Wie man an den Kriterien oben sehen kann, wird die AS Pfad-Länge recht weit oben als Kriterium benutzt. Umso länger der AS-Pfad ist, umso unattraktiver die Route. Möchte man nun nicht, dass eine Route bevorzugt benutzt wird, kann man den AS-Pfad länger machen und damit die Route unattraktiver.
In der Praxis hängt man seine eigene AS-Nummer an den Pfad an. Dies bedeutet aber auch, dass Path Prepending erkennbar ist, welches in gut konfigurierten Systemen jedoch kein Problem darstellt. Um Path Prepending in bird durchzuführen, gibt es die Funktion `prepend`:
```bird
bgp_path.prepend(64500);
```
In diesem Code Abschnitt würde man zum Beispiel die AS Nummer `64500` an den Pfad angehängt (prependen). Dabei gibt das Argument *nicht* die Anzahl der Prepends, sondern die AS-Nummer, welche angehängt werden soll an. In anderen BGP Implementierungen, kann das Argument jedoch auch die Anzahl angeben!
In der Praxis verwendet man ein bis drei Prepends. Danach wird die Route so unattraktiv, dass sie so gut wie nicht mehr verwendet wird.
Path Prepending ist also - wenn richtig eingesetzt - ein starkes Mittel, um eine Route global unattraktiver zu machen. Path Prepending geht über das eigene und die benachbarten autonomen Systeme hinaus.

### BGP lokale Präferenz

Die lokale Präferenz ist ein sehr starkes Instrument - und könnte beinah als rohe Gewalt bezeichnet werden. Die AS Pfad-Länge oder anderen Kriterien werden nicht mehr überprüft, wenn eine einzige Route zum Ziel eine hohe Präferenz hat. Die lokale Präferenz sollte daher sorgfältig benutzt werden.
Eine gute Anwendungsmöglichkeit wäre, wenn man sicherstellen möchte, dass man Routen von einem benachbarten AS direkt zu diesem sendet.
```bird
if (bgp_path.len = 1) then
    bgp_local_pref = bgp_local_pref + 700;
```
Sollte die AS Pfad Länge eins sein, bedeutet dies, dass man direkt eine Route zum Ziel AS hat. Mit diesem Codeblock im Import-Filter kann man also erzwingen, dass diese direkte Route dann benutzt wird.

#### Warum nicht `bgp_path.first = bgp_path.last`?

Dies ist einer der Gründe, warum die lokale Präferenz so gefährlich sein kann. Sollte jemand seinen AS-Pfad absichtlich länger machen (Path Prepending), so möchte dieser jemand absichtlich erzielen, dass man eine andere Route wählt. Mit diesem Befehl würde man die Bemühungen wirkungslos machen.
Beispielsweise könnte man ein zwei Punkten mit einem AS gepeert sein. Nun ist eine Verbindung kurzweilig instabil und die andere weiterhin stabil. In der Zeit, wo die eine Verbindung instabil ist, soll die andere Verbindung bevorzugt werden - die instabile Verbindung soll allerdings nicht gekappt werden. Daher macht man mit Path Prepending die instabile Verbindung unattraktiver. Da die lokale Präferenz jedoch vor der AS Pfad-Länge überprüft wird, wird das Path Prepending ignoriert und die instabile Verbindung bevorzugt.

#### Man kann nicht unendlich weit sehen

Ein anderer Grund, warum man lokale Präferenzen vermeiden sollte ist, dass man nur die Verbindung zwischen sich und dem benachbarten AS bewerten kann - beispielsweise wie stabil die Verbindung ist oder welche Latenz vorliegt.
Beispiel: Es gibt drei autonome Systeme, welche alle drei miteinander verbunden sind. Die Verbindung zwischen AS A und AS B ist sehr gut. Die Verbindung zwischen AS A und AS C ist zufriendstellend. Die Verbindung zwischen AS B und AS C ist jedoch sehr schlecht. AS A möchte nun AS C erreichen. Die sinnvolle Route wäre, den direkten Weg von AS A zu AS C zu benutzen. Dort wäre die Route zufriedenstellend. AS A hat jedoch für alle Routen von AS B eine hohe lokale Präferenz eingerichtet, da die Verbindung zwischen diesen ASes sehr gut ist. Nach dem Route Selection Algorithmus, wird also die Route über AS B verwendet - AS A -> AS B -> AS C. Da die Verbindung zwischen AS B und AS C jedoch sehr schlecht ist, ist jetzt auch die Verbindung zwischen AS A und AS C sehr schlecht - besser wäre gewesen, wenn AS A eine direkte Verbindung zu AS C aufgebaut hätte, wie es ohne lokale Präferenz gewesen wäre.
Dieses Beispiel zeigt, dass man immer nur die Verbindung zu den benachbarten ASes einschätzen kann und nicht deren Verbindung zu anderen Systemen.

![Die Oben beschriebene Situation mit AS A, AS B und AS C als Diagramm dargestellt.](../../assets/img/bgp-route-selection/bgp-local-pref-is-evil.png)

#### Communities

In BGP gibt es Communities. So werden in dn42 beispielsweise BGP Communities verwendet, um Bandbreite, Latenz und Verschlüsselung zu übermitteln. Die Implementierung dieser Communities ist jedoch optional. Des Weiteren können und sollen die Communities von jedem AS auf dem Weg bearbeitet werden - so ist zum Beispiel die höchste Bandbreite von einer Route immer die vom Knoten des Pfades mit der geringsten Bandbreite. Dies wirft zwei Probleme auf: Es kann sein, dass ASes die Communities nicht implementieren und daher wichtige Informationen verloren gehen. Des Weiteren kann es sein, dass die Communities aufgrund einer Fehlkonfiguration falsch bearbeitet werden.
Darüber hinaus, würde es sicherheitstechnisch schlecht sein, die lokale Präferenz anhand der Communities festzumachen. Dann könnte ein bösartiger Akteur mithilfe der Communities "behaupten", er hätte eine sehr gute Verbindung zu allen Systemen. Dies würde dazu führen, dass die lokale Präferenz dafür sorgt, dass jede Route und damit auch der Traffic über den Angreifer geht.

## Multiple Exit Discriminator (MED)

Es kann vorkommen, dass zwei autonome Systeme über zwei oder mehr Verbindungen peeren. Ohne MED wird die Route vom Router mit der niedrigsten Router ID ausgewählt. Dies ist kein sinnvolles Auswahlkriterium, jedoch ist es deterministisch (es tritt bei den gleichen Bedingungen immer dasselbe Ergebnis auf). Nun kann man jeder Route ein MED zuweisen. Dabei wird der **kleinste** MED bevorzugt.
Beispiel: Zwei autonome Systeme AS A und AS B sind über zwei Verbindungen miteinander gepeert. Die eine Verbindung ist stabil und die andere instabil. Man möchte die instabile Verbindung jedoch als Backup beibehalten, da sie alternativ Route nicht besser wäre. Wenn man nun die stabile Verbindung bevorzugen möchte, kann man dort eine geringere MED setzen. Dies macht man in bird, indem man `bgp_med` auf den entsprechenden Wert setzt.

![Die Oben beschriebene Situation mit AS A und AS B als Diagramm dargestellt.](../../assets/img/bgp-route-selection/bgp-med-is-good.png)

## Router ID

Als letztes Vergleichskriterium wird von vielen BGP Implementierungen, darunter auch bird, die Router ID benutzt. Die Router ID wird im Normalfall als IPv4 dargestellt und dient zur eindeutigen Identifizierung eines Routers unter seinen Nachbarn. Dieses Entscheidungskriterium ist zwar deterministisch, jedoch wenig sinnvoll. In bird kann man dieses letzte Entscheidungskriterium dahingehend ändern, dass die Route nicht nach der Router ID, sondern nach der **ältesten** Route ausgesucht wird.
Um dieses alternative Entscheidungskriterium zu benutzten, benutzt man das Statement `prefer older on;` beim Setup seiner BGP Session. Das Statement wird in `protocol bgp` geschrieben und gilt dann für die gesamte BGP Session.


# Links

- [FRR BGP Route Selection](http://docs.frrouting.org/en/latest/bgp.html#route-selection)
- [Bird BGP](https://bird.network.cz/?get_doc&v=20&f=bird-6.html#ss6.3)
- [Bird Route Selection](https://bird.network.cz/?get_doc&v=20&f=bird-2.html#ss2.1)
- [BGP communities in dn42](https://dn42.dev/howto/Bird-communities)
