<p>
  Hello, this is Jon The Nice Guy, and after 10 years of knowing
  about Hacker Public Radio, here is my first podcast for the
  network.</p>
<p>
  <br>
</p>
<p>
  Firstly, I want to give a shout out to my Admin Admin Podcast
  co-host Al, who I heard just a week-or-so ago talking about
  Proxmox! Glad to hear you're over here too!</p>
<p>
  <br>
</p>
<p>
  I wanted to record an episode on my ridiculously complicated DHCP
  setup at home. I'm not saying this is the right or even a good
  idea for anyone else, but it's something you might want to do.</p>
<p>
  <br>
</p>
<p>
  Firstly, a little about why I have a complicated DHCP setup, and
  it starts with the router my previous ISP gave me.</p>
<p>
  <br>
</p>
<p>
  My router could just about cope with serving DHCP, but at the time
  when I was experimenting with running services on my home lab, the
  DNS server on the router wouldn't return addresses for hosts on my
  network, just those on the public internet. This wasn't a great
  experience! So, I installed PiHole [1] - initially because I'd
  heard good things about it's ad blocking capabilities, but later
  because it was just a pretty and sensible DHCP and DNS server that
  I could do things with.</p>
<p>
  <br>
</p>
<p>
  Under the covers, PiHole is running DNSMasq [2], which means that
  all the configuration is plain text files that I can overwrite
  with Ansible [3].</p>
<p>
  <br>
</p>
<p>
  My PiHole was running on a Raspberry Pi 2 [4], in a lego-style
  case [5] plugged into the back of my router. And this was fine for
  a few months. And then it ran out of storage space, I changed
  jobs, my wife complained one too many times, and I reverted back
  to using the router's DHCPd and DNS. I also picked up either
  Nebula [6] or Tailscale [7] at around that time too, so I didn't
  need internal DNS to resolve to home services any more, and
  anything public I setup external DNS records pointing to the
  internal addresses. Job done.</p>
<p>
  <br>
</p>
<p>
  Scrub forward a couple of years, and when I changed jobs, I got a
  joining bonus which paid for me to get wired network around my
  house. I also setup my own Proxmox [8] cluster, which I documented
  on a post [9] on my blog [10]. Again, everything was peachy. I
  setup home assistant [11], which I expose on to the internet via a
  proxy on my VPS, and everything was still good... but things are a
  little more complicated now - I've got more stuff to keep track of
  and the router's DHCP server was struggling a little... but it was
  all OK.</p>
<p>
  <br>
</p>
<p>
  And then I changed ISP. My new ISP shipped a router running a
  customized version of OpenWRT [12], and I thought, finally, a good
  router! And then I realised I couldn't do *anything* sensible with
  it. It was so locked down, I couldn't even change the admin
  password without factory resetting it! Ugh. Within a couple of
  weeks my wife was complaining about random intermittent DNS
  requests failing, and I was seeing it too. So, I found on the
  Proxmox Helper Scripts [13] website that someone had put a script
  to setup a PiHole instance... So naturally, as I had two Proxmox
  Servers by this point, I ran two PiHole servers. This lasted a few
  months until I performed a system upgrade to the proxmox cluster
  and it took down both Proxmox cluster members at the same time and
  DNS fell off the network! I revived the Raspberry Pi 2 which now
  sits attached to the router again! Yes!</p>
<p>
  <br>
</p>
<p>
  Meanwhile, I was now getting more into IoT and I had several Tuya
  IoT devices connected over Wifi, and the 254 network addresses
  available in the /24 sized network [14] to me at home didn't seem
  enough, so I decided to expand my network to a /22, giving me
  enough address space for 1022 devices. Plus, I have kids, who each
  have computers and phones and games devices, my wife and I both
  work from home, so we both have computers from work and our own
  devices too... so I decided, now is the time to plan out my
  network.</p>
<p>
  <br>
</p>
<p>
  I decided to use PHPIPAM [15] having been asked to look at it at
  work, and found it was a good fit for what I wanted to do with it.</p>
<p>
  <br>
</p>
<p>
  PHPIPAM is really designed for owners of large-scale networks,
  people who allocate chunks of public IP scopes and IPv6 address
  ranges, but it will subdivide smaller network blocks, and so I
  could carve up my network.</p>
<p>
  <br>
</p>
<p>
  I decided to split my /22 into four /24 networks. One was
  dedicated to DHCP addressed items, with one smaller subnet in
  there allocated to the Proxmox hosted PiHole and another to the
  Raspberry Pi hosted PiHole, and both are basically a catch-all for
  anything I've not yet allocated. One was for end-user devices,
  like phones, computers, TVs and Games Consoles separated into
  smaller subnets per-person and one additional subnet for
  room-shared devices like TVs and Games Consoles. One subnet was
  separated into smaller subnets for IoT devices and core network
  things, like mains and network switches, light bulbs, cameras and
  printers. The last /24 subnet was undivided, but was for servers,
  both physical and virtual.</p>
<p>
  <br>
</p>
<p>
  Great, I've now got a lovely network map [IMAGE1], but *ugh* I've
  got to transfer all those DHCP and static IP allocations to the
  PiHoles. And, while I'd been using Gravity Sync [15] to
  synchronize between the two PiHole devices, sometimes it took a
  while for Gravity Sync to sync.</p>
<p>
  <br>
</p>
<p>
  And over time, I wanted to expose some of those services I was
  running at home, to my family, at home.</p>
<p>
  <br>
</p>
<p>
  So, I turned to Ansible.</p>
<p>
  <br>
</p>
<p>
  A few years ago, I'd helped write some Ansible modules which were
  used to interact with a cloud service my employer at the time was
  running, so I had a kind of idea on how Ansible works under the
  surface, the documentation for writing a new set of lookups was
  OK, and ChatGPT helped where I lost my way.</p>
<p>
  <br>
</p>
<p>
  I knew that there was a Terraform [17] Provider [18] for PHPIPAM,
  so there was a working API... and so I knew I could look up data
  in PHPIPAM. I wrote some Ansible lookups [19] to confirm the data
  was accessible from PHPIPAM, and it was! Great, now all I needed
  to do was to drop files into PiHole.</p>
<p>
  <br>
</p>
<p>
  I'd heard Alex [20] from the Self Hosting Podcast [21] talking
  about how he wrote some Ansible to automate his PiHole management
  [22], but it assumed a lot about how your network was setup and
  integrated a lot with other things he did - no complaints there!
  It's his network after all! But so I knew I needed to do 5 things.</p>
<p>
  <br>
</p>
<p>
  1. Create a list of static DHCP allocations on both PiHole
  devices.</p>
<p>
  2. Create a list of DNS names to resolve in the internal network
  to addresses via A records</p>
<p>
  3. Create a list of DNS names to resolve to other DNS names via
  CNAME records</p>
<p>
  4. Create a list of DNS wildcards, so anything ending in that name
  would appear in my network.</p>
<p>
  5. If anything changed, restart DNSMasq.</p>
<p>
  <br>
</p>
<p>
  I wrote this code and ran it. Well, ran it and it didn't work, so
  I fixed it and ran it again... and again and again until it did
  work.</p>
<p>
  <br>
</p>
<p>
  I've just added that to my Github today, so feel free to take a
  look [23].</p>
<p>
  <br>
</p>
<p>
  You've spent a while listening to this, so what is my "too long,
  didn't listen"?</p>
<p>
  <br>
</p>
<p>
  I have two pihole devices, I run a phpipam service under docker on
  a LXC container on my proxmox server. On the same LXC container I
  have a cron job which triggers the ansible playbook every 5
  minutes to push any updates to PHPIPAM to the pihole hosts.</p>
<p>
  <br>
</p>
<p>
  Every few days I check to see what hosts have turned up in the
  DHCP pools on the PiHole hosts, map those to hosts I want to track
  in the future, and allocate them addresses in PHPIPAM so that
  those hosts will get managed IP addresses after 5 minutes, the
  next time they renew their DHCP addresses...</p>
<p>
  <br>
</p>
<p>
  Tada!</p>
<p>
  <br>
</p>
<p>
  For more over engineered solutions like this, feel free to take a
  look at the content on my blog, or maybe I'll appear again, on
  Hacker... Public... Radio.</p>
<p>
  <br>
</p>
<p>
  Take care, 73.</p>
<p>
  <br>
</p>
<br>
<p>
  [1] PiHole: <a moz-do-not-send="true" href="https://pi-hole.net/">https://pi-hole.net/</a></p>
<p>
  [2] DNSMasq: <a moz-do-not-send="true"
    href="https://thekelleys.org.uk/dnsmasq/doc.html">https://thekelleys.org.uk/dnsmasq/doc.html</a></p>
<p>
  [3] Ansible: <a moz-do-not-send="true" href="https://ansible.com">https://ansible.com</a></p>
<p>
  [4] Raspberry Pi: <a moz-do-not-send="true"
    href="https://www.raspberrypi.com/products/">https://www.raspberrypi.com/products/</a></p>
<p>
  [5] Lego style case: <a moz-do-not-send="true"
    href="https://www.amazon.co.uk/gp/product/B015WVR5BS">https://www.amazon.co.uk/gp/product/B015WVR5BS</a></p>
<p>
  [6] Nebula: <a moz-do-not-send="true"
    href="https://www.defined.net/">https://www.defined.net/</a></p>
<p>
  [7] Tailscale: <a moz-do-not-send="true"
    href="https://tailscale.com/">https://tailscale.com/</a></p>
<p>
  [8] Proxmox: <a moz-do-not-send="true"
    href="https://www.proxmox.com">https://www.proxmox.com</a></p>
<p>
  [9] Proxmox post: <a moz-do-not-send="true"
    href="https://jon.sprig.gs/blog/post/2885">https://jon.sprig.gs/blog/post/2885</a></p>
<p>
  [10] My blog: <a moz-do-not-send="true"
    href="https://jon.sprig.gs">https://jon.sprig.gs</a></p>
<p>
  [11] Home Assistant: <a moz-do-not-send="true"
    href="https://www.home-assistant.io/">https://www.home-assistant.io/</a></p>
<p>
  [12] OpenWRT: <a moz-do-not-send="true"
    href="https://openwrt.org/">https://openwrt.org/</a></p>
<p>
  [13] Helper Scripts: <a moz-do-not-send="true"
    href="https://community-scripts.github.io/ProxmoxVE/">https://community-scripts.github.io/ProxmoxVE/</a></p>
<p>
  [14] Network address spreadsheet: <a moz-do-not-send="true"
href="https://gist.github.com/JonTheNiceGuy/a847aa4faf878d7d6cee5c069e1d66d6">https://gist.github.com/JonTheNiceGuy/a847aa4faf878d7d6cee5c069e1d66d6</a></p>
<p>
  [15] PHPIPAM: <a moz-do-not-send="true"
    href="https://phpipam.net/">https://phpipam.net/</a></p>
<p>
  [16] Gravity Sync: <a moz-do-not-send="true"
    href="https://github.com/vmstan/gravity-sync">https://github.com/vmstan/gravity-sync</a></p>
<p>
  [17] Terraform: <a moz-do-not-send="true"
    href="https://www.terraform.io/">https://www.terraform.io/</a></p>
<p>
  [18] PHPIPAM Terraform Provider: <a moz-do-not-send="true"
    href="https://registry.terraform.io/providers/lord-kyron/phpipam/latest">https://registry.terraform.io/providers/lord-kyron/phpipam/latest</a></p>
<p>
  [19] Ansible Lookup: <a moz-do-not-send="true"
href="https://gist.github.com/JonTheNiceGuy/289a8a2e0233e730f0fbc8f958ec4bc6">https://gist.github.com/JonTheNiceGuy/289a8a2e0233e730f0fbc8f958ec4bc6</a></p>
<p>
  [20] Alex Kretzschmar: <a moz-do-not-send="true"
    href="https://alex.ktz.me/">https://alex.ktz.me/</a></p>
<p>
  [21] Self Hosted Podcast: <a moz-do-not-send="true"
    href="https://selfhosted.show/">https://selfhosted.show/</a></p>
<p>
  [22] Fully Automated DNS and DHCP with PiHole and DNSMasq: <a
    moz-do-not-send="true"
href="https://blog.ktz.me/fully-automated-dns-and-dhcp-with-pihole-and-dnsmasq/">https://blog.ktz.me/fully-automated-dns-and-dhcp-with-pihole-and-dnsmasq/</a></p>
<p>
  [23] ansible-pihole: <a moz-do-not-send="true"
    href="https://github.com/JonTheNiceGuy/ansible-pihole">https://github.com/JonTheNiceGuy/ansible-pihole</a></p>
<p>
  <br>
</p>
<p>
  [IMAGE1] <a moz-do-not-send="true"
href="https://jon.sprig.gs/blog/wp-content/uploads/2024/12/Screenshot-from-2024-12-20-19-29-22.png">https://jon.sprig.gs/blog/wp-content/uploads/2024/12/Screenshot-from-2024-12-20-19-29-22.png</a><br>
</p>
<p><a href="[IMAGE1]
https://jon.sprig.gs/blog/wp-content/uploads/2024/12/Screenshot-from-2024-12-20-19-29-22.png"><img
src="https://jon.sprig.gs/blog/wp-content/uploads/2024/12/Screenshot-from-2024-12-20-19-29-22.png"
alt="https://jon.sprig.gs/blog/wp-content/uploads/2024/12/Screenshot-from-2024-12-20-19-29-22.png"
      class="transparent" moz-do-not-send="true" height="539"
      border="0" width="232"></a>
  <meta http-equiv="content-type" content="text/html;
    charset=windows-1252">
</p>
