The Virtual Network We Have at Home
I like the theatre. It is an art form that requires so much planning, practice, and effort to conjure a world that disappears the moment the lights come up. Its ephemeral nature is part of its beauty. No matter how terrible, wonderful, or intriguing the characters are, they now exist only in our memories, and the echoes of what we have witnessed has become part of who we are.
Computers should be more like that sometimes.
In the course of my professional labours, I often find myself needing to test things out. Reproducing a problem, stress testing an edge case, etc. I use a lot of virtual machines. I’ve had VMWare setups, Xen, Proxmox, Multipass, and most recently, Incus. Incus has been really valuable lately. It has the same ease of use of multipass, but doesn’t require a whole lot of tweaking to get it working on various different linux distros.
Lately, I’ve been daily driving Debian on my laptops, and have PopOS on a desktop that acts as my home server. This is where I run my containerized homelab stuff, and my ephemeral VMs. Lately, I’ve tried using Incus containers to run some services. Why? Because I’m a nerd, and that’s the sort of things that nerds do.
Is it better than Docker? Who knows!?
Is it easier? Absolutely not!
Is it cooler? I would argue yes.
Why? Vibes!
Out of the box, Incus created it’s own NATed virtual network space in the 10/8 CIDR. This is fine, and maybe better for testing stuff. Keep it from colliding with my “normal” bits of load-bearing nonsense. But now, I wanted to run a server in there, and for that I need an IP Address that I can reach from outside the walled garden. Obviously, this is running Tailscale, and I can reach it from outside that way, but I’d like this to be accessible to everything on my home network, because this is going to be a DNS Server. Specifically a pihole DNS filter.
Ads are annoying, yes. But I can handle annoyances. The modern advertising ecosystem is also a security nightmare. The level of detail that these tracking sites can assemble about you is the sort of thing you expect in a distopian cyberpunk novel. At least in that world, you could get a tiny apartment in a neon-lit city centre while working part time as a data courier. But I’m wandering off. Ad networks are being used to target people, spread malware, and gaslight us into thinking that a $10 razor blade that has 5 blades somehow cuts better than a 25 cent razor blade that you can sharpen if you really want to. It’s a mess, it makes the internet barely useable for what I want to use it for, and I want to opt out as best I can. (close rant).
Where was I… Right! For whatever reasons that might be bubbling about in the darker caverns of my brain, I want to host my own DNS server. I want it accessible to the Tailscale network as well as the LAN, and I want to run it on Incus, because Incus has a cool name, and seems to do what I want it to. But first I need an IP Address.
The Incus documentation is comprehensive. I couldn’t find a straightforward way to do what I needed. It’s in there, I’m sure. I just couldn’t find it. I don’t have the patience for documentation. My parents blamed music videos, now that I’m the grumpy old man, I’ll blame TikTok. Once, the oldsters blamed novels. I think people just like distraction too much.
So after some monkeying around, some forums, some dumb luck, I think I have a recipe that is repeatable to have your Incus devices get LAN IPs by default.
I realize now that if you’re actually coming here looking for the pathway to do this, you’re probably wondering if I write recipes as well. Here’s my life story, with a recipe hidden inside! Not really, though I do talk about bread occasionally. But this isn’t a how-to guide, this is a how and why I did a thing story, that might actually help you get to the to through the how.
I’ll assume you have Incus installed and have done a thing or two with it. That’s where I started from.
My machine’s primary ethernet is enp4s0, and my LAN CIDR is 192.168.2.0/24. I’m running Pop!OS but anything debianish should probably track here.
I deleted the existing Incus network bridge, and started with:
incus network create bridge0 ipv4.address=none ipv6.address=none
The address lines mean that it’s not going to try to assign IP Addresses to these devices.
Then I bound a network bridge device to that with the ethernet card. Edit /etc/network/interfaces and add:
auto bridge0
iface bridge0 inet dhcp
bridge_ports enp4s0
bridge_stp off
bridge_fd 0
At this point, you will need to restart networking. You could just reboot, but I was logged in via ssh, and didn’t want to walk all the way over there in case something didn’t come back up, so I ran a script to do all the things while I was disconnected.
jay@marvin:~$ cat fixnetwork.sh
sudo ip link set enp4s0 down
sudo ip link set enp4s0 master bridge0
sudo ip link set enp4s0 up
sudo dhclient bridge0
That booted me out, and I was able to reconnect after a minute or so. Next will be to add the bridge network to the default Incus profile. This is going to be the way I want to use it going forward so I removed the old Incus eth0 device and ran:
incus profile device add default eth0 nic network=bridge0
Now when I do an incus launch images:debian/12 pihole the pihole device gets a 192.168.2.0/24 address, and I can ping it from other network tools. I can now have my TV box filtered. The various IoT devices, phones, whathaveyou.
But more importantly, I did a thing, and it worked! (Eventually).
Now my ephemeral computers that dance into existence for a brief moment for me to avoid asking the Duck about yum syntax or some such can have an IP address that suits my needs. And I can have a few fewer ads, snoops, and other nonsense peeking at me. Maybe I can’t win that fight, but I don’t have to make it easy for them.