BGP Workshop

From Haxogreen 2024 Wiki

Ever wondered how to use the protocol that binds the internet together? This workshop will help you understand the basics of BGP, by performing a number of tasks with BGP. The workshop is divided into two parts; In the first part, we will be building a demonstration network in which we will apply the basic configuration to get a working BGP network. Using this knowledge (and assuming you know how to configure point-to-point VPN tunnels), you can setup fully routed private networks that are vendor / device / OS agnostic. The second part of the workshop is optional, and will discuss some practical applications that are built on top of, namely Anycast and DDoS migitation using remotely triggered blackhole routing.

  1. Basics
    1. Routing theory
    2. Setting up a peering
    3. Filtering
    4. Aggregation
    5. Hijacking
  1. Advanced
    1. Anycast
    2. DDoS migitation

Assumed is that you have an understanding of Linux and the basics of networking (what is an ip, what is a subnet, what is a router, what is a switch). While the workshop is designed around Linux/BIRD, the concepts that we will be working with apply to all devices that are able to talk, configure policies/access lists and can speak BGP, or most other routing protocols.

Expectations

This workshop will NOT be about internet routing. It will discuss the BGP protocol using a bunch of examples that can be applied to anything that runs BGP. These techniques can be applied on your LAN and over VPN tunnels.

Requirements

In order to participate in this workshop, you need to have the following:

  • A working Debian system (either virtualized or bare-metal). Other distros will also work.
  • A direct connection to the network (no nat, no routed connections)
  • BIRD version 2.x, bash, netcat, ping, iproute2

Registration

Every participant of the workshop needs their own AS number and a prefix. Either add your details to the sheet below, or ask r3boot to add you.

https://docs.nurd.space/sheet/#/2/sheet/edit/IacR4-gLFoetuyrli3JBhIMB/

Workshop

Setting up your local networks

Create the two networks using iproute2:

ip link add type dummy
ip link add type dummy

ip addr add 192.168.0.1/24 dev dummy0
ip addr add 192.168.1.1/24 dev dummy1

ip link set dummy0 up
ip link set dummy1 up

Enable ip forwarding

sysctl -w net.ipv4.ip_forward=1


Setup initial configuration of BIRD

Configure BIRD to read network prefixes from all dummy devices. Do this by editing `/etc/bird/bird.conf`. Replace the current content with the content below. Be sure to replace X.X.X.X with your ip address.

router id X.X.X.X;

protocol device { }

protocol direct {
	ipv4;
	interface "dummy*";
}

protocol kernel {
	ipv4 {
	      export all;
	};
}


Load and check setup

birdc configure
birdc show route

A correctly configured BIRD will show a routing table that looks like the one below:

BIRD 2.0.12 ready.
Table master4:
192.168.0.0/24       unicast [direct1 13:48:13.162] * (240)
	dev dummy0
192.168.1.0/24       unicast [direct1 13:48:18.015] * (240)
	dev dummy1


Doublecheck that BIRD is exporting routes to the kernel using ip route show protocol bird. It should look like the following:

192.168.0.0/24 dev dummy0 proto bird scope link metric 32
192.168.1.0/24 dev dummy1 proto bird scope link metric 32

1) Basic BGP operations

1.1) Setting up your first BGP peering(s)

For each participant you want to setup a peering for, configure a block like below. Replace X.X.X.X and AAAAA with your own details. Replace Y.Y.Y.Y and BBBBB with the details that are used by your peer. Add a descriptive name for PEERNAME.

protocol bgp PEERNAME {
	local X.X.X.X as AAAAA;
	neighbor Y.Y.Y.Y as BBBBB;

	ipv4 {
		import all;
		export all;
	};
}


Once the peer configuration is added, load the configuration, and doublecheck if the peering is established.

birdc configure
birdc show protocols
birdc show route
ip route show protocol bird

1.2) Filtering

Modify the configuration and add an export filter for each peer.

filter export_to_PEERNAME {
        if net ~ [ 192.168.0.0/23{23,24} ] then accept;
        reject;
}


Next, configure the peer to use the filters for both importing and exporting routes:

protocol bgp alita {
        [...]

        ipv4 {
                import all;
                export filter export_to_alita;
        };
}

Once you are done, reload the configuration and check your routes again

birdc configure
birdc show route
ip route show protocol bird

1.3) Aggregation

Setup a static route which contains both your subnets. Configure the subnet to send host unreachables whenever an ip does not respond to ARP requests.

protocol static my_network {
        ipv4;
        route 192.168.0.0/23 unreachable;
}


Tighten your export filter for all your peerings so that you only send your aggregated network:

filter export_to_alita {
        if net ~ [ 192.168.0.0/23 ] then accept;
        reject;
}


1.4) Hijacking

Configure an extra dummy interface that is configured with an IP address belonging to some peer:

ip link add type dummy
ip addr add 192.168.2.66/32 dev dummy2
ip link set dummy2 up


Modify your export filters to send the hijacked prefix:

filter export_to_alita {
        if net ~ [ 192.168.0.0/23 ] then accept;
        if net ~ [ 192.168.2.66/32 ] then accept;
        reject;
}


Reload the configuration, and validate that the new route is set:

birdc configure
birdc show route
ip route show protocol bgp

1.4.1) Preventing BGP hijacking

Modify the import filter for your peer to only accept prefixes that belong to your peer, and use this filter to select routes imported from your peer:

filter import_from_alita {
        if net ~ [ 192.168.6.0/23 ] then accept;
        reject;
}

protocol bgp alita {
        [...]

        ipv4 {
                import filter import_from_alita;
                export filter export_to_alita;
        };
}

Next, reload the configuration, restart the BGP peering and check the routing tables:

birdc configure
birdc restart alita
birdc show route


Once you are done with this excercise, remove the dummy interface you used for hijacking.

ip link del dummy2

2) Advanced BGP tricks

2.1) BGP Anycast

Configure a loopback interface for your service

ip link add type dummy


Configure a health check which manages the anycast ip.


#!/usr/bin/env bash

INTERFACE='dummy2'
IP='192.168.0.42'

while :; do
    if nc -w1 -nz 127.0.0.1 22; then
        ip addr add ${IP}/32 dev ${INTERFACE} 2>/dev/null
    else
        ip addr flush dev ${INTERFACE}
    fi
    sleep 1
done

Now start or stop your service. Notice that bird will advertise the service once second after the service starts listening on its port, and stops advertising the address as soon as you stop the service.

Be sure to tear down the dummy2 interface once you are done, since the next example is incompatible with it.

ip link del dummy2

2.2) DDoS migitation using s/RTBH

Modify your export filter(s) so that a BGP community gets added whenever BIRD finds a single ip address belonging to your ip space:

filter export_to_alita {
   if net ~ [ 192.168.0.0/23{32,32} ] then
        bgp_community.add((65000,42));
        accept;
    fi

    if net ~ [ 192.168.0.0/23 ] then accept;

    reject;
}


Modify the import filter of your peers to reject a prefix as soon as it finds the migitation community

filter import_from_alita {
    if ( net ~ [ 192.168.6.0/23{32,32} ] && (65003,42) ~ bgp_community) then {
        dest = RTD_UNREACHABLE;
        accept;
   }

    if net ~ [ 192.168.6.0/23 ] then accept;

    reject;
}

Reload your configuration. Notice that nothing will change, since you have not tagged any prefix with the migitation community.

Now, pick an ip address within your range, and ask one of your peers to run a ping towards this ip.

To activate the migitation, add a static route for an ip address you want to protect, and reload your configuration:

protocol static my_network {
        [...]

        route 192.168.1.1/32 blackhole;
}

To deactivate the migitation, remove the static route and reload your configuration.