Hi everyone!
I did a thing
I’ve been enjoying NixOS for about a year now and I figure it’s about time I contribute my own project to the nix community: Wirenix. I encourage you to check out the wiki. I don’t want to spread out documentation across forum posts and chatrooms, so everything you need should be in there. If it isn’t, that’s a bug and you should raise an issue about it. You can also find the repo on sourcehut.
What is Wirenix?
Wirenix is a flake designed to take a single configuration file describing a (set of) virtual private networks, and generates the network configuration necessary on each machine to make it happen using Wiregaurd. It supports networkd, static network configurations, and generating secrets with agenix-rekey or reading them from files. Agenix automatically generates ipv6 addresses and adds them to the hosts file, but does support manual IP assignment as well. Wirenix can handle arbitrary network topologies, but is best suited for full mesh or hub and spoke networks. In addition, Wirenix is built to be modular, and you can plug in your own configuration format, output configuration generators, and secret providers if you need to.
What is not Wirenix?
Wirenix is not aiming to be a tailscale/headscale replacement. Those services already do a great job for connecting machines across NATs and Firewalls you don’t control, and are excellent choices for allowing users to connect to a network from any machine. Wirenix is instead meant to offer a simple (dare I say more robust?) setup for machines on networks you control to connect to eachother. Wirenix doesn’t handle any routing, NAT, DNS, DHCP, or anything else like that. There’s nothing stopping you from adding that on top of a Wirenix network, Wirenix won’t do it for you.
Me rambling if you’re into that
My personal motivation for this project comes from a need to secure certain parts of my home LAN (without an 802.1X capable switch):
- I could individually configure each peer with Wiregaurd, but that wouldn’t scale well, especially if I add containerized/virtualized services to my network.
- I could write some bespoke code for my particular configuration, but I wanted to keep my nix config simple and decoupled from any complex logic wiring peers together.
- I could have used tailscale or headscale, but these were essential parts of my LAN network, and I didn’t want more single points of failure in the form of control nodes.
- I could have secured all my services at a higher layer, which I do, but I use internal ACME for some services that don’t like other forms certificate distribution. As far as I can tell (I’m a bit of a novice here so don’t trust me), ACME relies on assumptions that DNS and IP addresses are secure. In the case of a home network without 802.1X, this isn’t true.
So I was left with the option of writing a nix flake to automate the tedious bits of setting up Wiregaurd. I was further convinced that writing a flake for the community to use was the right choice after asking around and hearing that many people in the nix community have solved this exact same problem in their own configs, but there was no generalized flake sufficiently decoupled from its corresponding nix configurations.
I was hoping to be further along with testing and stabilization before letting people know about this project, but the core features work, and I don’t want to hold off releasing it indefinitely just to finish that last 20% of work. If you run into any issues, which is likely, feel free to report them and I’ll make sure to give them some attention.
Thanks Everyone
As a recent member of the cult of Nix, I just wanted to thank everyone for this awesome and welcoming community. NixOS has seen some massive growth, I’m a part of that wave, and I’m sure there’s been some tension around that and difficulty maintaining the community. Even so, I’ve seen nothing but friendly, welcoming, slightly fanatical, people whenever I engage with the community (with some exceptions because it’s the internet). So here’s to everyone who enables (at least some) newbies like me to survive long enough to add something to the project. Now let the brutal unsolicited code reviews begin (because, again, it’s the internet)!