A local-first userspace mesh VPN: Noise-encrypted UDP tunnels, WireGuard-compatible config, zero servers required. Ships the Rust binary as a console script, ruff-style.
Project description
ghostwire
A local-first userspace mesh VPN you fully own.
ghostwire is a zero-server mesh VPN toolkit for building encrypted peer-to-peer tunnels from local config. It generates WireGuard-compatible Curve25519 keys, plans full-mesh node configs, exports wg-quick files, and includes a pure-UDP encrypted datapath that can be tested without admin privileges.
Why
- Own your tunnel: no control-plane SaaS, accounts, or hosted coordinator.
- WireGuard-compatible keys: Curve25519 keys encoded as standard base64, compatible with
wgkey material. - Vetted crypto: the Noise Protocol Framework via the
snowcrate, not hand-rolled primitives. - Local-first config: your mesh lives in a local
ghostwire.toml. - Single static binary workflow: generate, inspect, export, self-test, and bring up from one CLI.
How It Works
ghostwire speaks Noise_IK_25519_ChaChaPoly_BLAKE2s: Noise IK over Curve25519, ChaCha20-Poly1305, and BLAKE2s. The initiator already knows the responder's static public key, sends the first handshake datagram, and the responder replies with the second. After those two UDP datagrams, both peers have a Noise transport session.
The datapath is intentionally simple: one application packet is sealed as one Noise transport message and sent as one UDP datagram. All cryptography is delegated to snow.
Keys are 32-byte Curve25519 values rendered as standard base64, matching WireGuard's wg genkey / wg pubkey format. ghostwire can export wg-quick configs, including QR output for mobile import.
Real OS packet routing through TUN is optional and gated behind --features tun. That path needs admin/root privileges, and on Windows it requires wintun.dll. The pure-UDP crypto datapath works without privileges and is covered by ghostwire selftest.
Install
From this repository:
cargo install --path .
Or build a release binary:
cargo build --release
For real TUN routing:
cargo build --release --features tun
Quickstart
Verify the local encrypted datapath without needing a TUN device:
ghostwire selftest
Create a new local mesh config with three nodes:
ghostwire init --name home --subnet 10.42.0.0/24 --nodes laptop,vps,phone
Inspect the nodes, tunnel addresses, abbreviated public keys, endpoints, and which entries have local private keys:
ghostwire show
Export a WireGuard-compatible config for a node:
ghostwire export --node laptop
Export a QR code for mobile WireGuard import:
ghostwire export --node phone --qr # scan into the WireGuard mobile app
Generate a fresh keypair:
ghostwire keygen
Security
ghostwire uses Noise_IK_25519_ChaChaPoly_BLAKE2s through the snow crate. That gives it Curve25519 static identity keys, ephemeral keys for forward secrecy during session setup, ChaCha20-Poly1305 transport encryption, and BLAKE2s hashing. The crate does not implement its own crypto primitives.
Private keys are not logged through Debug; key debug output is redacted to a short fingerprint. ghostwire.toml contains private keys for local nodes and is intentionally gitignored.
Status: early. Audit before trusting ghostwire with anything critical.
Roadmap
- Multi-peer demux with cookie/index handling like WireGuard.
- Roaming endpoints.
- Pre-shared symmetric key option.
- Windows service and systemd units.
License
MIT
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 Distributions
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 ghostwire-0.1.0.tar.gz.
File metadata
- Download URL: ghostwire-0.1.0.tar.gz
- Upload date:
- Size: 24.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
57ced48b30a974a1827caaf67254c01c841b65f61be627431fa6ef4c1e04b7db
|
|
| MD5 |
b457cc6d71f5831a3327e6e2cf3b223c
|
|
| BLAKE2b-256 |
9933fd2943a4180be34fb1e786fb46e477d78b14adf82e07a15dfc553019ec5d
|
Provenance
The following attestation bundles were made for ghostwire-0.1.0.tar.gz:
Publisher:
pypi.yml on Makeph/ghostwire
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ghostwire-0.1.0.tar.gz -
Subject digest:
57ced48b30a974a1827caaf67254c01c841b65f61be627431fa6ef4c1e04b7db - Sigstore transparency entry: 2226472755
- Sigstore integration time:
-
Permalink:
Makeph/ghostwire@a2bef096bfb98afc96bdf779c0ad03a3f53a4dfb -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Makeph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@a2bef096bfb98afc96bdf779c0ad03a3f53a4dfb -
Trigger Event:
push
-
Statement type:
File details
Details for the file ghostwire-0.1.0-py3-none-win_amd64.whl.
File metadata
- Download URL: ghostwire-0.1.0-py3-none-win_amd64.whl
- Upload date:
- Size: 887.5 kB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6d48aeb69dbf427af354333b1c13900fb6b066cb331cf0943b34f88bccdceac
|
|
| MD5 |
d675fdf2f230ec6de9b4f3219d3d4a18
|
|
| BLAKE2b-256 |
3b1a8fda9465628b495944ee30389cdc33973a27ba90c3af10912315fb3346ca
|
Provenance
The following attestation bundles were made for ghostwire-0.1.0-py3-none-win_amd64.whl:
Publisher:
pypi.yml on Makeph/ghostwire
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ghostwire-0.1.0-py3-none-win_amd64.whl -
Subject digest:
c6d48aeb69dbf427af354333b1c13900fb6b066cb331cf0943b34f88bccdceac - Sigstore transparency entry: 2226474135
- Sigstore integration time:
-
Permalink:
Makeph/ghostwire@a2bef096bfb98afc96bdf779c0ad03a3f53a4dfb -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Makeph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@a2bef096bfb98afc96bdf779c0ad03a3f53a4dfb -
Trigger Event:
push
-
Statement type:
File details
Details for the file ghostwire-0.1.0-py3-none-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: ghostwire-0.1.0-py3-none-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 963.2 kB
- Tags: Python 3, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a8cfb328e3fa2da64ed82b06c943668b2a03abd66f0b0b02391dc449e60f4ed6
|
|
| MD5 |
119f621f152780fff846f59550294f0b
|
|
| BLAKE2b-256 |
991f9db4eb59a61cab0f312d08fb8ef53b032044ebf33ee806867735d5f410eb
|
Provenance
The following attestation bundles were made for ghostwire-0.1.0-py3-none-manylinux_2_34_x86_64.whl:
Publisher:
pypi.yml on Makeph/ghostwire
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ghostwire-0.1.0-py3-none-manylinux_2_34_x86_64.whl -
Subject digest:
a8cfb328e3fa2da64ed82b06c943668b2a03abd66f0b0b02391dc449e60f4ed6 - Sigstore transparency entry: 2226473639
- Sigstore integration time:
-
Permalink:
Makeph/ghostwire@a2bef096bfb98afc96bdf779c0ad03a3f53a4dfb -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Makeph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@a2bef096bfb98afc96bdf779c0ad03a3f53a4dfb -
Trigger Event:
push
-
Statement type:
File details
Details for the file ghostwire-0.1.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: ghostwire-0.1.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 919.3 kB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
286322b50cb68591557c8c2954bec8e1142486b38c70f7b4c0762c1ca4bc3283
|
|
| MD5 |
e31cd2a7d0d1d35a854cbd7105743f05
|
|
| BLAKE2b-256 |
ef2aca944280f01c4929b7e0840cb982d3a4ea64b0588ef3dd6de7f274de2bba
|
Provenance
The following attestation bundles were made for ghostwire-0.1.0-py3-none-macosx_11_0_arm64.whl:
Publisher:
pypi.yml on Makeph/ghostwire
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ghostwire-0.1.0-py3-none-macosx_11_0_arm64.whl -
Subject digest:
286322b50cb68591557c8c2954bec8e1142486b38c70f7b4c0762c1ca4bc3283 - Sigstore transparency entry: 2226473134
- Sigstore integration time:
-
Permalink:
Makeph/ghostwire@a2bef096bfb98afc96bdf779c0ad03a3f53a4dfb -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Makeph
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@a2bef096bfb98afc96bdf779c0ad03a3f53a4dfb -
Trigger Event:
push
-
Statement type: