{"id":13469016,"url":"https://github.com/tonarino/innernet","last_synced_at":"2025-05-14T22:04:43.155Z","repository":{"id":39412458,"uuid":"352725385","full_name":"tonarino/innernet","owner":"tonarino","description":"A private network system that uses WireGuard under the hood.","archived":false,"fork":false,"pushed_at":"2025-04-08T03:37:33.000Z","size":855,"stargazers_count":5177,"open_issues_count":95,"forks_count":196,"subscribers_count":61,"default_branch":"main","last_synced_at":"2025-05-07T21:14:52.931Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://blog.tonari.no/introducing-innernet","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tonarino.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-03-29T17:17:27.000Z","updated_at":"2025-05-07T16:05:14.000Z","dependencies_parsed_at":"2023-12-27T04:51:11.316Z","dependency_job_id":"6a7d21f2-4e8f-4ac4-83ed-1d13ae0869bd","html_url":"https://github.com/tonarino/innernet","commit_stats":{"total_commits":335,"total_committers":33,"mean_commits":"10.151515151515152","dds":"0.28059701492537314","last_synced_commit":"85c8cc37ecf71372fb0833f0b5e5567b32235353"},"previous_names":[],"tags_count":45,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonarino%2Finnernet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonarino%2Finnernet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonarino%2Finnernet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonarino%2Finnernet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tonarino","download_url":"https://codeload.github.com/tonarino/innernet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254235686,"owners_count":22036962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T15:01:24.513Z","updated_at":"2025-05-14T22:04:43.016Z","avatar_url":"https://github.com/tonarino.png","language":"Rust","funding_links":[],"categories":["Rust","Proxy and VPN","Web and Cloud Security","Applications","others","Apps","Transport-layer defenses","Projects","Security"],"sub_categories":["Python","Cloud and Infrastructure","Networking","Overlay and Virtual Private Networks (VPNs)","Mesh Network","VPN"],"readme":"# innernet\n\n[![Actively Maintained](https://img.shields.io/badge/Maintenance%20Level-Actively%20Maintained-green.svg)](https://gist.github.com/cheerfulstoic/d107229326a01ff0f333a1d3476e068d)\n[![MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/tonarino/innernet/blob/master/LICENSE)\n\nA private network system that uses [WireGuard](https://wireguard.com) under the hood. See the [announcement blog post](https://blog.tonari.no/introducing-innernet) for a longer-winded explanation.\n\n\u003cimg src=\"https://user-images.githubusercontent.com/373823/118917068-09ae7700-b96b-11eb-80f4-6860072d504d.gif\" width=\"600\" height=\"370\"\u003e\n\n`innernet` is similar in its goals to Slack's [nebula](https://github.com/slackhq/nebula) or [Tailscale](https://tailscale.com/), but takes a bit of a different approach. It aims to take advantage of existing networking concepts like CIDRs and the security properties of WireGuard to turn your computer's basic IP networking into more powerful ACL primitives.\n\n`innernet` is not an official WireGuard project, and WireGuard is a registered trademark of Jason A. Donenfeld.\n\nThis has not received an independent security audit, and should be considered experimental software at this early point in its lifetime.\n\n## Usage\n\n### Server Creation\n\nEvery `innernet` network needs a coordination server to manage peers and provide endpoint information so peers can directly connect to each other. Create a new one with\n\n```sh\nsudo innernet-server new\n```\n\nThe init wizard will ask you questions about your network and give you some reasonable defaults. It's good to familiarize yourself with [network CIDRs](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) as a lot of innernet's access control is based upon them. As an example, let's say the root CIDR for this network is `10.60.0.0/16`. Server initialization creates a special \"infra\" CIDR which contains the `innernet` server itself and is reachable from all CIDRs on the network.\n\nNext we'll also create a `humans` CIDR where we can start adding some peers.\n\n```sh\nsudo innernet-server add-cidr \u003cinterface\u003e\n```\n\nFor the parent CIDR, you can simply choose your network's root CIDR. The name will be `humans`, and the CIDR will be `10.60.64.0/24` (not a great example unless you only want to support 256 humans, but it works for now...).\n\nBy default, peers which exist in this new CIDR will only be able to contact peers in the same CIDR, and the special \"infra\" CIDR which was created when the server was initialized.\n\nA typical workflow for creating a new network is to create an admin peer from the `innernet-server` CLI, and then continue using that admin peer via the `innernet` client CLI to add any further peers or network CIDRs.\n\n```sh\nsudo innernet-server add-peer \u003cinterface\u003e\n```\n\nSelect the `humans` CIDR, and the CLI will automatically suggest the next available IP address. Any name is fine, just answer \"yes\" when asked if you would like to make the peer an admin. The process of adding a peer results in an invitation file. This file contains just enough information for the new peer to contact the `innernet` server and redeem its invitation. It should be transferred securely to the new peer, and it can only be used once to initialize the peer.\n\nYou can run the server with `innernet-server serve \u003cinterface\u003e`, or if you're on Linux and want to run it via `systemctl`, run `systemctl enable --now innernet-server@\u003cinterface\u003e`. If you're on a home network, don't forget to configure port forwarding to the `Listen Port` you specified when creating the `innernet` server.\n\n### Peer Initialization\n\nLet's assume the invitation file generated in the steps above have been transferred to the machine a network admin will be using.\n\nYou can initialize the client with\n\n```sh\nsudo innernet install /path/to/invitation.toml\n```\n\nYou can customize the network name if you want to, or leave it at the default. `innernet` will then connect to the `innernet` server via WireGuard, generate a new key pair, and register that pair with the server. The private key in the invitation file can no longer be used.\n\nIf everything was successful, the new peer is on the network. You can run things like\n\n```sh\nsudo innernet list\n```\n\nor\n\n```sh\nsudo innernet list --tree\n```\n\nto view the current network and all CIDRs visible to this peer.\n\nSince we created an admin peer, we can also add new peers and CIDRs from this peer via `innernet` instead of having to always run commands on the server.\n\n### Adding Associations between CIDRs\n\nIn order for peers from one CIDR to be able to contact peers in another CIDR, those two CIDRs must be \"associated\" with each other.\n\nWith the admin peer we created above, let's add a new CIDR for some theoretical CI servers we have.\n\n```sh\nsudo innernet add-cidr \u003cinterface\u003e\n```\n\nThe name is `ci-servers` and the CIDR is `10.60.64.0/24`, but for this example it can be anything.\n\nFor now, we want peers in the `humans` CIDR to be able to access peers in the `ci-servers` CIDR.\n\n```sh\nsudo innernet add-association \u003cinterface\u003e\n```\n\nThe CLI will ask you to select the two CIDRs you want to associate. That's all it takes to allow peers in two different CIDRs to communicate!\n\nYou can verify the association with\n\n```sh\nsudo innernet list-associations \u003cinterface\u003e\n```\n\nand associations can be deleted with\n\n```sh\nsudo innernet delete-associations \u003cinterface\u003e\n```\n\n### Enabling/Disabling Peers\n\nFor security reasons, IP addresses cannot be re-used by new peers, and therefore peers cannot be deleted. However, they can be disabled. Disabled peers will not show up in the list of peers when fetching the config for an interface.\n\nDisable a peer with\n\n```su\nsudo innernet disable-peer \u003cinterface\u003e\n```\n\nOr re-enable a peer with\n\n```su\nsudo innernet enable-peer \u003cinterface\u003e\n```\n\n### Specifying a Manual Endpoint\n\nThe `innernet` server will try to use the internet endpoint it sees from a peer so other peers can connect to that peer as well. This doesn't always work and you may want to set an endpoint explicitly. To set an endpoint, use\n\n```sh\nsudo innernet override-endpoint \u003cinterface\u003e\n```\n\nYou can go back to automatic endpoint discovery with\n\n```sh\nsudo innernet override-endpoint -u \u003cinterface\u003e\n```\n\n### Setting the Local WireGuard Listen Port\n\nIf you want to change the port which WireGuard listens on, use\n\n```sh\nsudo innernet set-listen-port \u003cinterface\u003e\n```\n\nor unset the port and use a randomized port with\n\n```sh\nsudo innernet set-listen-port -u \u003cinterface\u003e\n```\n\n### Remove Network\n\nTo permanently uninstall a created network, use\n\n```sh\nsudo innernet-server uninstall \u003cinterface\u003e\n```\n\nUse with care!\n\n## Security recommendations\n\nIf you're running a service on innernet, there are some important security considerations.\n\n### Enable strict Reverse Path Filtering ([RFC 3704](https://tools.ietf.org/html/rfc3704))\n\nStrict RPF prevents packets from _other_ interfaces from having internal source IP addresses. This is _not_ the default on Linux, even though it is the right choice for 99.99% of situations. You can enable it by adding the following to a `/etc/sysctl.d/60-network-security.conf`:\n\n```\nnet.ipv4.conf.all.rp_filter=1\nnet.ipv4.conf.default.rp_filter=1\n```\n\n### Bind to the WireGuard device\n\nIf possible, to _ensure_ that packets are only ever transmitted over the WireGuard interface, it's recommended that you use `SO_BINDTODEVICE` on Linux or `IP_BOUND_IF` on macOS/BSDs. If you have strict reverse path filtering, though, this is less of a concern.\n\n### IP addresses alone often aren't enough authentication\n\nEven following all the above precautions, rogue applications on a peer's machines could be able to make requests on their behalf unless you add extra layers of authentication to mitigate this CSRF-type vector.\n\nIt's recommended that you carefully consider this possibility before deciding that the source IP is sufficient for your authentication needs on a service.\n\n## Installation\n\ninnernet has only officially been tested on Linux and MacOS, but we hope to support as many platforms as is feasible!\n\n### Runtime Dependencies\n\nIt's assumed that WireGuard is installed on your system, either via the kernel module in Linux 5.6 and later, or via the [`wireguard-go`](https://git.zx2c4.com/wireguard-go/about/) userspace implementation.\n\n[WireGuard Installation Instructions](https://www.wireguard.com/install/)\n\n### Arch Linux\n\n```sh\npacman -S innernet\n```\n\n### Debian and Ubuntu\n\n[**@tommie**](https://github.com/tommie) is kindly providing Debian/Ubuntu innernet builds in the https://github.com/tommie/innernet-debian repository.\n\n### Other Linux Distributions\n\nWe're looking for volunteers who are able to set up external builds for popular distributions. Please see issue [#203](https://github.com/tonarino/innernet/issues/203).\n\n### macOS\n\n```sh\nbrew install tonarino/innernet/innernet\n```\n\n### Cargo\n\n```sh\n# to install innernet:\ncargo install --git https://github.com/tonarino/innernet --tag v1.6.1 client\n\n# to install innernet-server:\ncargo install --git https://github.com/tonarino/innernet --tag v1.6.1 innernet-server\n```\n\nNote that you'll be responsible for updating manually.\n\n## Development\n\n### Cargo build feature for SELinux\n\nIf your target system uses SELinux, you will want to enable the 'selinux' feature when building the innernet binary.\nThis will ensure that innernet maintains the correct selinux context on the /etc/hosts file when adding hosts.  To do so add ```--features selinux``` to the ```cargo build``` options.\nThe `selinux-devel` package will need to be installed for the correct headers.\n\n### `innernet-server` Build dependencies\n\n- `rustc` / `cargo` (version 1.50.0 or higher)\n- `libclang` (see more info at [https://crates.io/crates/clang-sys](https://crates.io/crates/clang-sys))\n- `libsqlite3`\n\nBuild:\n\n```sh\ncargo build --release --bin innernet-server\n```\n\nThe resulting binary will be located at `./target/release/innernet-server`\n\n### `innernet` Client CLI Build dependencies\n\n- `rustc` / `cargo` (version 1.50.0 or higher)\n- `libclang` (see more info at [https://crates.io/crates/clang-sys](https://crates.io/crates/clang-sys))\n\nBuild:\n\n```sh\ncargo build --release --bin innernet\n```\n\nThe resulting binary will be located at `./target/release/innernet`\n\n### Testing\n\nYou can manually invoke Docker-based tests assuming you have Docker daemon running. If you specify\n`--interactive` flag, it allows you to attach to the server and client innernet Docker\ncontainers, so you can test various innernet commands inside a sandboxed environment.\n\n```\ndocker-tests/build-docker-images.sh\ndocker-tests/run-docker-tests.sh [--interactive]\n```\n\nIf you are developing a new feature, please consider adding a new test case to `run-docker-tests.sh` ([example PR](https://github.com/tonarino/innernet/pull/310/files#diff-5d47ea0d379e45f35471e2afa48fdba09d2ca4bcf090e16bb1adccebea080081)).\n\n### Releases\n\nPlease run the release script from a Linux machine: generated shell completions depend on available wireguard backends and Mac doesn't support the `kernel` backend. \n\n1. Fetch and check-out the `main` branch.\n2. Run `./release.sh [patch|major|minor|rc]`\n3. Push the `main` branch and the created tag to the repo.\n4. Publish crates that have `publish = true` to crates.io.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftonarino%2Finnernet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftonarino%2Finnernet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftonarino%2Finnernet/lists"}