Merge pull request 'add bird configuration' (#10) from mark22k/docs:master into master

Reviewed-on: https://codeberg.org/CRXN/docs/pulls/10
This commit is contained in:
Marek Küthe 2023-01-03 10:35:13 +00:00
commit a280d13d7a
19 changed files with 527 additions and 614 deletions

View File

@ -1,7 +1,5 @@
# Servers
HINT: This is currently a work in progress by @mark22k
## Recursive
| DNS | IP address |

View File

@ -1,4 +0,0 @@
CRXN DNS
========
**CRXN DNS** is coming soon.

View File

@ -1,124 +0,0 @@
# Servers
## Rekursiv
| DNS | IP address |
| --- | --- |
| recur1.bandura.crxn | fd92:58b6:2b2::5353 |
## Authoritiv
# Resolve CRXN domains only
Advantage:
- Very simple configuration
Disadvantage:
- No more access to Clearnet domains
- Dependence on one server
You can enter a recursive CRXN server as your DNS server in the operating system.
The configuration of this differs depending on the operating system. For example, in Debian without NetworkManager, you can add the following to `/etc/resolv.conf`:
```
nameserver fd92:58b6:2b2::5353
```
# Run your own forwarder
Advantage:
- Simple configuration
Disadvantage:
- Dependence on one server
With this method, you run a small DNS server of your own, which receives and forwards requests. This is suitable for one computer or very small networks.
There are several software you can use for this.
## Coredns
This guide is for Debian based systems.
First you need to download Coredns. You can find the software at https://coredns.io/. As a download package you get a compressed file. Extract it and make the file `coredns` executable and copy it into the directory `/usr/local/bin`.
```
$tar xvf coredns_1.10.0_linux_amd64.tgz
$chmod +x coredns
$sudo cp coredns /usr/local/bin/
```
To start Coredns automatically you can create a Systemd unit:
```
$ editor /etc/systemd/system/coredns.service
```
Paste the following:
```
[Unit]
Description=CoreDNS DNS server
Documentation=https://coredns.io/
After=network.target
After=alfis.service
After=meshnamed.service
[Service]
PermissionsStartOnly=true
LimitNOFILE=1048576
LimitNPROC=512
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
User=coredns
ExecStart=/usr/local/bin/coredns -conf=/etc/coredns/Corefile
ExecReload=/bin/kill -SIGUSR1 $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
```
After that reload systemd:
```
$sudo systemctl daemon-reload
```
To isolate Coredns, you create a new user:
```
$sudo adduser --home /etc/coredns/ --disabled-password --disabled-login coredns
```
After that you can create and edit the Coredns configuration file `Corefile`:
```
editor /etc/coredns/Corefile
```
Paste the following:
```
crxn., d.f.ip6.arpa. {
loop
bind 127.0.0.1 ::1
forward . fd92:58b6:2b2::5353
}
```
Replace `fd92:58b6:2b2::5353` with your preferred recursive server.
With `bind 127.0.0.1 ::1` you bind Coredns to your local machine only, so no one else can access it. If you want to create a network forwarder, you have to remove this line. If you want to restrict the forwarder access only to a specific network, you can use the [ACL Plugin](https://coredns.io/plugins/acl/).
To resolve Clearnet domains, insert the following:
```
. {
loop
bind 127.0.0.1 ::1
forward . tls://1.1.1.1 tls://1.0.0.1 tls://2606:4700:4700::1111 tls://2606:4700:4700::1001 {
tls_servername 1dot1dot1dot1.cloudflare-dns.com
}
}
```

View File

@ -1,124 +0,0 @@
# Servers
## Rekursiv
| DNS | IP address |
| --- | --- |
| recur1.bandura.crxn | fd92:58b6:2b2::5353 |
## Authoritiv
# Resolve CRXN domains only
Advantage:
- Very simple configuration
Disadvantage:
- No more access to Clearnet domains
- Dependence on one server
You can enter a recursive CRXN server as your DNS server in the operating system.
The configuration of this differs depending on the operating system. For example, in Debian without NetworkManager, you can add the following to `/etc/resolv.conf`:
```
nameserver fd92:58b6:2b2::5353
```
# Run your own forwarder
Advantage:
- Simple configuration
Disadvantage:
- Dependence on one server
With this method, you run a small DNS server of your own, which receives and forwards requests. This is suitable for one computer or very small networks.
There are several software you can use for this.
## Coredns
This guide is for Debian based systems.
First you need to download Coredns. You can find the software at https://coredns.io/. As a download package you get a compressed file. Extract it and make the file `coredns` executable and copy it into the directory `/usr/local/bin`.
```
$tar xvf coredns_1.10.0_linux_amd64.tgz
$chmod +x coredns
$sudo cp coredns /usr/local/bin/
```
To start Coredns automatically you can create a Systemd unit:
```
$ editor /etc/systemd/system/coredns.service
```
Paste the following:
```
[Unit]
Description=CoreDNS DNS server
Documentation=https://coredns.io/
After=network.target
After=alfis.service
After=meshnamed.service
[Service]
PermissionsStartOnly=true
LimitNOFILE=1048576
LimitNPROC=512
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
User=coredns
ExecStart=/usr/local/bin/coredns -conf=/etc/coredns/Corefile
ExecReload=/bin/kill -SIGUSR1 $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
```
After that reload systemd:
```
$sudo systemctl daemon-reload
```
To isolate Coredns, you create a new user:
```
$sudo adduser --home /etc/coredns/ --disabled-password --disabled-login coredns
```
After that you can create and edit the Coredns configuration file `Corefile`:
```
editor /etc/coredns/Corefile
```
Paste the following:
```
crxn., d.f.ip6.arpa. {
loop
bind 127.0.0.1 ::1
forward . fd92:58b6:2b2::5353
}
```
Replace `fd92:58b6:2b2::5353` with your preferred recursive server.
With `bind 127.0.0.1 ::1` you bind Coredns to your local machine only, so no one else can access it. If you want to create a network forwarder, you have to remove this line. If you want to restrict the forwarder access only to a specific network, you can use the [ACL Plugin](https://coredns.io/plugins/acl/).
To resolve Clearnet domains, insert the following:
```
. {
loop
bind 127.0.0.1 ::1
forward . tls://1.1.1.1 tls://1.0.0.1 tls://2606:4700:4700::1111 tls://2606:4700:4700::1001 {
tls_servername 1dot1dot1dot1.cloudflare-dns.com
}
}
```

View File

@ -0,0 +1,53 @@
# Format and Rules
## Language
In edb JSON is used to describe the entities. Each entity has a JSON file in the format: `<entity>.json`, where `<entity>` is the name of the entity. This file may contain the following characters:
- `a-z`
- `0-9`
- `_`
- `-`
The entity must not be `schema`.
## Indentation
An indentation of two spaces is used. Each entity must be formatted correctly. You can use a tool like jq or [jsonlint.com](https://jsonlint.com/) for this.
## Format verification
In the `schema.json` a schema with the format for the JSON files is defined. A check can be done for example with the Python tool `check-jsonschema`:
```
check-jsonschema --schemafile schema.json entity.json
```
## Availability
The edb is hosted by [Codeberg](https://codeberg.org/). The edb uses git for version control.
## Propose changes / registration
To propose a change or to register in the edb, you have to fork the repository, make your changes and then request a PR.
## Scripts
The edb repository currently contains two different scripts:
| `test.sh` | Tests the JSON files for validity |
| `build_maxlen_filter.sh` | Builds a bird-compatible filter list |
## Do I need to squash my commits before setting a PR?
Yes and No. Changes to files should be traceable. Therefore, a commit is recommended for every change. However, we also want to avoid more than 30 commits for one file in one PR. Therefore, if there are still mistakes in the initial registration, it would be nice to keep the number of commits within limits.
With the following commands you can squash two commits to one:
```
git rebase -i HEAD~2
```
Replace the second `pick` with `s` or `squash`. Save the file and exit.
Enter your new commit message. Save the file and exit.
Sign the commit with the following command:
```
git commit --amend -s -S
```
After that you can upload the changes. If the Git server rejects the changes, you can use the following command:
```
git push -f
```
## License
The edb is available under the AGPL v3 license. More information is available in the `LICENSE.md` in the repository of the edb.

15
docs/entitydb/index.md Normal file
View File

@ -0,0 +1,15 @@
# entitydb
Note: This documentation is in WIP.
In entitydb, the persons or organizations are registered in CRXN with their IP addresses. Here, each entity has a JSON file in which the data is recorded. The entitydb is also abbreviated as edb.
[entitydb](https://codeberg.org/CRXN/entitydb/)
- [Format and Rules](format-rules)
- [Security in Git](security-in-git)
Attributes:
- route
- [max-len](maxlen)

22
docs/entitydb/maxlen.md Normal file
View File

@ -0,0 +1,22 @@
# max-len filter
## What is a max-len filter?
By default, a prefix can be divided into any number of /64 blocks. By a `max-len` one can define the maximum size of a prefix of a subnet. For example, if you want to divide your subnet into /56 blocks, you can set the `max-len` to 56. This will filter all larger prefixes (e.g. `/60` or `/64`) from that subnet.
## Why is this important?
The principle of [longest prefix match](https://en.wikipedia.org/wiki/Longest_prefix_match) applies. This means that the largest and thus most accurate prefix is always selected. If an attacker now wants to hijack an IP address, one can propagate a larger prefix that contains the IP address. This means that the packets are now forwarded to them instead of the actual operator of the prefix. To fend off such attacks, it is necessary to filter more accurate prefixes. However, since each operator wants to propagate a different prefix size, the `max-len` can be set in the entitydb. If no `max-len` is specified, 64 is assumed.
## Where do I have to enter this in the edb?
```
"route": {
"<subnet>/48": {
"description": "<descr>",
"max-len": "<max-len>",
"device": {
"<device>": { }
}
}
}
```
Under `route`/`IP-Address` you create an attribute `max-len` of type string with the maximum length like `56` or `48`.

View File

@ -0,0 +1,18 @@
# Security in Git
Our entitydb is on codeberg.org, a free Git server based on Gitea.
## Two-factor authentication
Two-factor authentication requires entering a one-time code or using a physical security key in addition to the password when logging into Codeberg. If the password is compressed, an attacker cannot log in to the account.
- [Setting up two-factor authentication](https://docs.codeberg.org/security/2fa/)
- [Free authenticator apps on F-Droid](https://search.f-droid.org/?q=totp)
## Integrity of the connection to Codeberg
When connecting to Codeberg, an SSH connection is often used. To prevent MITM attacks, you can verify the SSH fingerprint.
- [Verifying you're connected to Codeberg using SSH fingerprints](https://docs.codeberg.org/security/ssh-fingerprint/)
## Sign the commits
To verify the authenticity and integrity of commits, it is recommended to sign them with GPG.
- [Signing Your Work](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work)
- [Signing commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits)

View File

@ -1,14 +1,10 @@
# Getting started
Firstly we'd like to say that we're glad you'd like to join our network and
greater community! This document will provide you with the directions you
will need to follow in order to get connected.
Firstly we'd like to say that we're glad you'd like to join our network and greater community! This document will provide you with the directions you will need to follow in order to get connected.
## Steps to follow
Below you can follow the steps one-by-one to get yourself familiar with our
practices and inner-workings and by the end you should have all the information
and configuration details needed to get connected!
Below you can follow the steps one-by-one to get yourself familiar with our practices and inner-workings and by the end you should have all the information and configuration details needed to get connected!
1. [Rules](rules)
* We have **few** but **strict** rules nonetheless

View File

@ -1,5 +1,27 @@
# DNS
TODO: Add documentation @mark22k
In the `radv` protocol in bird, there is a possibility to pass DNS servers to the clients. This requires a working recursive DNS server. If you only want to resolve CRXN domains, you can use a DNS server from [Additional/DNS](../additional/dns). If you also want to resolve Clearnet domains, it is recommended to use your own DNS resolver (recursive or forward) like Coredns or Unbound.
You can take look at [Additional/DNS](../additional/dns) in the meantime.
With the following option, you can specify a DNS server:
```
rdnss fd92:58b6:2b2::5353;
```
The following option allows you to specify multiple DNS servers:
```
rdnss {
ns fd92:58b6:2b2::5353;
ns fd92:58b6:2b2::5354;
};
```
If you also have a CRXN domain, you can also tell the clients a search domain:
```
dnssl "home.example.crxn";
```
```
dnssl {
domain "home.example.crxn";
domain "lab.home.example.crxn";
};
```

View File

@ -35,11 +35,48 @@ In the above example I am advertising a `/64` within my `/48`/ULA (`fd40:ec65:5b
## Advertising route(s)
You can advertise a default route, to `fd00::/8` or simply all routes in your router's routing table, to your hosts using the following:
You can advertise a default route, to `fd00::/8` or simply all routes in your router's routing table, to your hosts using the following.
The advantage of announcing only a single `fd00::/8` is that this needs less advertisement updates and thus consumes less traffic. Furthermore, the end devices do not have to maintain such large routing tables.
### Advertising a single `fd00::/8`
TODO: Add this as I normally don't do this even though one should as it means less memory consumption and advertisement updates
In order not to have the default route in our normal routing table, it is recommended to make an extra routing table for the radv routes. There we define the default route.
```
ipv6 table radv_routes;
protocol static {
ipv6 {
table radv_routes;
export all;
};
route fd00::/8 unreachable;
}
protocol radv
{
# Enable propagating of routes exported to us via radv to hosts
propagate routes yes;
ipv6 {
# Export ula default routes into the radv advertisement
export all;
table radv_routes;
};
# Interface to run radv on - only eth0 (change to what you want)
interface "eth0" {
# Advertise your prefix
prefix fd40:ec65:5b4c::/64 {
# Defaults are fine
};
# Prevent advertising of default route
default lifetime 0;
};
}
```
### Advertising all known routes

View File

@ -11,65 +11,40 @@
<img src="./img/map.png" class="floating_right" alt="CRXN logo">
CRXN stands for **C**ommunity **R**un e**X**pansive **N**etwork. It's a computer network _run by the community for the community_.
We provide an IPv6 (that's the freshest Internet Protocol out there to date) and on CRXN anything that can speak IPv6
will be able to function correctly - a network without borders! We are focused with having a network that really focuses
on the "end-to-end" principal of IP - that is to say that if you want to run something and make it available to other then
you won't have to worry about NAT-traversal, port forwarding, lack of raw IP support and all the other non-sense that IPv4
created (due to lack of addresses).
CRXN stands for **C**ommunity **R**un e**X**pansive **N**etwork. It's a computer network _run by the community for the community_. We provide an IPv6 (that's the freshest Internet Protocol out there to date) and on CRXN anything that can speak IPv6 will be able to function correctly - a network without borders! We are focused with having a network that really focuses on the "end-to-end" principal of IP - that is to say that if you want to run something and make it available to other then you won't have to worry about NAT-traversal, port forwarding, lack of raw IP support and all the other non-sense that IPv4 created (due to lack of addresses).
Compared to the clearnet (normal Internet) there isn't much fuss involved around getting
a network ID assigned to you and so forth, we truly are for the community and all our members take some of their own time
to work on their network and the greater CRXN inter-network as a whole.
Compared to the clearnet (normal Internet) there isn't much fuss involved around getting a network ID assigned to you and so forth, we truly are for the community and all our members take some of their own time to work on their network and the greater CRXN inter-network as a whole.
It's a great place to test out new protocols, networking projects, play games, exchange ideas and learn about networking,
routing and network sub-systems themselves. You also get to learn how CRXN is put together which is a great way to learn
networking with those that run networks already themselves.
It's a great place to test out new protocols, networking projects, play games, exchange ideas and learn about networking, routing and network sub-systems themselves. You also get to learn how CRXN is put together which is a great way to learn networking with those that run networks already themselves.
## Our goals
The network has a few goals that we always want to maintain as to not lose our allure:
1. Be a network for learning
* We don't want to shun people away from using some new
routing protocol as it might be cool and interesting to
learn
* We don't want to shun people away from using some new routing protocol as it might be cool and interesting to learn
2. Be reliable
* Of course when learning people should also make sure
their routers don't just accept any route without making
sure its valid - hence network operators should make sure
their networks operate even when some are causing mayhem
(malicious or learning by trial and error)
* Of course when learning people should also make sure their routers don't just accept any route without making sure its valid - hence network operators should make sure their networks operate even when some are causing mayhem (malicious or learning by trial and error)
* Also shouldn't be painfully slow
3. Diverse routing
* We want to try out protocols like **ospf**, **babel**, **bgp**
and so on and so forth
* We want to build a network out of a mix and match of these all
working in harmony together
* We want to try out protocols like **ospf**, **babel**, **bgp** and so on and so forth
* We want to build a network out of a mix and match of these all working in harmony together
* Monocultures suck!
4. Usable
* We have DNS, we have voice chat servers and we have IRC (we
even have gaming!) but we can always do with much **much more**!
* We want the users, _you_, to make the network usable for your
needs - who knows it might provide a service that helps out
someone else
* We have DNS, we have voice chat servers and we have IRC (we even have gaming!) but we can always do with much **much more**!
* We want the users, _you_, to make the network usable for your needs - who knows it might provide a service that helps out someone else
5. Peering
* We want people to setup redundant links using whatever protocols
they want, be it **wireguard**, **GRE**, **fastd** etc.
* We want people to setup redundant links using whatever protocols they want, be it **wireguard**, **GRE**, **fastd** etc.
* We want there to be interesting links and diversity
6. _Chaos and Order_
* The network should never stop experimenting
* But it should have 99% uptime and safety fallbacks
* If you want to experiment - then go ahead and try cause
as little disruption as possible
* If you run a node - make it secure - sign routes etc.
to prevent others from experimenting from messing your
network up
* If you want to experiment - then go ahead and try cause as little disruption as possible
* If you run a node - make it secure - sign routes etc. to prevent others from experimenting from messing your network up
We aim to create a more open Internet available to everyone and a place to learn about IP routing and networking in general.
We don't use any particular tooling, the only thing that is standard is the IPv4 and IPv6 part. What tunnelling software, physical
mediums or routing daemon you choose to use is up to you - this falls in line with our _open_ ethos.
We don't use any particular tooling, the only thing that is standard is the IPv4 and IPv6 part. What tunnelling software, physical mediums or routing daemon you choose to use is up to you - this falls in line with our _open_ ethos.
## About the network
@ -77,11 +52,9 @@ A few details about the network.
### Protocol support
We only use IPv6 on CRXN because it has many features, such as link-local addresses, that make
setting up dynamic routing protocols near-zero-config.
We only use IPv6 on CRXN because it has many features, such as link-local addresses, that make setting up dynamic routing protocols near-zero-config.
It's also the modern way of the Internet and means you will get a large space of addresses
assigned to you.
It's also the modern way of the Internet and means you will get a large space of addresses assigned to you.
### The range
@ -97,9 +70,7 @@ We keep track of allocations on a Git-based repository called [_EntityDB_](https
### Joining the network
Does it sound interesting enough for you already? Want to get connected? Then head on over
to our [Getting started](getting-started/) section where you can find all the guides you need in order to get connected,
follow the rules and have fun!
Does it sound interesting enough for you already? Want to get connected? Then head on over to our [Getting started](getting-started/) section where you can find all the guides you need in order to get connected, follow the rules and have fun!
---

View File

@ -49,8 +49,6 @@ Hackint IRC: `mark22k`
### Rany `~rany`
<!-- <img src="people/rany.png"> -->
Administer of EntityDB.
Roles: EntityDB
@ -61,8 +59,6 @@ Matrix: `@rany:fairydust.space`
### Alex Denes `~caskd`
<!-- <img src="people/caskd.png"> -->
European CRXN adminstration, runs the CRXN DNS root name server.
Roles: Network services, CRXN DNS

View File

@ -1,289 +0,0 @@
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
the core of what makes CRXN an inter-network.
The software we use for this procedure is known as BIRD or _BIRD Internet Routing Daemon_,
of which there are two versions:
1. Bird 1.6
2. Bird 2
You can use Bird 1.6 but you are on your own then in terms of configuration, the syntax
differs slightly but we recommend (and for the rest of this document we will be) using
Bird 2 as it comes with many bug fixes and improvements and most distributions (including Debian)
now have support for it.
## Installation
In order to install the BIRD daemon on your machine you should look for a package named `bird2` or something
similar (some repositories name it slightly differently - such as _just_ `bird`). On a Debian-based system you
can use:
```bash
sudo apt install bird2 -y
```
You can confirm that the version of BIRD you installed is version 2 with the command `bird -v`. If that shows the correct version number then continue to the next step:
```bash
sudo systemctl enable --now bird
```
This will ensure that the routing daemon starts on boot.
## Configuration
In this section we will be configuring two files:
1. `bird.conf`
* For general BIRD configuration e.g. _router IDs_, _device protocol_ and _includes_
2. `crxn.conf`
* For CRXN-specific details
### Basics
There are some basic definition that we are required to add to our configuration file. BIRD is normally configured to use the base configuration stored at something like `/etc/bird/bird.conf` or `/etc/bird.conf`, so open that file up and add the following to it.
#### Router ID
Every BIRD daemon is required to have what is known as a router ID which is written in the form of an IPv4 address. Now this does not actually need to be a valid IPv4 address in the sense of one you actually use but rather it just needs to follow the format, hence a router ID such as `1.1.1.1` is fine, despite you not "owning it".
Define the router ID as the first line in the configuration file like so:
```
router id 1.1.1.1;
```
TODO: These need to be unique - check how much this applies etc
These router IDs are required to be unique as they are used in the various protocols that BIRD supports in order to determine where a route advertisement came from - see them as a unique identifier of your BIRD router. Failing to do so will cause issues when routing on CRXN **and** a banning (TODO: see how we can enforce this).
#### Device protocol
BIRD supports many protocols which are used to import routing data from and export routing data to. However, the most basic of protocols which BIRD supports is known as the `device` protocol. The job of this protocol is just to provide basic device information to BIRD over time, it is required but luckily does not require much setup.
All that is required for this protocol to work is the following:
```
protocol device
{
# Optional parameters go here
}
```
You can adjust [scan times and such](https://bird.network.cz/?get_doc&v=20&f=bird-6.html#ss6.4) but the kernel normally will signal any changes to BIRD.
#### Includes
BIRD allows one to source configuration file contents from other files. Seeing that we will configure the CRXN-specific parts next we will want to include that file in the main entry file (`bird.conf`), this can be accomplished by placing this line at the bottom of said file:
```
include "/etc/crxn.conf";
```
### CRXN-specific setup
The below sections all apply to the CRXN-specific configuration and are to be placed in the file `/etc/crxn.conf`.
### Tables
We need to define the routing tables that BIRD will use in its process to store the routes that we want to learn from other routers and also advertise. Such a definition looks as follows:
```
# Define the IPv6 BIRD table
ipv6 table crxn;
```
You can choose any name for the table you want but you will just need to remember it such that you can refer to it later when it is needed.
### Filters
We need to define a filter which will be used to filter out any incorrect routes we want to advertise _to_ the network but also prevents any incorrect routes that are being propagated _from_ any misconfigured BIRD instances on the network:
```
filter crxnFilter
{
if (net ~ fd00::/8) then accept;
reject;
}
```
TODO: Add a check about not installing RTD_UNREACHABLEs which babel will generate sometimes and which BIRD reportedly has undefined behavior with
### Direct protocol
This provides BIRD with a manner of picking up the `subnet/prefix` pair that is assigned to local interfaces such that these can be imported into BIRD and later advertised.
```
protocol direct crxnDirect
{
ipv6
{
table crxn;
import filter crxnFilter;
};
# Interfaces to find neighbors on
interface "eth*";
}
```
### Kernel protocol
We need to sync the routes from the BIRD routing table `crxn` to the actual kernel's routing table such that it can be used in forwarding decisions. This is accomplished with the following declaration:
```
protocol kernel crxnKernel
{
ipv6 {
# bird's crxn table -> kernel
table crxn;
export filter crxnFilter;
};
persist;
}
```
1. The `persist` option means that when BIRD exits it will not flush the routing table. This is useful if you want to do maintenance and still want to allow forwarding of traffic for a little while (of course other routers may expire routes to you but at least not that fast)
---
Old stuff below WIP):
TODO: Re-do this sections
The configuration template is constructed out of the following files:
1. `filters.conf`
* Filter functions and the filter itself
2. `networks.conf`
* Advertisement of ULA
3. `tables.conf`
* The table definitions
4. `router.conf`
* This contains the needed protocol definition for discovering
your interface's prefixes and generating routes form them
* It also contains the needed protocol definitions to sync bird
routes into the Linux kernel's routing table (so you cna forward
packets based on the routes from Bird)
5. `protocols.conf`
* Depending on what protocol you want to use this will contains
configurations for each
All of these will be included in a file saved at `/etc/bird/bird.conf` like so:
```
router id <ipv4>;
include "/etc/bird/crxn/tables.conf";
include "/etc/bird/crxn/filters.conf";
include "/etc/bird/crxn/router.conf";
include "/etc/bird/crxn/networks.conf";
```
Additionally, add the files for the route distribution protocol which we configure in the next steps.
```
include "/etc/bird/crxn/babel.conf"; # For babel routing
include "/etc/bird/crxn/ospfv3.conf"; # For OSPFv3 routing
```
Remember to set a unique router ID in `<ipv4>`, make it anything - it doesn't have to even be an address you own.
#### `filters.conf`
This file holds all the required functions for subnet matching and also
filters that match to the specific prefix aggregates (regional subnets)
that CRXN uses.
```
filter crxnFilter
{
if (net ~ fd00::/8) then accept;
reject;
}
```
#### `tables.conf`
This file holds all table definitions. There are only two actually.
The table `crxn` is the one we actually use, `master` is optional
and is only present because if one uses `bird-lg-go` (the looking glass
we use) then it, by default, only shows routes in the `master` table.
It is meant to have the same routes as the `crxn` table.
```
# CRXN table
ipv6 table crxn;
```
#### `router.conf`
This contains an instance of the `direct` protocol which reads the address
and prefix assigned to your AF_INET6 interfaces and generates routes from
those that represent routes to directly atrtached networks those interfaces
are on. The reason for this is that the `kernel` protocol never learns routes
in the Linux kernel's routing table that have the `kernel` protocol which
is what you get when you assign interfaces addresses and prefixes. This
doesn't even need those, it gets them from the interface.
```
# The kernel protocol doesn't grab kernel routes that are added by you when you assign an
# address and prefix. So instead of reading this from all routes with `proto kernel` this just
# yeets the routes off of the interface structure itself (even if you didn't have a route for your
# directly attached networks - i.e. nexthop = 0.0.0.0)
protocol direct crxnDirect
{
ipv6
{
table crxn;
import filter crxnFilter;
};
# Interfaces to find neighbours on
interface "eth*";
}
protocol device {
}
```
The second part is for syncing routes from Bird to the Linux kernel's routing
table such that you can forward traffic based on the routes in Bird.
TODO: Check, defualt `learn` should learn non `kernel` and non-`bird` routes
```
# CRXN Kernel protocol
# We import any routes from the kernel table other than `proto bird` and `proto kernel`,
# could be `proto static` for example. By default it will learn these.
# Of course we also then export all routes from our Bird tables into the kernel so you can actually forward packets
protocol kernel crxnKernel
{
ipv6 {
# bird's crxn table -> kernel
table crxn;
export filter crxnFilter;
};
}
```
#### `networks.conf`
This is just something we normally add. Usually you would assign a `/64` within your ULA `/48` but you also want to claim the whole `/48` by advertising a blackhole for it. Here our `/48`/ULA is `fd40:ec65:5b4c::/48`.
```
protocol static crxnStatic
{
# Advertise your /48 with a blackhole
route fd40:ec65:5b4c::/48 blackhole;
ipv6 {
import filter crxn6;
table crxn;
}
}
```

306
docs/routing/bird/bird.md Normal file
View File

@ -0,0 +1,306 @@
# 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 the core of what makes CRXN an inter-network.
The software we use for this procedure is known as BIRD or _BIRD Internet Routing Daemon_, of which there are two versions:
1. Bird 1.6
2. Bird 2
You can use Bird 1.6 but you are on your own then in terms of configuration, the syntax differs slightly but we recommend (and for the rest of this document we will be) using Bird 2 as it comes with many bug fixes and improvements and most distributions (including Debian) now have support for it.
## Installation
In order to install the BIRD daemon on your machine you should look for a package named `bird2` or something similar (some repositories name it slightly differently - such as _just_ `bird`). On a Debian-based system you can use:
```bash
sudo apt install bird2 -y
```
You can confirm that the version of BIRD you installed is version 2 with the command `bird -v`. If that shows the correct version number then continue to the next step:
```bash
sudo systemctl enable --now bird
```
This will ensure that the routing daemon starts on boot.
## 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.
### Full example
`<OWNIP>` is replaced by an IP address from its own subnet. Often `xxxx::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.
BIRD is normally configured to use the base configuration stored at something like `/etc/bird/bird.conf` or `/etc/bird.conf`, so open that file up and add the following to it.
```
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 {}
```
### Explanations
```
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.
## 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 `?`.
## Babel
Babel uses port 6696/udp and the multicast address `ff02::1:6`. Accordingly, port 6696/udp must be enabled locally.
## Old bird configurations
Old configuration can be found [here](old-configuration).
Very old configuration can be found [here](very-old-configuration).

View File

@ -0,0 +1,5 @@
# bird routing daemon
- [Configuring Bird2](bird)
- [`max-len` filter](maxlen-filter)

View File

@ -0,0 +1,23 @@
# Implement max-len filter
To implement a max-length filter, we need a rule/policy/filter file that contains the corresponding prefixes with their maximum length. The entitydb contains a bash script `build_maxlen_filter.sh` for this purpose. If you run this script, you will get a bird-compatible list.
```
define CRXN_IPs = [
include "<path-to-file>";
];
function is_crxn_net() {
return net ~ CRXN_IPs;
}
```
This bird configuration can be used to load the file. You have to replace `<path-to-file>` with the path of the filter file. The function `is_crxn_net` then checks whether a route complies with the rules or not.
```
if (! is_crxn_net() ) then {
print "[CRXN] Invalid crxn route: ", net;
reject;
}
```
This configuration can then be added to your import filter before 'accept'. The line with `print` is optional. If you leave this line, every hjack attempt will be logged in the bird log output.

View File

@ -2,23 +2,15 @@
## Enabling forwarding
We will be setting up the machine that runs bird as a router so therefore
we need to make your Linux kernel's network stack not drop IPv6 packets
that it receives (addressed to it via Ethernet) but are not addressed to
it via IPv6 address - in other words it must try do something with these packets,
namely attempt to forward them one hop closer to their initial destination.
We will be setting up the machine that runs bird as a router so therefore we need to make your Linux kernel's network stack not drop IPv6 packets that it receives (addressed to it via Ethernet) but are not addressed to it via IPv6 address - in other words it must try do something with these packets, namely attempt to forward them one hop closer to their initial destination.
Enabling forwarding on all interfaces can be achieved as follows (you will need
to be root):
Enabling forwarding on all interfaces can be achieved as follows (you will need to be root):
```bash
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
```
However, after reboot it won't be saved and will go back to its defaults. Therefore
what you need to do is to enable forwarding on boot-up, this can be done by
adding an additional line to your `/etc/sysctl.conf` (which holds a bunch of
these statements), it should look like this:
However, after reboot it won't be saved and will go back to its defaults. Therefore what you need to do is to enable forwarding on boot-up, this can be done by adding an additional line to your `/etc/sysctl.conf` (which holds a bunch of these statements), it should look like this:
```bash
net.ipv6.conf.all.forwarding=1

View File

@ -13,7 +13,7 @@ nav:
- Routing:
- Fowarding: routing/forwarding
- Setting up Bird: routing/bird
- Setting up Bird: routing/bird/bird
- Tunneling:
- Fastd: tunneling/fastd