BGP Bird – przydatne filtry #2

Kontynuując poradnik dotyczący demona BGP Bird, przyszedł czas na filtry do sterowania ruchem wychodzącym (export) z naszych routerów BGP.

Ponownie zacznę od filtra uniwersalnego, który będzie bazą dla pozostałych. Zaczniemy od rozgłoszenia naszych prefixów. Tworzymy statyczne routingi z parametrem reject (null w cisco) dla sieci które chcemy rozgłaszać. Dzięki temu cokolwiek wydarzy się na naszych routerach, to prefixy będą dostępne w tablicy routingu i rozgłaszane do upstreamów.

protocol static ISP {
  route 192.168.0.0/22 reject;
 }

Budujemy filtr, który rozgłosi nasz prefix:

filter ISP_OUT {
 if proto="ISP" then { accept; }
 reject;
 }

w konfiguracji sesji dodajemy parametr:

export filter ISP_OUT;

Najczęściej używanym dodatkowym parametrem jest z pewnością prepend, który pozwoli „pogorszyć” trasę do nas przez wydłużenie ścieżki AS. Prependy dodajemy powielając linijkę:

bgp_path.prepend(65555);

Przykład z 1x prepend:

filter ISP_OUT {
 bgp_path.prepend(65555);
 if proto="ISP" then { accept; }
 reject;
 }

Przykład z 3x prepend:

filter ISP_OUT {
 bgp_path.prepend(65555);
 bgp_path.prepend(65555);
 bgp_path.prepend(65555);
 if proto="ISP" then { accept; }
 reject;
 }

Efekt dla powyższego:

bird> show route export NMBGP2 all
 192.168.0.0/22   unreachable [ISP 2021-08-08 06:46:22] * (200)
     Type: static unicast univ
     BGP.origin: IGP
     BGP.as_path: 65555 65555 65555 65555
     BGP.next_hop: 10.0.10.1
     BGP.local_pref: 120

Teraz przykład użycia communities:

filter ISP_OUT {
 bgp_community.add((62047,666));
 bgp_path.prepend(65555);
 if proto="ISP" then { accept; }
 reject;
 }

Oraz ext-communities:

filter ISP_OUT {
 bgp_ext_community.add((rt,6939,65000));
 bgp_path.prepend(65555);
 if proto="ISP" then { accept; }
 reject;
 }

I efekt powyższego:

bird> show route export EPIX_RS1 all
     BGP.ext_community: (rt, 6939, 65000)

Inny ciekawy przykład filtra. Chcemy rozgłaszać do swojego peera tylko prefixy oznaczone własnymi communities, a konkretnie zakresem od 65555:200 do 65555:300:

filter RTR1_OUT {
  if ( bgp_community ~ [ (65555, 200..300) ] ) then accept;
  reject;
 }

Na koniec filtry pozwalające rozgłaszać prefixy do blackholingu. Dla statycznej konfiguracji:

Protocol static BH {
   route 192.168.1.100/32 reject;
 }

filter EPG_OUT {
 if proto="ISP" then { accept; }
 if proto="BH" then { bgp_community.add((50607,666));
          accept; }
 reject;
 }

Oraz dla konfiguracji w której mamy własny system do wykrywania ataków DDoS i atakowany prefix oznaczamy własnym community:

filter EPG_OUT {
 if  (proto="ANTYDDOS" && (64666,666) ~ bgp_community ) then  {
          bgp_community = -empty-;
          bgp_community.add((50607,666));
          accept;
 }
 if proto="ISP" then { accept; }
 reject;
 }

Myślę, że przybliżyłem nieco zasady budowania filtrów w Bird. Jak widać elastyczność jest bardzo duża i filtry o danej funkcjonalności można budować na kilka sposobów. Podane w tym i poprzednim wpisie przykłady, to tylko ułamek możliwości jakie daje Bird. Zachęcam do własnych testów.