Open-source project
tonarino/innernet avatar
tonarino/innernet

innernet: WireGuard with CIDR-based ACLs, and how to run the coordination server

A private network system that uses WireGuard under the hood.

5,554 stars214 forksRustMIT

At a glance

What is it?
innernet is a private network system built on WireGuard that turns ordinary IP CIDRs into access control groups. This review covers the coordination server model, the install path, and where the design gets in your way.
Who is it for?
innernet fits teams that already think in CIDRs, want to run their own coordination server, and accept that peer addresses are permanent. It is the wrong tool if you need a managed control plane, a security audit trail, or a Windows client.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 65 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What problem innernet solves, and for whom

WireGuard gives you encrypted point-to-point tunnels. It does not give you a way to decide which peers may talk to which, or a way to hand a new machine a working configuration without editing files by hand on both ends. innernet fills that gap. The README describes it as "a private network system that uses WireGuard under the hood," and the mechanism it adds on top is the CIDR. A network has a root CIDR, for example 10.60.0.0/16, and you carve named CIDRs out of it: a humans CIDR, a ci-servers CIDR. Peers live inside a CIDR. Access between CIDRs is not automatic; two CIDRs have to be associated before peers in one can reach peers in the other. That is the whole access control model, and it is deliberately coarse. If you want per-port rules or identity-based policy, this is not the abstraction you are looking for. The intended user is someone comfortable with IP networking who wants the coordination server to live on their own hardware. The README compares the goals to Slack's nebula and to Tailscale, and then says innernet "takes a bit of a different approach": it leans on existing networking concepts and WireGuard's security properties instead of inventing a new identity layer. The README is also explicit that this "has not received an independent security audit, and should be considered experimental software at this early point in its lifetime." Treat that sentence as part of the feature list.

The coordination server and the invitation file

Every network needs a coordination server. Its job is to manage peers and hand out endpoint information so peers can connect to each other directly. The traffic itself is WireGuard; the server is control plane, not data plane. The lifecycle of a peer is what makes this design concrete. An admin runs add-peer on the server, and the CLI produces an invitation file. That file contains just enough information for the new peer to reach the server and redeem the invitation. The README states it should be transferred securely and that it can only be used once. On the peer side, install reads the invitation, connects to the server over WireGuard, generates a new key pair, and registers that pair. The private key in the invitation file can no longer be used afterward. Adding a peer is therefore a two-party operation with a single-use credential in the middle, which is a cleaner story than copying a static config around. The repository layout reflects the split: server/, client/, client-core/, shared/, plus smaller crates such as hostsfile/, publicip/, netlink-request/, and wireguard-control/. The Cargo.toml workspace lists server, client, client-core, hostsfile, shared, publicip and netlink-request as members, and pins netlink-packet-wireguard and netlink-packet-route, which tells you the Linux path talks to WireGuard through netlink rather than by shelling out to wg. The release profile uses lto = "fat", codegen-units = 1, opt-level = "s" and panic = "abort", so the shipped binaries are size-oriented, not tuned for throughput.

Installing innernet and getting a first peer onto the network

The README does not document a package installation step, so where you get the binaries depends on your distribution or on building from the Rust workspace. What it does document is the sequence after you have the two binaries, innernet-server and innernet. Start by creating the network on the machine that will act as the coordination server. The init wizard asks questions about your network and offers defaults, and the README suggests familiarizing yourself with network CIDRs first because access control is based on them.

bash
sudo innernet-server new

Next create a CIDR to hold peers. The README's example uses a root CIDR of 10.60.0.0/16 and adds a humans CIDR at 10.60.64.0/24, with the parent set to the network's root CIDR. By default, peers in a new CIDR can reach only peers in the same CIDR plus the special infra CIDR created at server initialization, which contains the server itself.

bash
sudo innernet-server add-cidr <interface>

Now add an admin peer. The CLI suggests the next available IP address, and you answer yes when asked whether the peer should be an admin. The output is an invitation file; move it to the new machine over a channel you trust, since it works once.

bash
sudo innernet-server add-peer <interface>

On the peer, install from the invitation. innernet connects to the server over WireGuard, generates a key pair, and registers it. You can change the network name at the prompt or accept the default.

bash
sudo innernet install /path/to/invitation.toml

Confirm the peer is on the network and inspect the CIDR tree:

bash
sudo innernet list --tree

To run the server as a service on Linux, the README gives systemctl enable --now innernet-server@<interface>. If the server sits behind a home router, the README notes you must configure port forwarding to the Listen Port chosen during server creation. From the admin peer you can then run add-cidr, add-peer and add-association through the innernet client instead of going back to the server host.

Associations, disabled peers and the immutability trade-off

Peers in different CIDRs cannot talk until the CIDRs are associated. The admin peer runs add-association, selects two CIDRs, and that is the entire operation. list-associations shows the current set and delete-associations removes one. This is easy to reason about, and it is also the sharpest limitation in the design. There is no per-peer exception inside a CIDR pair: association is all-or-nothing at CIDR granularity. If you want one host in humans to reach one host in ci-servers and nothing else, you have to reorganize your CIDRs, not write a rule.

The second trade-off is address permanence. The README states that for security reasons IP addresses cannot be re-used by new peers, and therefore peers cannot be deleted. They can be disabled instead, and disabled peers do not appear in the peer list when a client fetches its config. enable-peer reverses it. The practical consequence is that your address space only moves in one direction. A network that churns through contractors or short-lived CI runners will accumulate disabled entries forever, and the CIDR sizing you chose on day one becomes a ceiling you cannot lower. That is a deliberate choice, and it is worth deciding whether you agree with it before you pick 10.60.64.0/24 for your humans.

Two smaller escape hatches exist for connectivity problems. override-endpoint sets an explicit internet endpoint for a peer when the server's automatic discovery of the endpoint it sees from that peer does not work; override-endpoint -u returns to automatic discovery. set-listen-port changes the local WireGuard listen port, and set-listen-port -u returns to a randomized port.

Security posture and what the README asks you to do

The README's security section leads with strict Reverse Path Filtering per RFC 3704. Strict RPF prevents packets arriving on other interfaces from carrying internal source IP addresses, and the README states plainly that this is not the default on Linux. That is the kind of note that separates a project written by people running it from one written as a demo. It also tells you the threat model: innernet is not trying to be a zero-trust identity broker, it is trying to make your host's IP stack enforce the boundaries you drew. If a packet with an internal source address can arrive over your public interface, the CIDR model is only as strong as the host configuration underneath it.

The README's own disclaimer belongs in the same paragraph. There has been no independent security audit, and the project calls itself experimental. Nothing in the repository contradicts that, and the release history does not suggest a stabilization push: v2.0.0 landed on 2026-07-02, after v1.7.1 on 2025-11-10 and v1.7.0 on 2025-08-13. The last push to the repository was on 2026-07-28, so development is recent, but a major version bump with a disclaimer like that one deserves a read of the release notes before you put it in front of production traffic. The licence is MIT, which is permissive and places few obligations on how you redistribute or embed the code; the LICENSE file sits at the repository root. Nothing here is legal advice, and if you ship innernet inside a product, your own counsel should read the MIT text rather than this paragraph.

How innernet differs from Tailscale and nebula

The README names two points of comparison itself: Slack's nebula and Tailscale. The difference is where policy lives. Tailscale is a managed service with an identity provider in the loop; you authenticate users and devices through an external IdP and the control plane is operated for you. innernet has no identity provider. It has a coordination server you run, and policy is expressed as CIDR associations in that server's database. If your organization already has SSO and expects device posture checks, innernet is a step backward in convenience and a step forward in independence.

nebula is closer in spirit: self-hosted, certificate-based, with its own lighthouse nodes for discovery. The meaningful contrast is the policy primitive. nebula's model is built around host certificates and firewall rules you write per host; innernet's model is the CIDR, and the README frames that as the point, aiming to "turn your computer's basic IP networking into more powerful ACL primitives." If your mental model is subnets and routing tables, innernet will feel native. If your mental model is identities and groups, you will spend your time translating.

One more practical difference sits in the repository rather than the README. The workspace pins netlink-packet-wireguard and netlink-packet-route and includes a wireguard-control crate, which points at a Linux netlink integration. The README's own instructions assume sudo throughout and mention systemctl for the server. Teams with a mixed Windows and macOS fleet should confirm the client story on each platform before committing, because the documented workflow is written for hosts where you control the interface configuration.

Maintenance, upgrades and what to check before you commit

The last push was on 2026-07-28, and v2.0.0 was released on 2026-07-02. Two minor releases preceded it, v1.7.1 on 2025-11-10 and v1.7.0 on 2025-08-13. That is a slow but real cadence, roughly one or two tagged releases a year. The README's badge claims active maintenance, and the push date is consistent with that, but the gap between v1.7.1 and v2.0.0 is about eight months, so plan upgrades around releases rather than expecting continuous fixes.

The upgrade cost has one hard edge that the README makes clear: innernet-server uninstall <interface> permanently removes a created network, and the README says to use it with care. There is no documented rollback path for a network, and because peers cannot be deleted and addresses cannot be re-used, a botched re-create is not a clean reset. The README does not document a migration procedure between major versions, so the honest position is that v1 to v2 upgrades should be tested on a throwaway network first. On the client side, hostsfile/ in the workspace suggests the client manages host entries for peer names, which means an upgrade can touch files outside the WireGuard config; check what innernet list shows after upgrading before assuming the names resolve. The MIT licence keeps the legal surface small, and the README's trademark note is worth repeating: innernet is not an official WireGuard project, and WireGuard is a registered trademark of Jason A. Donenfeld.

Editorial conclusion

innernet fits teams that already think in CIDRs, want to run their own coordination server, and accept that peer addresses are permanent. It is the wrong tool if you need a managed control plane, a security audit trail, or a Windows client. Before adopting it, verify that your kernel or userspace WireGuard path works on every OS you plan to run, read the security recommendations in the README about strict Reverse Path Filtering, and confirm the release cadence of v2.0.0 (2026-07-02) against your own upgrade window.

Frequently asked questions

Does innernet require a central server?

Yes. The README states that every innernet network needs a coordination server to manage peers and provide endpoint information so peers can connect to each other directly. The server is control plane only; peer traffic runs over WireGuard.

Can I delete a peer in innernet?

No. The README says that for security reasons IP addresses cannot be re-used by new peers and therefore peers cannot be deleted. They can be disabled with disable-peer, and disabled peers do not show up when a client fetches its config.

How do two CIDRs in innernet talk to each other?

They must be associated. Running add-association on an admin peer and selecting the two CIDRs is enough to let peers in those CIDRs communicate, and list-associations shows the current set.

Is innernet related to the word inner or the InnerWeb?

No. innernet is the name of a private network system that uses WireGuard under the hood, and the README describes it as similar in goals to nebula and Tailscale. Questions about the meaning of inner or the InnerWeb refer to something else entirely.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. tonarino/innernet on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/tonarino-innernet.svg)](https://hysenlabs.com/projects/tonarino-innernet)