today I joined the CRXN netwerk. The CRXN is similar to the dn42, but with four differences:
- It uses IPv6 only
- It uses the babel routing protocol
- It is small, which can be seen by the number of prefixes
- It uses fastd as a tunnel
I wanted to have the CRXN on the same nodes as I have the dn42 network, but the two networks should not mix because their registries are not synced, use different routing protocols, and are not interconnected to each other. This presented a bit of a challenge.
Furthermore, in CRXN it is currently not (yet) possible to validate the routes, so route hijacking or similar is quite easy.
It uses only IPv6
I think it is a good decision to only use IPv6. Not for nothing IPv6 is the future. CRXN uses the ULA range. This corresponds to the private IPv4 range. This range is so large that (if the prefixes are randomly generated) there is normally no collision for example with the dn42.
It uses the babel routing protocol
Babel is actually used for IGP, but it is also possible to connect networks with it. The routing becomes so more efficient that as selection criterion a metric is used, which corresponds in the reference implementation (babeld) to the latency in ms. Thus, the path with the shortest latency is always used. Also bird and frr have implemented babel in the meantime, but there the metric is (unfortunately) not calculated automatically. I made it so that I measure this at the beginning of a peering and then enter it manually. The problem is that latencies can change - for example when the underlay network (here the clearnet) changes.
It is small
If you don’t do strict validation of routes, you get about 20 IPv6 prefixes. If you do more strict validation, you get about 10 prefixes. With dn42 (+ NeoNetwork + IC-VPN + ChaosVPN) there are about 600 prefixes.
It uses fastd
In dn42, WireGuard is normally used for peering, as it is easy to configure and provides good security. Before that OpenVPN was used. OpenVPN is slower and less secure when used with a preshared key (PSK). fastd is also used by Freifunk / IC-VPN. It is also a tunnel solution, which is also encrypted with good security. In contrast to WireGuard, it operates on layer 2 of the OSI model (MAC addresses), whereas WireGuard operates on layer 3 (IP addresses).
Multiple nets on one node
Multiple nets on one node - there are different solutions for this. One solution would be to use multiple bird instances. For this solution I don’t have the knowledge and it is too complex for me.
Another solution would be to use different routing tables. So you could use
ipv6 table crxn; to create a second IPv6 routing table. This approach becomes problematic if you - like me - have several nodes which are connected via iBGP. I would have to have twice as many BGP sessions as I do now, since multiple routing tables cannot be transmitted in one BGP session.
Another option is to “tag” routes. On import, the dn42 routes would be tagged with “dn42” and the CRXN routes would be tagged with “crxn”. When exporting, you could now assign each route to the appropriate network. There are several ways to tag a route. The most common one is to append BGP Communities or Large BGP Communities (for 32-bit ASNs) to the route. However, since dn42 peers only expect dn42 routes, the information that these are dn42 routes is unnecessary and would only take up space in the Global Routing Table. This means you would have to delete the corresponding communities on export.
The next problem with communities was that I have two AS numbers. One from dn42 and one from NeoNetwork. Which one should I use to tag the routes? Since it would be internal only, it wouldn’t matter.
An alternative to the BGP communities are user defined BGP attributes. A BGP attribute is for example
bgp_med, but you can also define them yourself. I decided to use this option. I created a new integer attribute named
attribute int netid;. If the route gets from the dn42 net, it gets the id
1. If the route comes from the CRXN network, it gets the ID
2. Accordingly I have to filter the other network during export. So I have all routes in one routing table and tagged them accordingly.
Missing validation of routes
In dn42 you can generate ROA entries from the registry. In these it is written, which AS, which prefixes and with which length may announce. In CRXN, however, there are no AS numbers, which is why ROA filtering is out of the question. As registry there is only an
entitydb, in which name of the network and prefix of the network is indicated. The files in it are in JSON format. The only validation I can do is to say that non-CRXN prefixes are not exported. The prefixes which are allowed I parse again from the
entitydb. All other routes I discard.
A possible networking with the dn42 is planned. There should be an ASN, which has the authorization to export all CRXN routes. With appropriate configuration, one could establish so several gateways between the dn42 and the CRXN. It remains exciting.
- entitydb: https://codeberg.org/CRXN/entitydb
- CRXN documentation: http://deavmi.assigned.network/projects/crxn/
- CRXN documentation mirror: https://crxn.de/docs/
- fastd documentation: https://fastd.readthedocs.io/en/stable/index.html