Introduction & Problem Statement
Ever since starting my homelab, the networking side has been one of the more interesting ones and more painful ones to manage. One of the key problems in networking is there seem to be various moving pieces that all need to align on two key points, IP and DNS name to allow the network to function. These two points however involve at least three moving pieces, the host that has the interface that will be bound to the IP, the DHCP server that gives out the IP, and the DNS server that maps the IP to the host. However, there is no ready made API to ensure that this mapping is always consistent, which is especially difficult for the case of distributing IPs and DHCP. For an enterprise, one might have a set policy to hand out IPs and some sort of operational structure. Within a homelab, this might be far more difficult to achieve. Ideally, one would have all three pieces talk to eachother to ensure that all components are always updated and that there are no conflicts. But what if there is a conflict? If the DNS record doesn't match up with the machines hostname, or there are overlaps in IP space, which element is right? Should the DHCP win or the virtual machine using the IP? As such, the problem statement is as follows: ''How to ensure that IP allocation and DNS have a consistent, auto-updating view of the network?''
For my personal setup, Proxmox as compute platform with an EdgeMax Lite router serving DHCP and DNS, this comes the added operational overhead of having to update them both whenever I make some sort of new guest on the Proxmox machine. Thus this project was born. I wanted to ensure someway to keep consistency and introduce a source of truth that the other moving pieces will update from and will have to adhere to. Due to my environment being a homelab, I have no strict requirements, and I mostly will bother myself if I do something wrong.
The core of my solution unfortunately involves adding another moving piece, namely an IPAM solution. This IPAM solution would be the aggerate source of truth, from which the other pieces in the system would derive their desired state. This should hopefully give me a single consistent view of my DNS and IP space in the DNS manager, which would accurately reflect the state in both the compute platform and the routing/DNS platform. The key point in adding this IPAM would be that it needs to be fully automated from the view of the compute. Whenever a new guest would be spun up, the IPAM should gather this state, and assuming no conflicts, push this new state back to the networking layer and check for consistency.
With this given problem and solution outline, I could come up with the requirements of the system that would have to be built:
- Automatic configuration of the EdgeMax DHCP platform
- Discovery of new guests on the DHCP platform
- Automatic configuration of the EdgeMax DNSmasq DNS platform
- Automatic data acquisition of the Proxmox networking configuration
- IPAM with consistent data from EdgeMax and Proxmox
- Service that runs standalone which can hook into both platforms to ensure state
One of the downsides of a homelab is that not all equipment is always up to enterprise standards (although what those are is also debatable). The EdgeMax router platform has a solid feature set, but no API to interface with the configuration system. This is not uncommon of course, but mean that I would have ot rely on SSH and text scraping for configuration. For enterprise class devices, NAPALM (https://github.com/napalm-automation-community) exists, which allows for some sort of configuration control on supported devices. For the EdgeMax platform in my lab, I could likely make use of the Vyos driver (since EdgeMax is a Vyatta derviative)(https://github.com/napalm-automation-community/napalm-vyos)
Proxmox however is much better, with a very solid REST API and just as important, very good documentation with clear examples of what data you will get(https://pve.proxmox.com/pve-docs/api-viewer/index.html). This left me with the choice of IPAM solution and the language to build the integrations with. I settled on Nipap, for three simple reasons. No bloat, solid simple API, GUI that requires very little clicks (http://spritelink.github.io/NIPAP/). I'm running a homelab, I do not need fancy features or deployments. The system needs to run and I need to be able to interact with via an API for automation and a GUI to just have a look at my network. Another big advantage for Nipap is that it is written in Python and open source, so I could check any part of the API and understand it. (This turned out to be a big advantage when debugging the API)
Conclusion & Plans
This post just serves as a reference for the coming project, which I might update to further outline the architecture or changes that will I undoubtedly make. I do not aim to build the perfect system or make it suitable for more needs than just my own. However, I do want it to be a solid piece of software that I can run with minimal operational overhead and hopefully learn a thing or two in the process regarding sources of truth and how to manage network state.
Sources & Links