add bird configuration

Signed-off-by: Marek Küthe <m.k@mk16.de>
This commit is contained in:
Marek Küthe 2023-01-01 18:13:15 +01:00
parent 15e993248a
commit b3ad6f77f9
No known key found for this signature in database
GPG Key ID: 7E869146699108C7
2 changed files with 278 additions and 2 deletions

View File

@ -1,5 +1,4 @@
Configuring Bird2
=================
# Configuring Bird2
We now need to configure the routing daemon for your router which will allow you to
exchange routes with other routers over the tunnels you will setup later. This is at
@ -16,6 +15,10 @@ differs slightly but we recommend (and for the rest of this document we will be)
Bird 2 as it comes with many bug fixes and improvements and most distributions (including Debian)
now have support for it.
## Alternative bird configuration
A guide to an alternative configuration with similar functionality can be found at [here](bird_alternative).
## Installation
In order to install the BIRD daemon on your machine you should look for a package named `bird2` or something

View File

@ -0,0 +1,273 @@
# Alternative bird configuration
This is an alternative bird configuration.
Due to the low complexity of the CRXN network, all configuration data is written to a file. It is also possible to split them into several files.
## Configuration
```
define OWNIP = <OWNIP>;
define OWNNET = <OWNNET>;
define OWNNETSET = [<OWNNET>+];
define RID = <RID>;
define HOSTNAME = "<HOSTNAME>";
router id RID;
hostname HOSTNAME;
ipv6 table crxn;
function is_self_net() {
return net ~ OWNNETSET;
}
function is_valid_network() {
return net ~ [
fd00::/8{44,64}
];
}
function reject_default_route() {
if (net = fd00::/8 || net = ::/0) then
reject;
}
function crxn_import_filter() {
if (net.type != NET_IP6 || ! is_valid_network() || is_self_net()) then
reject;
reject_default_route();
accept;
}
function crxn_export_filter() {
if ( ! is_valid_network() ) then
reject;
if (source !~ [RTS_STATIC, RTS_BABEL]) then
reject;
reject_default_route();
accept;
}
protocol static ownnet {
route OWNNET unreachable;
ipv6 {
table crxn;
export all;
};
}
protocol kernel {
ipv6 {
table crxn;
import none;
export filter {
krt_prefsrc = OWNIP;
accept;
};
};
}
protocol babel crxn_net {
interface "crxn_peer1" {
type wired;
rxcost 30;
};
ipv6 {
table crxn;
import where crxn_import_filter();
import limit 2000 action block;
export where crxn_export_filter();
};
}
protocol device {}
```
`<OWNIP>` is replaced by an IP address from its own subnet. Often `::1` is used for the router. `<OWNNET>` is replaced by its subnet or the part you want to propagate. If you have only one node, you can enter your whole /48 network. If you have several nodes and want to give each node a smaller network (e.g. /56 or /52), enter it here.
`<RID>` is a random IPv4 address which is used as unique identifier of the bird instance. You cannot peer with a peer that has the same router ID.
`<HOSTNAME>` can be replaced with the hostname of the router. This can be any string.
```
router id RID;
hostname HOSTNAME;
```
Here the router ID and hostname bird entered above is communicated.
```
ipv6 table crxn;
```
Here an IPv6 routing table with the name `crxn` is created. Alternatively, you can also use the default routing table `master6`. You do not have to create the `master6` table separately.
Next comes a set of utility functions that will later help us build the filters.
```
function is_self_net() {
return net ~ OWNNETSET;
}
```
This function returns `true` if the net is the own, otherwise `false`.
```
function is_valid_network() {
return net ~ [
fd00::/8{44,64}
];
}
```
The CRXN network uses IP addresses in the ULA range (`fd80::/8`). Here it is checked whether the network is in this range. This function can be used if you want to prevent clearnet addresses from being imported. Furthermore two limits are set with `{44,64}`: A net may have a maximum size of 64 and a minimum size of 44. The limitation of `/64` is to prevent the routing table from becoming too large. For example, someone could otherwise carry out an attack by propagating very many `/128` addresses. This prevents such an attack.
```
function reject_default_route() {
if (net = fd00::/8 || net = ::/0) then
reject;
}
```
If a router is misconfigured, it may happen that a default route is exported. A default route is `::/0` in the Clearnet and `fd00::/8` in the ULA range. If you propagate this, you say that you can reach any address. However, if an address is unknown, you want to get an ICMP unreachable or an ICMP No route. If you now import a default route, you would export the request to the peer that sends the default route, which would result in not getting an ICMP message.
Next we build the import and export filters:
```
function crxn_import_filter() {
if (net.type != NET_IP6 || ! is_valid_network() || is_self_net()) then
reject;
reject_default_route();
accept;
}
```
There are three creteria where we do not want to import a route: 1) It is not an IPv6 route. CRXN is an IPv6 network. This setting prevents misconfiguration. 2) The network is not in ULA range. 3) It is the own network.
You yourself what best how to reach your own network. One exports it to others. However, someone can try to hjack your network. For example by exporting a smaller (and therefore more precise) prefix. There are several ways to prevent this. One is to not participate in the attack on yourself. Therefore, not to import your own network from others.
Furthermore, we reject the Default Routes. If the route still exists afterwards, we import it.
```
function crxn_export_filter() {
if ( ! is_valid_network() ) then
reject;
if (source !~ [RTS_STATIC, RTS_BABEL]) then
reject;
reject_default_route();
accept;
}
```
To prevent misconfiguration on our own router, we filter out any non-ULA network and default route during export.
Furthermore, we only export routes which we have learned statically (see below) (`RTS_STATIC`) or which we have learned over others via Babel (`RTS_BABEL`).
```
protocol static ownnet {
route OWNNET unreachable;
ipv6 {
table crxn;
export all;
};
}
```
Next, we create a static route for our own network and export it to the routing table `crxn`. If you use the table `master6` you can omit the `table crxn;` statement. We say bird that our own network is not reachable. This ensures that bird now knows a route to our network and exports it. However, we ourselves can still reach devices on our network because they have a more precise prefix and longest prefix match applies.
```
protocol kernel {
ipv6 {
table crxn;
import none;
export filter {
krt_prefsrc = OWNIP;
accept;
};
};
}
```
In routing, a distinction is made between "Control Plane" and "Forwarding Plane". The control plane calculates the routes and passes them on to the forwarding plane. The forwarding plane then accepts the packets and forwards them accordingly. On a Linux router, bird is the control plane and the kernel is the forwarding plane, since the kernel is responsible for forwarding IP packets.
With `krt_prefsrc` we specify our source IP address. This is the addresses defined above. This address must exist on an interface. It is generally bound to a dummy interface.
Advantage and disadvantage of `persist`:
The keyword `persist` can be used to prevent bird from deleting routes from the forwarding plane. Only routes will be updated. The advantage of this is that when bird is terminated, the forwarding plane still knows the routes to the destinations. The disadvantage is that routes that are no longer propagated are retained. If the control plane no longer knows a route to a particular prefix, using `persist` will not delete the route from the forwarding plane. This can lead to some strange routing.
```
protocol babel crxn_net {
interface "crxn_peer1" {
type wired;
rxcost 30;
};
ipv6 {
table crxn;
import where crxn_import_filter();
import limit 2000 action block;
export where crxn_export_filter();
};
}
```
Here we create the Babel protocol, which is used to communicate with other CRXN routers. The protocol consists of `interface` and `ipv6` among others. The `interface` can occur several times, `ipv6` not.
In `ipv6` our import/export filters and our routing table `crxn` are defined accordingly. Furthermore an import limit of 2000 routes is set. If a malicious actor now tries to crash a router, for example by propagating a lot of routes, we protect ourselves with this. If 2000 routes are imported via CRXN, every further route is blocked. Although we protect our memory with this, a high rejection of routes can lead to an increased CPU load.
With `interface "crxn*";` you can mark any interface starting with `crxn` as a peer, but then you cannot fine-tune a peer.
Therefore it makes sense to define a separate interface for each peer. As `type` there are `wired` and `wireless`. In general `wired` is always used. According to the `type` parameter babel is adjusted. With `rxcost` we define the "cost", which a peer needs to us. Without specification this is 96. Here it is recommended to take the latency as cost. If you want to avoid that packets are routed through you, you can increase the cost.
In this example, there is a connection to our peer via the interface `crxn_peer1`. This is a wired connection with a latency of 30ms.
```
protocol device {}
```
The protocol `device` is mandatory in bird. This allows bird to communicate with the router. This is necessary for bird to get information about interfaces and the like.
## Network
Babel uses port 6696/udp and the multicast address `ff02::1:6`. Accordingly, port 6696/udp must be enabled locally.
## Control
These commands can be entered with in `birdc`:
To display all Babel peers you can use the following:
```
show babel neighbors
```
or
```
show babel n
```
View all CRXN routes:
```
show route protocol crxn
```
View all CRXN routes with details:
```
show route protocol crxn all
```
Display all the routes that you export:
```
show route export crxn
```
Display all the routes that you export with details:
```
show route export crxn all
```
Reload configuration:
```
configure
```
or
```
c
```
Help can be obtained by typing the command and then a `?`.