Minimal self-hosted WireGuard mesh overlay — direct-or-fail, IPv6-only, CA-gated
Project description
Greasewood
A minimal, self-hosted, greasy WireGuard mesh network.
Its one priority is being easy to reason about. It was built by someone who lovingly maintained a fleet of hand-written WireGuard/networkd text files far past the point of practicality, and wanted the simplest possible upgrade.
📖 Full documentation: cschlick.github.io/greasewood — quickstart, concepts, access control, TLS, operations, and the CLI/config reference. The docs/ pages are also browsable here in the repo.
- Private. Membership is gated by a certificate authority; revoke a node by not renewing it.
- Direct-or-fail. No routing, no relays. A link comes up directly or it honestly fails.
- IPv6 only overlay. The overlay is IPv6-only; the underlay may be IPv4 or IPv6.
- Linux-only. Leans heavily on systemd, nftables.
- Greasy. Uses the stock
wg/iptools over subprocess. - Named. Every node gets a
<host>.<mesh>.internalname and matching TLS certs from the same CA. - Policy-derived topology. Roles + an allow-only grant table control who talks to whom.
- Self-certifying addresses. A node's IPv6 address is a hash of its identity key.
- Service TLS. The same CA issues auto-renewing x509 certs for your services (Postgres, nginx, …).
- Offline-tolerant. The anchor can be down for a credential lifetime, nodes run from cache.
- Hands-off. Never automatically configures your main firewall. Port access control lives on a dedicated table.
- Auditable. Pure Python, one dependency. Fanatical logging.
- Self-contained. The coordination anchor is just a normal node. Any node can become the anchor.
Install
Requires Python 3.11+, the WireGuard tools (wg), and iproute2 (ip).
sudo apt install pipx wireguard-tools # Debian/Ubuntu; use your distro's pkg mgr
sudo pipx install --global greasewood
--global puts gw on root's PATH so sudo gw … resolves. Distro .deb/
.rpm packages and the bundled installer are also available — see the
install guide (and its first-run pitfalls, straight from
real fleets coming up).
Quickstart
# 1. On the anchor — holds the CA, serves enrollment:
sudo gw create mymesh # names live under *.mymesh.internal
# 2. Mint a join token (anchor), redeem it on the new machine:
sudo gw invite # prints a token
sudo gw join <token> # on the new node
# 3. Watch it link — the live, colored mesh dashboard:
sudo gw watch
create and join set up a managed systemd service, so the daemon stays up
across reboots. That's the whole loop. The quickstart
walks through what each step does (the CA, the enrollment "door", the reconcile
loop), and the live dashboard page shows gw watch in
action.
Prior art
The nearest full-featured projects are Tailscale, Nebula, and innernet. Next to greasewood they're all bigger systems that do more: routing, NAT traversal, multi-platform, etc. Greasewood aims to be a minimal alternative — the non-goals aren't missing, they're the point.
Testing & contributing
Unit tests run in ~30s with no privileges:
pip install -e '.[test]' && python -m pytest
The Podman-based integration/stress/chaos suites and the nightly Hypothesis tier are documented in docs/testing.md.
Security & operations
- Security — trust boundaries, what the 7-step check enforces, accepted risks, and the security-review results.
- Operations — moving the anchor, plus disaster SOPs:
compromised node, lost/leaked CA key, destroyed anchor, fleet-wide teardown,
and reading
gw diagnose.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file greasewood-0.1.4.tar.gz.
File metadata
- Download URL: greasewood-0.1.4.tar.gz
- Upload date:
- Size: 414.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e86f70542f5f9b6b634feb7fc6f50b4872fd76c43573e7813193a64f029e87a
|
|
| MD5 |
8ea01c938a4ff03cddf146bd1c35b1af
|
|
| BLAKE2b-256 |
68e5b4256f567957c930c8732a2c61deffbd726044e386a67f92231df5ec29e8
|
Provenance
The following attestation bundles were made for greasewood-0.1.4.tar.gz:
Publisher:
release.yml on cschlick/greasewood
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
greasewood-0.1.4.tar.gz -
Subject digest:
8e86f70542f5f9b6b634feb7fc6f50b4872fd76c43573e7813193a64f029e87a - Sigstore transparency entry: 2231644401
- Sigstore integration time:
-
Permalink:
cschlick/greasewood@ebede047ad1079dd965b9d19ecc602b12f99ceb5 -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/cschlick
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ebede047ad1079dd965b9d19ecc602b12f99ceb5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file greasewood-0.1.4-py3-none-any.whl.
File metadata
- Download URL: greasewood-0.1.4-py3-none-any.whl
- Upload date:
- Size: 250.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2cc895a3f69d22144ef947a5f916d26abc997ca22ce8cc8b4e7e7918a5b21562
|
|
| MD5 |
dafb7862348a6f298164229b07f1e7c2
|
|
| BLAKE2b-256 |
d8f9c02cd2f1d562d793510ce18df2206054f8f6b6e2eea7507867a752a31498
|
Provenance
The following attestation bundles were made for greasewood-0.1.4-py3-none-any.whl:
Publisher:
release.yml on cschlick/greasewood
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
greasewood-0.1.4-py3-none-any.whl -
Subject digest:
2cc895a3f69d22144ef947a5f916d26abc997ca22ce8cc8b4e7e7918a5b21562 - Sigstore transparency entry: 2231645317
- Sigstore integration time:
-
Permalink:
cschlick/greasewood@ebede047ad1079dd965b9d19ecc602b12f99ceb5 -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/cschlick
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ebede047ad1079dd965b9d19ecc602b12f99ceb5 -
Trigger Event:
push
-
Statement type: