Pinning ephemeral ports made the existing field useful but left the default behaviour (random port at every start) hostile to the typical private-network setup, where the user pre-configures a port-forward on their home router and expects mycelium to keep using the same port. Default to 9651 (TCP) and 9652 (QUIC), which match the public mycelium convention. Clearing either field still falls back to ephemeral. Help text updated; placeholder now says "leave empty for ephemeral" instead of "ephemeral" so users understand the field is currently filled with the default.
mycellium-ui-private
Desktop GUI for joining a private Mycelium overlay network — a self-contained IPv6 mesh isolated from the public Mycelium network by a shared 32-byte key.
This is a fork of mycellium-ui (the public-network variant). Code structure is identical; only the bundled daemon (mycelium-private instead of mycelium), the default config (no public seed peer), and a new "Private network" panel in Settings differ.
The two apps are designed to coexist on the same machine: distinct app identifier (tech.threefold.mycellium-ui-private), distinct binary (/usr/bin/mycellium-ui-private), distinct polkit action.
What's a private network?
Mycelium 0.6.1 ships an opt-in mode where every packet is wrapped under an additional symmetric key. Two nodes only see each other if:
- They run the
mycelium-privatedaemon (not the publicmycelium). - They were both started with the same
--network-name(UTF-8, 2–64 bytes — public, e.g.acme-corp-private). - They were both started with
--network-key-filepointing at the same 32-byte secret.
Without the right name+key, peers reject each other at the handshake. There's no Threefold-operated bootstrap node for private networks — the operator distributes the key out-of-band and brings up at least one reachable peer (typically a VPS) that other nodes can dial.
Status
v0.1, Linux-only. Same UI surface as the public variant. Marked experimental upstream (docs/private_network.md in the mycelium repo).
Setup (dev)
sudo apt install -y \
libwebkit2gtk-4.1-dev libjavascriptcoregtk-4.1-dev \
libsoup-3.0-dev libayatana-appindicator3-dev librsvg2-dev \
build-essential curl wget file libssl-dev libgtk-3-dev libxdo-dev \
pkg-config policykit-1
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
pnpm install
bash scripts/fetch-mycelium.sh # downloads mycelium-private v0.6.1
pnpm tauri dev
On first launch:
- Open Settings → Private network.
- Type a network name (e.g.
acme-corp-private). - Click Generate 32-byte key (or Import a key already shared with you).
- Click Reveal hex and share the hex string out-of-band with your other nodes.
- Save daemon configuration (add at least one bootstrap peer).
- Click Start daemon in the sidebar.
Other nodes paste the same hex into their Import field and use the same network name.
Build a .deb
pnpm tauri build --bundles deb
# → src-tauri/target/release/bundle/deb/Mycellium UI Private_*.deb
The .deb declares Depends: pkexec | policykit-1 (Debian 12 + 13 covered) and ships:
/usr/bin/mycellium-ui-private(GUI)/usr/bin/mycelium-private(daemon)/usr/bin/mycellium-bootstrap-private(cleanup wrapper for orphan handling)/usr/share/polkit-1/actions/tech.threefold.mycellium-ui-private.policy
Diverging from upstream
This fork tracks Mycell-UI upstream as origin/upstream (after running the git remote add upstream ... step). To pull bugfixes:
git fetch upstream
git cherry-pick <upstream-commit>
Most fixes will apply cleanly because the only divergence is in:
src-tauri/src/sidecar.rs(network_name + key_file args)src-tauri/src/commands.rs(network_key_* commands)src-tauri/packaging/(different bootstrap script + polkit policy)src-tauri/tauri.conf.json(productName, identifier, externalBin)src/views/Settings.vue(Private network section)src/stores/config.ts(defaults)
Known limitations (v0.1)
- Linux only.
- The
mycelium-privatebinary is upstream's experimental track; the API may shift in a future release. - Network keys are stored in
$XDG_DATA_HOME/tech.threefold.mycellium-ui-private/network_key.binwith mode0600. Not encrypted at rest — host-level disk encryption is the only layer. - No multi-network support — one private overlay at a time.