[WIP] A framework for automating networking with OpenWRT
obviously heavily WIP, we'll need a lot more basic features before this can be merged. This would require the router to use OpenWRT and expose ubus RPC to a network interface the host rhzyome is running on has access to. The OpenWRT RPC interface uses https with a self signed cert by default. Rather than disable https, we should use step and let rhyzome validate the certificate of the router.
- networks are a new first class thing that can be created/(unsupported: read/updated/deleted).
- I'm calling these "managables" and built out a little bit of stuff that can be used for manageable generally. I might remove that to prevent scope creep of the MR.
- currently there are no options for customizing the network parameters, but lots of stuff is hard coded in rhyzome and can easily be changed to be configurable.
- All networks use subnet 192.168.0.0/24 with the router and DNS server at 192.168.1.1
- All networks have a DHCP server that will assign IPs between .10 and .100
- when creating an instance, you must specify an existing network or a new network will be created
- I would like to update the instance creation process to assign new instances a static DHCP lease before they boot, which would allow us to show the IP before the instance DHCPs
- Unclear if we can get OpenWRT to pick the IP, otherwise rhyzome will have to query existing static leases and pick a new one that isn't already taken.
- OpenWRT can be configured to operate a wireguard node. I haven't actually checked everything but I'm pretty sure we could allow clients to configure which networks they have access to.
- Because of the way uci works, we need to lock access to the router while updates occur. There is currently no mechanism to do this, which could cause problems. We make several requests to update the config then commit it, and need to make sure two updates don't happen at once.
- There is no failsafe. Netowrk creation failure should result in a network cleanup.
- When OpenWRT RPC calls fail they return a non-zero exit code. There is currently no detection for this, which could be a problem.
- If there is an error before we can call
owrt.UCICommit()we should revert the UCI changes.
- There is no client support yet
- There are some challenges around OpenWRT network names. The firewall zone name has to be 10 characters (or less). Interface names can be a few characters more than that. Neither of these can have any (maybe just most) non-alphanumeric characters. Currently I solve this in two ways: first by changing how the global GenerateID() function works to result in shorter identifiers with a smaller range of characters. Second, for the firewall name, i just take a substring of the identifier. I'm not sure if this is really a good idea and I think shortening the global ID length more is probably a good idea. As it stands, these already shortened identifiers look like AWS identifiers. Example:
Must fix before merge:
Out of the box there is no good way to access a newly created instance. There are a number of ways we could solve this, some that come to mind:
- Make an easy way to automatically configure a default network for new instances in the rhyzomectl config and a way make a wireguard connection into these networks
- New instances are assigned an SSH port and a port-forward is automatically configured. I don't like this option but it would be a lot easier
- Deleting a network doesn't clean up anything in OpenWRT
- rhyzomectl needs to be able to create/delete networks as well as configure networks for new instances
Several changes to secure stuff:
- a CA has to be configured and the path to the root cert updated.
- OpenWRT RPC credentials need to be set in OpenWRT and provided to rhyzome. Not 100% sure how I want to make this happen yet