From 8a3037f2f858d94e1536471fd066b29da3eb4600 Mon Sep 17 00:00:00 2001 From: Fisher Darling Date: Thu, 3 Nov 2022 22:48:57 +0100 Subject: [PATCH] Doc about alanet reqs --- projects/alamesh/alanet_conf_reqs.md | 133 +++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 projects/alamesh/alanet_conf_reqs.md diff --git a/projects/alamesh/alanet_conf_reqs.md b/projects/alamesh/alanet_conf_reqs.md new file mode 100644 index 0000000..02c7554 --- /dev/null +++ b/projects/alamesh/alanet_conf_reqs.md @@ -0,0 +1,133 @@ +# Peering and BGP Configuration Requirements for Alanet + +[[_TOC_]] + +Before we start peering there are some questions we need to answer and a way to store global configuration. + +# Network Questions + +We need to decide: + +* What [ASN](https://en.wikipedia.org/wiki/Autonomous_system_(Internet)) range we will use for ourselves. Since +[RFC 4893](https://www.rfc-editor.org/rfc/rfc4893.html), ASNs are 32-bit numbers so we have plenty for the future ;). +[RFC 6996](https://www.rfc-editor.org/rfc/rfc6996.html) (heh) designated ASNs in the range `42XXXXXXXX` as "private". So +we just need to determine a prefix and go with that. `dn42` ASNs are `424242XXXX` which is a little small with only 10k. + * e.g. we could use `4255500000` and get 100k ASNs. +* What network do we use? I like sticking to `02::/8`. That's pretty large and memorable, and keeps `03::/8` available +for the future mesh network :). It'd be nice to not share space with `dn42` in case we want to peer with them. + * Here's a [list](https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml) of ipv6 address space. + `0200::/7` was deprecated in 2004, which is why I was thinking of using that. `dn42` uses `fd::/8`. +* How large of a prefix do we want to give people? Each hex char in an address adds 4 to the prefix len. + * `02::/8` since there's two chars "02" at the start. We could do `/16` for now. That's 256 at the start and limit to + one per AS. If we get above say `127` unique ASNs, then we can bump it up to a `/32`. + * With a `/16` prefix, addresses would look like `2XX::/16`. I was using `255::/16` and `200::/16` for my tests. + * Another option is to do `02XX:XX:X0::/32` where `X` is your ASN number suffix. That's kinda fun but then we don't get nice, + short addresses. + +Think about it what you want to do! Remember, it's _our_ internet. + +The rest of the document discusses our configuration requirements. + +# What Config Information Do We Need? + +As discovered in [[setting_up_bird]], there's a lot that can go wrong when setting up peering and bird configuration. +We want to automate that process and make it **a single command** to peer with a new person. + +We need global information about the router and information per-peer. + +## Router Config + +The router config is essentially the constants for configuring bird. + +- **ASN**: the router's ASN. Some number in some range `42XXXXXXXX`. +- **internal ip**: the router's alanet internal IPv6 addr. +- **subnet**: the internal subnet that this router controls/routes to. +- **router id**: the router's IPv4 unique ID. Can be generated or calculated manually. Does not have to be public. + +We can combine the internal IP and subnet pretty easily using cidr notation. e.g. `255:10::1/16` is the host +`255:10::1` and the network is `255::/16`. + +The router id can be calculated from the host and network. We take the set prefix of `255:10::1/16` which is `255::/16` +and convert that to a 128-bit integer. We then shift that integer left 96 bits and convert the lower 32 bits to an IPv4 +address. If the lowest byte of that new IPv4 addr is 0, we add 1. + +``` +255:: >> 96 = 0x02_55_00_00 (same as ::255:0) +0x02550000 + 1 = 0x02_55_00_01 (+1 since last byte was 0) +0x02550001 = 2.85.0.1 (unique IPv4 addr) +``` + +As long as we give people IPv6 prefixes that are shorter than 32 bits, the above algorithm will generate a unique IPv4 +addr per ASN. Another option is for people to use their public IPv4 addresses, but that requires people to have an +IPv4 capable server. Or, people just generate a random 32-bit number and we add that as part of the global ASN list. + +In any case, we can reduce the necessary per-router bird configuration to two things, the ASN and the host-with-cidr. + +## Peer Config (setting up BGP) + +BFP config for a peer is pretty simple. + +We just need: +- **Peer ASN**: the ASN of the peer. +- **Peer Internal IP**: the internal IP of the peer. +- **Peer Name**: some kind of friendly name (not neccessary, but nice to have). + +That's it. + +## Peer Config (connecting with WG) + +WireGuard config for a peer is dependent on some shared agreement between two parties. + +We need the: +- **Peer's PublicKey**: the public key of the peer. This could be globally configured. +- **Peer's endpoint**: the public endpoint, host with port, that we can reach this peer at. The port is different per-peer. + +The port is only different per-peer since we give each peer a separate interface. This makes things much easier from a +management and security perspective at the cost of making the port unknown. + +> We can setup auto-peering + +# What Are Our Automation Goals? + +* Only a single command to refresh or add a peer with a simple configuration format. +* Simple way to add public router information (asn, internal ip, subnet). +* Only exchange per-peer information _once_. I give you an endpoint and key, you give me an endpoint and key, done. + +See [[dn42_notes]] for an overview of how dn42 solves the above problems. TLDR; git repo. + +# Potential Implementation + +## Git Repo + +I like the git repo approach for global router information. People just open a PR and add a new block with their ASN. +The repo represents the source of truth and before you add a peer, you `git pull` the registry repo. This also lets us +generate a `Route Origin Authorization` (ROA) table that we can use to actually authenticate advertised routes. + +For peering we could do a similar git approach. We would all have public repos or folders. To Peer with someone, you open +a PR against their repo and then they open a PR against yours. Once both are merged, you pull the repo and run some sort +of tool that sets up the WG tunnel and bird. This doesn't have to be public and can be done over matrix or something, +but I like how git can act as a back up _and_ the tool could even manage the repo for you. + +## Matrix Room? + +Could we use matrix to share peering information, using the room state keys? Running a matrix user/bot might be taxing +on the super cheap VPS I'm using. Maybe there's another way. + +## Automatic Peering + +This would be incredibly useful. There's some dn42 peers that provide a UI or custom wg server that's 100% self serve. +The custom wg server is interesting since your connection port is the last 5 digits of your ASN which is really nice and +makes it very easy to peer with someone else. This makes me feel like peering should not be public and we might want to +eventually develop some sort of automatic peering solution. + +> I guess the automatic peering could be public, open a PR that's auto-merged if it passes. Once merged, a daemon builds +> something and the change is then live. + +## Other WG Implementations + +See [Identity Management for WireGuard](https://lwn.net/Articles/910766/). + +# Conclusion + +We need to answer the questions at the very beginning and figure out how to store ASN information. We could honestly +just answer the initial quesitions and just peer manually / not try to make anything fancy. Or we make it fancy :) \ No newline at end of file