2014-06-22 17:20:39 +02:00
Bird is a commonly used BGP daemon. This page provides configuration and help to run Bird for dn42.
2016-02-25 12:46:40 +01:00
Compared to quagga, bird supports multiple routing tables, which is useful, if you also plan to peer with other federated networks such as freifunk. In the following a working configuration for dn42 is shown. If you
2016-02-25 12:47:37 +01:00
want to learn the practical details behind routing protocols in bird, see the following [guide ](https://github.com/knorrie/network-examples )
2014-06-22 17:20:39 +02:00
2023-10-05 23:48:10 +02:00
**Bird 1.6.x will be EOL by the end of 2023, it's recommended to upgrade to 2.13.**
2015-04-20 15:49:56 +02:00
# Debian
2017-02-01 23:38:41 +01:00
In the Debian release cycle the bird packages may become outdated at times, if that is the case you should use the official bird package repository maintained by the developers of nic.cz.
This is not necessary for Debian Stretch, which currently ships the most recent version (1.6.3) in this repositories.
2021-05-31 21:20:54 +02:00
```sh
2021-09-05 11:42:08 +02:00
echo "deb http://deb.debian.org/debian buster-backports main" > /etc/apt/sources.list.d/buster-backports.list
apt update
apt install bird
2021-05-31 21:20:54 +02:00
```
2015-04-20 15:49:56 +02:00
2015-02-11 10:30:40 +01:00
# Example configuration
2014-06-22 17:20:39 +02:00
2018-06-12 13:29:14 +02:00
Note: This file covers the configuration of Bird 1.x. For an example configuration of Bird 2.x see [howto/Bird2 ](/howto/Bird2 )
2015-04-22 22:21:25 +02:00
* Replace `<AS>` with your Autonomous System Number (only the digits)
2015-02-11 10:17:36 +01:00
* Replace `<GATEWAY_IP>` with your gateway ip (the internal dn42 ip address you use on the host, where dn42 is running)
2017-02-16 22:08:21 +01:00
* Replace `<SUBNET>` with your registered dn42 subnet
2015-02-11 10:18:19 +01:00
* Replace `<PEER_IP>` with the ip of your peer who is connected with you using your favorite vpn protocol (openvpn, ipsec, tinc, ...)
2015-04-22 22:21:25 +02:00
* Replace `<PEER_AS>` the Autonomous System Number of your peer (only the digits)
2015-02-11 10:17:36 +01:00
* Replace `<PEER_NAME>` a self chosen name for your peer
2014-06-22 17:20:39 +02:00
2021-05-31 23:48:53 +02:00
## IPv6
2015-02-27 22:27:53 +01:00
2023-04-08 22:08:13 +02:00
```conf
2015-02-27 22:27:53 +01:00
#/etc/bird/bird6.conf
protocol device {
scan time 10;
}
# local configuration
######################
2015-12-14 15:08:28 +01:00
include "/etc/bird/local6.conf";
2015-02-27 22:27:53 +01:00
2015-03-24 15:10:23 +01:00
# filter helpers
#################
2017-05-09 11:01:01 +02:00
##include "/etc/bird/filter6.conf";
2015-03-24 15:10:23 +01:00
2015-02-27 22:27:53 +01:00
# Kernel routing tables
########################
2016-02-22 21:23:05 +01:00
/*
krt_prefsrc defines the source address for outgoing connections.
On Linux, this causes the "src" attribute of a route to be set.
2021-05-31 23:48:53 +02:00
2016-02-22 21:23:05 +01:00
Without this option outgoing connections would use the peering IP which
would cause packet loss if some peering disconnects but the interface
is still available. (The route would still exist and thus route through
the TUN/TAP interface but the VPN daemon would simply drop the packet.)
*/
2015-02-27 22:27:53 +01:00
protocol kernel {
scan time 20;
import none;
export filter {
2016-02-15 20:11:32 +01:00
if source = RTS_STATIC then reject;
2015-02-27 22:27:53 +01:00
krt_prefsrc = OWNIP;
accept;
};
}
# static routes
################
protocol static {
route < SUBNET > reject;
2016-02-01 20:58:34 +01:00
import all;
export none;
2015-02-27 22:27:53 +01:00
}
template bgp dnpeers {
local as OWNAS;
path metric 1;
import keep filtered;
import filter {
if is_valid_network() & & !is_self_net() then {
accept;
}
reject;
};
export filter {
2020-03-29 14:32:06 +02:00
if is_valid_network() & & source ~ [RTS_STATIC, RTS_BGP] then {
2015-02-27 22:27:53 +01:00
accept;
}
reject;
};
2016-08-29 23:42:31 +02:00
import limit 1000 action block;
2015-02-27 22:27:53 +01:00
}
include "/etc/bird/peers6/*";
2021-05-31 21:20:54 +02:00
```
2015-02-27 22:27:53 +01:00
2023-04-08 22:08:13 +02:00
```conf
2015-02-27 22:27:53 +01:00
# /etc/bird/local6.conf
# should be a unique identifier, use same id as for ipv4
router id < GATEWAY_IP > ;
define OWNAS = < AS > ;
define OWNIP = < GATEWAY_IP > ;
function is_self_net() {
return net ~ [< SUBNET > +];
}
2015-03-02 15:39:31 +01:00
2016-02-11 18:39:39 +01:00
function is_valid_network() {
2015-02-27 22:27:53 +01:00
return net ~ [
2017-05-12 15:00:31 +02:00
fd00::/8{44,64} # ULA address space as per RFC 4193
];
2017-02-01 23:53:03 +01:00
}
2021-05-31 21:20:54 +02:00
```
2015-02-27 22:27:53 +01:00
2023-04-08 22:08:13 +02:00
```conf
2016-02-20 23:55:03 +01:00
# /etc/bird/peers6/<PEER_NAME>
protocol bgp < PEER_NAME > from dnpeers {
neighbor < PEERING_IP > as < PEER_AS > ;
# if you use link-local ipv6 addresses for peering using the following
# neighbor < PEERING_IP > % '< INTERFACE_NAME > ' as < PEER_AS > ;
};
2021-05-31 21:20:54 +02:00
```
2016-02-20 23:55:03 +01:00
2016-02-15 09:46:43 +01:00
### IPv4
2023-04-08 22:08:13 +02:00
```conf
2016-02-15 09:46:43 +01:00
# /etc/bird/bird.conf
# Device status
protocol device {
scan time 10; # recheck every 10 seconds
}
protocol static {
# Static routes to announce your own range(s) in dn42
route < SUBNET > reject;
import all;
export none;
};
# local configuration
######################
# keeping router specific in a seperate file,
# so this configuration can be reused on multiple routers in your network
include "/etc/bird/local4.conf";
# filter helpers
#################
2017-05-09 11:01:01 +02:00
##include "/etc/bird/filter4.conf";
2016-02-15 09:46:43 +01:00
# Kernel routing tables
########################
/*
krt_prefsrc defines the source address for outgoing connections.
On Linux, this causes the "src" attribute of a route to be set.
2021-05-31 23:48:53 +02:00
2016-02-15 09:46:43 +01:00
Without this option outgoing connections would use the peering IP which
would cause packet loss if some peering disconnects but the interface
is still available. (The route would still exist and thus route through
the TUN/TAP interface but the VPN daemon would simply drop the packet.)
*/
protocol kernel {
scan time 20;
import none;
export filter {
if source = RTS_STATIC then reject;
krt_prefsrc = OWNIP;
accept;
};
};
# DN42
#######
template bgp dnpeers {
local as OWNAS;
# metric is the number of hops between us and the peer
path metric 1;
# this lines allows debugging filter rules
# filtered routes can be looked up in birdc using the "show route filtered" command
import keep filtered;
import filter {
# accept every subnet, except our own advertised subnet
# filtering is important, because some guys try to advertise routes like 0.0.0.0
if is_valid_network() & & !is_self_net() then {
accept;
}
reject;
};
export filter {
# here we export the whole net
2020-03-29 14:38:51 +02:00
if is_valid_network() & & source ~ [RTS_STATIC, RTS_BGP] then {
2016-02-15 09:46:43 +01:00
accept;
}
reject;
};
2016-08-29 23:42:31 +02:00
import limit 1000 action block;
2016-02-15 09:46:43 +01:00
#source address OWNIP;
};
include "/etc/bird/peers4/*";
2021-05-31 21:20:54 +02:00
```
2016-02-15 09:46:43 +01:00
2023-04-08 22:08:13 +02:00
```conf
2016-02-15 09:46:43 +01:00
#/etc/bird/local4.conf
# should be a unique identifier, <GATEWAY_IP> is what most people use.
router id < GATEWAY_IP > ;
define OWNAS = < AS > ;
define OWNIP = < GATEWAY_IP > ;
function is_self_net() {
return net ~ [< SUBNET > +];
}
function is_valid_network() {
return net ~ [
2017-02-01 23:53:03 +01:00
172.20.0.0/14{21,29}, # dn42
172.20.0.0/24{28,32}, # dn42 Anycast
172.21.0.0/24{28,32}, # dn42 Anycast
172.22.0.0/24{28,32}, # dn42 Anycast
172.23.0.0/24{28,32}, # dn42 Anycast
172.31.0.0/16+, # ChaosVPN
10.100.0.0/14+, # ChaosVPN
2020-05-09 16:27:43 +02:00
10.127.0.0/16{16,32}, # neonetwork
2017-10-08 05:46:16 +02:00
10.0.0.0/8{15,24} # Freifunk.net
2017-05-12 15:00:31 +02:00
];
2016-02-15 09:46:43 +01:00
}
2021-05-31 21:20:54 +02:00
```
2016-02-15 09:46:43 +01:00
2023-04-08 22:08:13 +02:00
```conf
2016-02-15 09:46:43 +01:00
# /etc/bird/peers4/<PEER_NAME>
protocol bgp < PEER_NAME > from dnpeers {
neighbor < PEERING_IP > as < PEER_AS > ;
};
2021-05-31 21:20:54 +02:00
```
2016-02-15 09:46:43 +01:00
2015-03-24 13:48:38 +01:00
# Bird communities
2015-03-30 23:24:20 +02:00
2015-03-28 15:26:33 +01:00
Communities can be used to prioritize traffic based on different flags, in DN42 we are using communities to prioritize based on latency, bandwidth and encryption. It is really easy to get started with communities and we encourage all of you to get the basic configuration done and to mark your peerings with the correct flags for improved routing.
More information can be found [here ](/howto/Bird-communities ).
2015-02-27 22:27:53 +01:00
2016-06-09 06:54:27 +02:00
# Route Origin Authorization
Route Origin Authorizations should be used in BIRD to authenticate prefix announcements. These check the originating AS and validate that they are allowed to advertise a prefix.
## ROA Tables
2021-05-19 14:25:06 +02:00
The ROA table can be generated from the registry directly or you can use the following pre-built ROA tables for BIRD:
2016-06-09 06:54:27 +02:00
2022-05-09 19:52:20 +02:00
ROA files generated by [dn42regsrv ](https://git.burble.com/burble.dn42/dn42regsrv ) are available from burble.dn42:
2020-01-19 11:12:20 +01:00
2023-04-08 21:53:12 +02:00
|URL| IPv4/IPv6 |Description|
|---|---|---|
| < https: / / dn42 . burble . com / roa / dn42_roa_46 . json > | Both | JSON format for use with RPKI |
| < https: / / dn42 . burble . com / roa / dn42_roa_bird1_46 . conf > | Both | Bird1 format |
| < https: / / dn42 . burble . com / roa / dn42_roa_bird1_4 . conf > | IPv4 Only | Bird1 format |
| < https: / / dn42 . burble . com / roa / dn42_roa_bird1_6 . conf > | IPv6 Only | Bird1 format |
| < https: / / dn42 . burble . com / roa / dn42_roa_bird2_46 . conf > | Both | Bird2 format |
| < https: / / dn42 . burble . com / roa / dn42_roa_bird2_4 . conf > | IPv4 Only | Bird2 format |
| < https: / / dn42 . burble . com / roa / dn42_roa_bird2_6 . conf > | IPv6 Only | Bird2 format |
2020-01-19 11:12:20 +01:00
2023-02-04 16:11:24 +01:00
ROA files generated by [roa_wizard ](https://git.dn42.dev/Kioubit/roa_wizard ) are available:
2022-11-17 17:30:40 +01:00
|URL| IPv4/IPv6 |Description|
2023-04-08 21:53:12 +02:00
|---|---|---|
| < https: / / kioubit-roa . dn42 . dev / ? type = v4 > | IPv4 Only | Bird2 format |
| < https: / / kioubit-roa . dn42 . dev / ? type = v6 > | IPv6 Only | Bird2 format |
| < https: / / kioubit-roa . dn42 . dev / ? type = json > | Both | JSON format for use with RPKI |
2022-11-17 17:30:40 +01:00
2016-06-09 06:54:27 +02:00
### Updating ROA tables
You can add cron entries to periodically update the tables:
2023-04-08 22:08:13 +02:00
```conf
2020-05-09 13:50:15 +02:00
*/15 * * * * curl -sfSLR {-o,-z}/var/lib/bird/bird6_roa_dn42.conf https://dn42.burble.com/roa/dn42_roa_bird1_6.conf && chronic birdc6 configure
*/15 * * * * curl -sfSLR {-o,-z}/var/lib/bird/bird_roa_dn42.conf https://dn42.burble.com/roa/dn42_roa_bird1_4.conf && chronic birdc configure
2021-05-31 21:20:54 +02:00
```
2016-06-09 06:54:27 +02:00
2017-05-09 11:01:01 +02:00
Debian version:
2023-04-08 22:08:13 +02:00
```conf
2020-07-06 12:10:01 +02:00
*/15 * * * * curl -sfSLR -o/var/lib/bird/bird6_roa_dn42.conf -z/var/lib/bird/bird6_roa_dn42.conf https://dn42.burble.com/roa/dn42_roa_bird1_6.conf && /usr/sbin/birdc6 configure
*/15 * * * * curl -sfSLR -o/var/lib/bird/bird_roa_dn42.conf -z/var/lib/bird/bird_roa_dn42.conf https://dn42.burble.com/roa/dn42_roa_bird1_4.conf && /usr/sbin/birdc configure
2021-05-31 21:20:54 +02:00
```
2017-05-09 11:01:01 +02:00
2017-11-30 16:46:35 +01:00
then create the directory to make sure curls can save the files:
2023-04-08 22:08:13 +02:00
```sh
2017-11-30 16:46:35 +01:00
mkdir -p /var/lib/bird/
2021-05-31 21:20:54 +02:00
```
2017-11-30 16:46:35 +01:00
2022-11-01 04:16:16 +01:00
Or use a systemd timer: (check the commands before copy-pasting)
2023-04-08 22:08:13 +02:00
```conf
2022-11-01 04:16:16 +01:00
# /etc/systemd/system/dn42-roa.service
[Unit]
Description=Update DN42 ROA
[Service]
Type=oneshot
ExecStart=curl -sfSLR -o /etc/bird/roa_dn42.conf -z /etc/bird/roa_dn42.conf https://dn42.burble.com/roa/dn42_roa_bird2_4.conf
ExecStart=curl -sfSLR -o /etc/bird/roa_dn42_v6.conf -z /etc/bird/roa_dn42_v6.conf https://dn42.burble.com/roa/dn42_roa_bird2_6.conf
ExecStart=birdc configure
```
2023-04-08 22:08:13 +02:00
```conf
2022-11-01 04:16:16 +01:00
# /etc/systemd/system/dn42-roa.timer
[Unit]
Description=Update DN42 ROA periodically
[Timer]
OnBootSec=2m
OnUnitActiveSec=15m
AccuracySec=1m
[Install]
WantedBy=timers.target
```
then enable and start the timer with `systemctl enable --now dn42-roa.timer` .
2023-12-11 16:03:48 +01:00
More advanced script with error checking:
```sh
#!/bin/bash
roa4URL=""
roa6URL=""
roa4FILE="/etc/bird/roa/roa_dn42.conf"
roa6FILE="/etc/bird/roa/roa_dn42_v6.conf"
cp "${roa4FILE}" "${roa4FILE}.old"
cp "${roa6FILE}" "${roa6FILE}.old"
if curl -f -o "${roa4FILE}.new" "${roa4URL};" ;then
mv "${roa4FILE}.new" "${roa4FILE}"
fi
if curl -f -o "${roa6FILE}.new" "${roa6URL};" ;then
mv "${roa6FILE}.new" "${roa6FILE}"
fi
if birdc configure ; then
rm "${roa4FILE}.old"
rm "${roa6FILE}.old"
else
mv "${roa4FILE}.old" "${roa4FILE}"
mv "${roa6FILE}.old" "${roa6FILE}"
fi
```
2021-09-09 19:05:28 +02:00
### Use RPKI ROA in bird2
2021-05-08 17:13:00 +02:00
* Download gortr
2021-05-08 17:11:35 +02:00
2023-04-08 22:08:13 +02:00
< https: / / github . com / cloudflare / gortr / releases >
2021-05-08 17:11:35 +02:00
2022-03-27 08:13:07 +02:00
* Run gortr.
2021-05-08 17:07:33 +02:00
2023-04-08 22:08:13 +02:00
```sh
2021-05-08 17:15:33 +02:00
./gortr -verify=false -checktime=false -cache=https://dn42.burble.com/roa/dn42_roa_46.json
2021-05-31 21:20:54 +02:00
```
2021-05-13 11:41:49 +02:00
2021-09-09 19:05:28 +02:00
* Run with docker
2021-05-13 11:41:49 +02:00
2023-04-08 22:08:13 +02:00
```sh
docker pull cloudflare/gortr
2021-05-31 21:20:54 +02:00
```
2023-04-08 22:08:13 +02:00
```sh
2021-05-13 11:41:49 +02:00
docker run --name dn42rpki -p 8282:8282 --restart=always -d cloudflare/gortr -verify=false -checktime=false -cache=https://dn42.burble.com/roa/dn42_roa_46.json
2021-05-31 21:20:54 +02:00
```
2021-05-08 17:07:33 +02:00
2021-05-13 12:02:53 +02:00
* Add this to your bird configure file,other ROA protocol must removed.
2021-05-08 17:07:33 +02:00
2023-04-08 22:08:13 +02:00
```conf
2021-05-08 17:07:33 +02:00
protocol rpki rpki_dn42{
roa4 { table dn42_roa; };
roa6 { table dn42_roa_v6; };
remote "< your rpki server ip or domain > " port 8282;
retry keep 90;
refresh keep 900;
expire keep 172800;
}
2021-05-31 21:20:54 +02:00
```
2021-05-08 17:07:33 +02:00
2016-06-09 06:54:27 +02:00
## Filter configuration
In your import filter add the following to reject invalid routes:
2023-04-08 22:08:13 +02:00
```conf
2020-01-19 11:05:38 +01:00
if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then {
2016-06-09 06:54:27 +02:00
print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
reject;
}
2021-05-31 21:20:54 +02:00
```
2016-06-09 06:54:27 +02:00
Also, define your ROA table with:
2023-04-08 22:08:13 +02:00
```conf
2016-06-09 06:54:27 +02:00
roa table dn42_roa {
2016-09-18 14:27:13 +02:00
include "/var/lib/bird/bird_roa_dn42.conf";
2016-06-09 06:54:27 +02:00
};
2021-05-31 21:20:54 +02:00
```
2016-06-09 06:54:27 +02:00
2021-05-08 17:07:33 +02:00
2016-06-09 06:54:27 +02:00
**NOTE**: Make sure you setup ROA checks for both bird and bird6 (for IPv6).
2015-02-11 10:37:21 +01:00
# Useful bird commmands
bird can be remote controlled via the `birdc` command. Here is a list of useful bird commands:
2023-04-08 22:08:13 +02:00
```sh
2015-02-11 10:37:21 +01:00
$ birdc
BIRD 1.4.5 ready.
2016-01-03 06:25:07 +01:00
bird> configure # reload configuration
Reading configuration from /etc/bird.conf
Reconfigured
2015-06-28 01:26:26 +02:00
bird> show ? # Completions work either by pressing tab or pressing '?'
show bfd ... Show information about BFD protocol
show interfaces Show network interfaces
show memory Show memory usage
show ospf ... Show information about OSPF protocol
show protocols [< protocol > | "< pattern > "] Show routing protocols
show roa ... Show ROA table
show route ... Show routing table
show static [< name > ] Show details of static protocol
show status Show router status
show symbols ... Show all known symbolic names
2015-02-11 10:37:21 +01:00
bird> show protocols # this command shows your peering status
name proto table state since info
device1 Device master up 07:20:25
kernel1 Kernel master up 07:20:25
chelnok BGP master up 07:20:29 Established
hax404 BGP master up 07:20:26 Established
static1 Static master up 07:20:25
2016-02-15 20:22:42 +01:00
bird> show protocols all chelnok # show verbose peering status for peering with chelnok
2015-02-11 10:37:21 +01:00
bird> show route for 172.22.141.181 # show possible routes to internal.dn42
172.22.141.0/24 via 172.23.67.1 on tobee [tobee 07:20:30] * (100) [AS64737i]
via 172.23.64.1 on chelnok [chelnok 07:20:29] (100) [AS64737i]
via 172.23.136.65 on hax404 [hax404 07:20:26] (100) [AS64737i]
2015-06-14 20:19:46 +02:00
bird> show route filtered # shows routed filtered out by rules
2015-02-27 22:27:53 +01:00
172.23.245.1/32 via 172.23.64.1 on chelnok [chelnok 21:26:18] * (100) [AS76175i]
172.22.247.128/32 via 172.23.64.1 on chelnok [chelnok 21:26:18] * (100) [AS76175i]
172.22.227.1/32 via 172.23.64.1 on chelnok [chelnok 21:26:18] * (100) [AS76115i]
172.23.196.75/32 via 172.23.64.1 on chelnok [chelnok 21:26:18] * (100) [AS76115i]
172.22.41.241/32 via 172.23.64.1 on chelnok [chelnok 21:26:18] * (100) [AS76115i]
172.22.249.4/30 via 172.23.64.1 on chelnok [chelnok 21:26:18] * (100) [AS4242420002i]
172.22.255.133/32 via 172.23.64.1 on chelnok [chelnok 21:26:18] * (100) [AS64654i]
2015-06-14 20:19:46 +02:00
bird> show route protocol < somepeer > # shows the route they export to you
bird> show route export < somepeer > # shows the route you export to someone
2015-02-27 22:27:53 +01:00
...
2021-05-31 21:20:54 +02:00
```
2015-02-11 10:38:14 +01:00
# External Links
2023-04-08 21:53:12 +02:00
* detailed bird configuration from Mic92: < https: // github . com / Mic92 / bird-dn42 >
* more bird commands: < https: // bird . network . cz /? get_doc & v = 20&f=bird-4.html >