Doc about alanet reqs
This commit is contained in:
@@ -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 :)
|
||||
Reference in New Issue
Block a user