knotroute
KnotRoute is a self-hosted encrypted overlay network for private services, self-authenticating .knot names, onion-style circuits, rendezvous services, automatic peer discovery, desktop/Android clients, and embeddable application SDKs.
KnotRoute uses the ordinary Internet only as transport between participating nodes. Services do not need public DNS names or public HTTP ports, and the network has no exit-node mode into the public Internet.
A published service owns a stable cryptographic address independent of the machine that currently hosts it:
https://aib6r4...q3.knot/The same service identity can be moved to another KnotRoute node by moving its service identity file.
KnotRoute v3 provides onion-style hop encryption and hidden-service-style introduction/rendezvous paths, but it has not received the years of public cryptographic review, traffic-analysis research, or operational hardening behind Tor/I2P. Do not market it as providing Tor-equivalent anonymity. See Security model.
Documentation by role
Заголовок раздела «Documentation by role»- End-user guide — install a client, join a network, enable
.knotbrowser integration, and troubleshoot access. - Service operator guide — publish sites/TCP services, manage stable service identities, migration, and application-layer access control.
- Server operator guide — relays, Docker sidecars, Traefik coexistence, monitoring, backups, and upgrades.
- Network operator guide — create an independent network, deploy Beacons/bootstrap relays, distribute invitations, monitor topology, and handle incidents.
- SDK guide — embed client/server KnotRoute into applications.
- Documentation index — all guides and protocol references.
network_idisolates overlays but is not a membership credential or password. Current v3 does not provide network-wide admission/revocation. Published hidden services also require application-layer authentication when access must be restricted.
What v3 contains
Заголовок раздела «What v3 contains»- Ed25519 node identities and independent Ed25519 service identities.
- Versioned checksummed
.knotnode and service addresses. - TLS 1.3 between directly connected peers.
- Signed link-state topology advertisements.
- Telescopically constructed multi-hop circuits using per-hop X25519 keys and AEAD layers.
- Hidden services using introduction points and a separately selected rendezvous node.
- Additional end-to-end X25519 + AES-256-GCM encryption between the client and service across the rendezvous path.
- Signed service descriptors replicated to XOR-nearest directory nodes.
- Multiple isolated networks selected by
network_id. - Automatic peer discovery through multiple Beacon URLs, LAN multicast, peer exchange, and persistent peer cache.
- A standalone KnotRoute Beacon container that can also provide a bootstrap relay.
- SOCKS5 and HTTP/CONNECT local gateways.
- A local KnotRoute Root CA for normal
https://*.knotbrowser UX. - Native Windows tray controller, per-user system integration, autostart, and optional Windows Service wrapper.
- Android browser/client backed by the same Go networking core through a generated AAR.
- Embeddable Go client and server SDKs.
- Gomobile binding for Android applications that want KnotRoute without requiring the standalone client app.
- Docker sidecar for publishing existing containers as
.knotservices without exposing their application port on the host. - Application primitives for RPC, message-oriented datagrams, encrypted topic pub/sub, content-addressed objects, and encrypted offline mailboxes.
- Signed network invitation bundles.
Addresses
Заголовок раздела «Addresses»KnotRoute has two canonical address types.
Node address
Заголовок раздела «Node address»A node address identifies one KnotRoute router:
<node-label>.knotssh.<node-label>.knotThe label contains a type/version byte, the SHA-256 node ID derived from the node’s Ed25519 public key, and a checksum.
Node addresses are useful for diagnostics and direct services. A relay can learn the destination node of a direct node-address connection, so they are not the preferred v3 hidden-service address.
Service address
Заголовок раздела «Service address»A published v3 service owns an independent Ed25519 identity:
<service-label>.knotThe service label is derived from the service public key, not the host node. A descriptor tells clients only which introduction points currently accept introductions for that service. The hosting node identity is not part of the address or descriptor.
Print addresses:
knotroute address --config knotroute.jsonknotroute address --config knotroute.json --service webA service configured with "publish": true prints its independent service-identity address. A non-published service prints the legacy/direct service.<node>.knot form.
Human-readable aliases
Заголовок раздела «Human-readable aliases»Aliases are intentionally local; KnotRoute has no global registrar that could honestly guarantee globally unique pretty names without introducing another trust/consensus system.
{ "aliases": [ { "name": "docs", "service_id": "ks_...", "description": "Documentation service" } ]}Then:
https://docs.knot/Node aliases can also be exported/imported as signed consent records:
knotroute alias export --config knotroute.json --name edge --out edge.knot-alias.jsonknotroute alias import --config knotroute.json --file edge.knot-alias.jsonHidden-service connection flow
Заголовок раздела «Hidden-service connection flow»For a published service, the normal v3 path is:
- The service keeps reverse circuits open to several introduction points.
- It signs a descriptor containing its service public key, introduction-point IDs, revision, expiration, and optional metadata.
- The descriptor is replicated to several XOR-nearest directory nodes.
- A client looks up and verifies the descriptor.
- The client selects a rendezvous node and opens an onion circuit to it.
- The client sends an introduction request through a different onion circuit to an introduction point.
- The service independently opens its own circuit to the rendezvous node.
- Client and service authenticate the service identity and derive an additional end-to-end session key.
- The rendezvous node bridges ciphertext. It does not receive the service payload key.
This is deliberately different from direct node-address routing: the service address does not disclose which node hosts the service.
Circuits
Заголовок раздела «Circuits»A client circuit is built one hop at a time. Each hop receives its own ephemeral X25519 handshake and separate forward/reverse AEAD keys.
A relay stores only the adjacent incoming/outgoing circuit identifiers and peers for that circuit. It does not receive the complete client-selected path as one routing header.
privacy.circuit_hops sets the desired minimum hop count where the currently known topology allows it. KnotRoute does not invent unreachable hops merely to satisfy the configured number.
Automatic peer discovery
Заголовок раздела «Automatic peer discovery»Discovery sources are additive:
- Beacon — signed soft-state peer announcements over HTTP/HTTPS;
- LAN — signed IPv4 multicast announcements on the local network;
- PEX — peer candidates exchanged over already authenticated KnotRoute links;
- peer cache — recently verified candidates persisted locally.
Every candidate is only a hint. The real KnotRoute TLS/HELLO handshake verifies the peer’s cryptographic identity and network_id, so a Beacon or PEX sender cannot make a client accept an endpoint as the wrong node identity.
A client with no publicly reachable listener may query Beacons without advertising a useless loopback/wildcard endpoint.
KnotRoute Beacon
Заголовок раздела «KnotRoute Beacon»Beacon is intentionally not a service directory and not a traffic relay requirement. It stores only short-lived signed peer announcements grouped by network_id.
The provided container can additionally run one normal KnotRoute bootstrap relay so a brand-new outbound-only client immediately has a first overlay edge.
docker compose -f compose.beacon.yaml up -d --buildRelevant ports in the example:
8080/tcp Beacon HTTP API7447/tcp optional bootstrap KnotRoute relayUse several independent Beacon URLs if availability matters. Once nodes have discovered peers, the overlay can continue operating without the Beacon as long as the topology remains connected.
Independent networks and invitations
Заголовок раздела «Independent networks and invitations»Every direct peer handshake includes network_id; nodes with different IDs refuse each other.
Generate a fresh network ID:
knotroute network createExport the current network bootstrap information as a signed invitation:
knotroute invite export --config knotroute.json --out network.knotinviteImport it:
knotroute invite import --config knotroute.json --file network.knotinviteThe invite authenticates who created the bundle and transports the network ID, Beacon URLs, and configured seeds. It is a bootstrap object, not a global naming authority or a cryptographic membership/authorization system.
Browser integration and local CA
Заголовок раздела «Browser integration and local CA»Defaults:
SOCKS5 127.0.0.1:9477HTTP proxy 127.0.0.1:9478Dashboard 127.0.0.1:8484PAC http://127.0.0.1:8484/proxy.pacThe PAC script sends only .knot web destinations to KnotRoute and returns DIRECT for everything else. This means KnotRoute can coexist with a separate VPN/TUN product: KnotRoute does not create a TUN device in its default desktop mode.
When ca.enabled and ca.intercept_https are enabled, the local HTTP proxy terminates browser TLS for every resolvable .knot hostname: canonical service identities, node-bound service names such as web.<node>.knot, and configured local aliases. It presents a short-lived certificate issued by a per-device KnotRoute Root CA, then sends plaintext HTTP bytes into the already authenticated/encrypted KnotRoute stream or rendezvous session.
The CA private key never leaves the local device, and certificate issuance explicitly refuses non-.knot names.
This is a local browser-compatibility mechanism, not a network-wide certificate authority.
Windows desktop client
Заголовок раздела «Windows desktop client»KnotRoute v4 ships the interactive Windows client as a single:
KnotRoute.exeThe executable contains the Go client runtime and an embedded desktop UI rendered by the system WebView2 runtime through Wails. It is not a browser tab and it does not depend on the loopback dashboard for presentation. Network startup runs outside the UI thread, and state changes are delivered to the frontend through application events.
Install from the Windows release archive with:
powershell -ExecutionPolicy Bypass -File .\Install-KnotRoute.ps1The ordinary UI separates consumer features (Chats, Feed, Catalog, Internet) from low-level service/node tooling under Developers. .knot browser integration installs the per-user KnotRoute Root CA and configures the current user’s PAC only after explicit confirmation. Existing PAC state is backed up and restored when integration is disabled.
The release also includes knotroute-cli.exe for diagnostics/automation and an optional knotroute-service.exe wrapper for unattended Windows Service deployments.
See docs/windows.md.
Android client
Заголовок раздела «Android client»The Android project is under android/ and embeds the same Go core from mobile/knotmobile with gomobile bind.
The v4 application is a communication/network client rather than an embedded browser: it exposes chats, feed, catalog and network state in Material UI, while .knot links are handed to the user’s real browser. A foreground VpnService can advertise the local KnotRoute HTTP proxy on Android 10+ as a browser-integration compatibility layer. Android documents that applications may ignore a VPN-provided HTTP proxy, so packet-level tun2socks integration remains the intended final v4 path.
Modern Android does not allow an ordinary application to silently install a user CA. KnotRoute exports knotroute-root-ca.crt and opens Security Settings; the user installs the certificate explicitly. Browser/app trust of user-installed CAs still depends on that application’s Android network-security policy.
Build:
./scripts/build-android.shRequirements and device-specific notes are documented in docs/android.md. GitHub Actions builds the debug APK, unsigned release APK, and reusable AAR.
Docker sidecar
Заголовок раздела «Docker sidecar»A service container does not need a host port merely to become a KnotRoute service.
services: app: image: nginx:alpine networks: [private]
knotroute: build: context: . dockerfile: Dockerfile.sidecar restart: unless-stopped networks: [private] volumes: - knotroute-data:/data environment: KNOTROUTE_BEACONS: "https://beacon.example" KNOTROUTE_SERVICE_NAME: "web" KNOTROUTE_SERVICE_TARGET: "app:80"The application can simultaneously participate in any normal reverse-proxy setup; KnotRoute only needs TCP reachability to the chosen target inside a shared Docker network.
Multiple services can be provided through KNOTROUTE_SERVICES_JSON.
See docs/docker.md and examples/docker-private-site/.
CLI quick start
Заголовок раздела «CLI quick start»Requires Go 1.23+ to build from source.
go test ./...go build -trimpath -o knotroute ./cmd/knotroute./knotroute init --config knotroute.json./knotroute doctor --config knotroute.json./knotroute run --config knotroute.jsonUseful commands:
knotroute initknotroute runknotroute idknotroute addressknotroute resolveknotroute alias export|importknotroute doctorknotroute ca init|path|fingerprint|install|uninstallknotroute network createknotroute invite export|importknotroute versionExample published service
Заголовок раздела «Example published service»{ "name": "web", "target": "127.0.0.1:8080", "publish": true, "intro_count": 3, "allow": ["*"], "metadata": { "protocol": "http" }}The first start creates a persistent service identity under the configured service identity path. Its canonical address can then be printed with:
knotroute address --config knotroute.json --service webBack up the service identity file if the .knot address must survive host migration.
Release builds
Заголовок раздела «Release builds»Linux/macOS
Заголовок раздела «Linux/macOS»VERSION=3.0.1 ./scripts/build-release.shWindows PowerShell
Заголовок раздела «Windows PowerShell»$env:VERSION = "3.0.1".\scripts\build-release.ps1The scripts create cross-platform desktop/server archives in dist/. Android is built separately because it requires the Android SDK and gomobile:
./scripts/build-android.shPushing a Git tag matching v* runs the GitHub release workflow, builds Android plus desktop/server archives, recalculates SHA-256 checksums, and attaches the artifacts to the GitHub Release.
Docker images
Заголовок раздела «Docker images»Build the generic node:
docker build -t knotroute:3.0.1 .Build the application sidecar:
docker build -f Dockerfile.sidecar -t knotroute-sidecar:3.0.1 .Build Beacon/bootstrap relay:
docker build -f Dockerfile.beacon -t knotroute-beacon:3.0.1 .All runtime images are scratch-based static binaries (the sidecar additionally contains CA certificates for outbound HTTPS Beacon access).
Security model
Заголовок раздела «Security model»KnotRoute v3 is designed to provide:
- cryptographic node identity;
- encrypted authenticated peer links;
- path-local onion circuit layers;
- service identities independent of host nodes;
- signed descriptors;
- hidden-service introduction/rendezvous paths;
- end-to-end payload confidentiality between hidden-service client and service;
- no public-Internet exit mode;
- no requirement for a central service registry.
It does not currently claim resistance to every anonymity attack. In particular, operators must assume exposure to some combination of:
- timing and volume correlation;
- global/passive traffic observation;
- Sybil-heavy overlays;
- malicious introduction/rendezvous/directory nodes;
- topology fingerprinting;
- denial of service and route manipulation by participating nodes;
- application-layer identity leaks, cookies, browser fingerprinting, or identifying content.
The local CA also expands the trust of the machine on which it is installed. KnotRoute deliberately keeps its CA private key local and refuses non-.knot certificate issuance, but compromise of that local key would allow forged .knot certificates on that device until the CA is removed/replaced.
Read SECURITY.md before deploying KnotRoute for sensitive workloads.
The repository includes unit and integration tests for:
- identities and address checksums;
- signed descriptors and invitations;
- Beacon registration and verification;
- link-state routing;
- direct encrypted streams;
- SOCKS5/HTTP proxy paths;
- multi-hop circuit construction;
- published service lookup, introduction, rendezvous, and encrypted payload exchange;
- local CA constraints;
- RPC/datagram/pubsub/object protocols;
- encrypted offline mailbox operations.
Run:
go test ./...go test -race ./...go vet ./...CI runs Go tests on Linux, Windows, and macOS, and has a separate Android build job.
Repository layout
Заголовок раздела «Repository layout»cmd/knotroute CLI/nodecmd/knotroute-desktop Wails/WebView2 Windows client with in-process runtimecmd/knotroute-service Windows SCM wrappercmd/knotroute-beacon peer-discovery/bootstrap servicecmd/knotroute-sidecar Docker publishing sidecarinternal/overlay routing, circuits, directory, rendezvousinternal/discovery Beacon, LAN, PEX/cache discoveryinternal/certauth local .knot CApkg/knotclient embeddable Go clientpkg/knotserver embeddable Go service hostpkg/knotapp application primitivespkg/knotmailbox offline encrypted mailbox primitivemobile/knotmobile gomobile-facing APIandroid/ Android applicationweb/ dashboard sourcepackaging/ OS integrationLicense
Заголовок раздела «License»MIT. See LICENSE.
Исходный код · Apache-2.0