No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
= Introduction = | |||
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 on a small-scale. We will work with the following subjects: | 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 on a small-scale. We will work with the following subjects: | ||
Line 7: | Line 7: | ||
* Aggregation | * Aggregation | ||
* Hijacking | * Hijacking | ||
* Anycast | |||
* DDoS migitation (s/RTBH) | * DDoS migitation (s/RTBH) | ||
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). | 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). | ||
== 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: | 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 working Debian system (either virtualized or bare-metal). Other distros will also work. | ||
* A direct connection to the network (no nat, no routed connections) | * 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 will receive a temporarily and private AS number and two private networks. During the workshop, we will create an "Internet" with these details. In order to register, ping r3boot on IRC or send an email to r3boot at r3blog dot nl, and I will add you to the list below: | |||
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 | |||
= Basic BGP operations = | |||
== 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 | |||
== 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 | |||
== 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; | |||
} | |||
== BGP 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 | |||
=== 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 | |||
= Advanced BGP tricks = | |||
== 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 | |||
== 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. | |||
Revision as of 15:09, 26 July 2024
Introduction
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 on a small-scale. We will work with the following subjects:
- Routing theory
- Setting up a peering
- Route leaks
- Aggregation
- Hijacking
- Anycast
- DDoS migitation (s/RTBH)
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).
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 will receive a temporarily and private AS number and two private networks. During the workshop, we will create an "Internet" with these details. In order to register, ping r3boot on IRC or send an email to r3boot at r3blog dot nl, and I will add you to the list below:
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
Basic BGP operations
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
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
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; }
BGP 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
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
Advanced BGP tricks
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
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.