{"id":50689355,"url":"https://github.com/geiserx/tailscaled-rs","last_synced_at":"2026-06-15T07:02:06.561Z","repository":{"id":363379034,"uuid":"1262910801","full_name":"GeiserX/tailscaled-rs","owner":"GeiserX","description":"An independent, from-scratch Rust system daemon (tailnetd) for joining a WireGuard-based mesh overlay via the Tailscale control protocol — the daemon layer atop the tailscale-rs engine. Unofficial; not affiliated with Tailscale Inc.","archived":false,"fork":false,"pushed_at":"2026-06-14T06:02:37.000Z","size":1639,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-14T06:04:10.527Z","etag":null,"topics":["cli","daemon","derp","mesh-vpn","nat-traversal","networking","noise-protocol","overlay-network","peer-to-peer","rust","self-hosted","systems-programming","tailscale","tailscaled","tokio","tsnet","vpn","wireguard","wireguard-vpn","zero-trust"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GeiserX.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":"geiserx","patreon":"geiser","buy_me_a_coffee":"geiser","thanks_dev":"u/gh/geiserx"}},"created_at":"2026-06-08T12:45:09.000Z","updated_at":"2026-06-14T05:28:38.000Z","dependencies_parsed_at":"2026-06-14T06:01:41.425Z","dependency_job_id":null,"html_url":"https://github.com/GeiserX/tailscaled-rs","commit_stats":null,"previous_names":["geiserx/tailscaled-rs"],"tags_count":51,"template":false,"template_full_name":null,"purl":"pkg:github/GeiserX/tailscaled-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeiserX%2Ftailscaled-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeiserX%2Ftailscaled-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeiserX%2Ftailscaled-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeiserX%2Ftailscaled-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GeiserX","download_url":"https://codeload.github.com/GeiserX/tailscaled-rs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeiserX%2Ftailscaled-rs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34351451,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["cli","daemon","derp","mesh-vpn","nat-traversal","networking","noise-protocol","overlay-network","peer-to-peer","rust","self-hosted","systems-programming","tailscale","tailscaled","tokio","tsnet","vpn","wireguard","wireguard-vpn","zero-trust"],"created_at":"2026-06-09T01:09:59.186Z","updated_at":"2026-06-15T07:02:06.511Z","avatar_url":"https://github.com/GeiserX.png","language":"Rust","funding_links":["https://github.com/sponsors/geiserx","https://patreon.com/geiser","https://buymeacoffee.com/geiser","https://thanks.dev/u/gh/geiserx"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/images/banner.svg\" alt=\"tailscaled-rs\" width=\"100%\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003etailscaled-rs\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/GeiserX/tailscaled-rs/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/GeiserX/tailscaled-rs/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-BSD--3--Clause-blue.svg\" alt=\"License: BSD-3-Clause\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/edition-2024-blue.svg\" alt=\"Rust edition 2024\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/status-experimental-orange.svg\" alt=\"Status: experimental\"\u003e\n\u003c/p\u003e\n\nAn independent, from-scratch **Rust system daemon** that joins a WireGuard-based mesh\noverlay network by speaking the Tailscale control protocol — the long-running, IPC-controlled\n*daemon* layer (a `tailscaled`-shaped process) built on top of the embeddable\n[`tailscale-rs`](https://github.com/GeiserX/tailscale-rs) engine library.\n\nWhere `tailscale-rs` is an **embeddable library** (you link it into your own program, the way\nGo's `tsnet` works), `tailscaled-rs` is the **daemon**: a persistent background service with a\nreconcilable state machine, persisted preferences, and a local control socket that a thin CLI\n(`tnet`) talks to. That daemon layer is exactly what an embeddable library leaves out, and it is\nwhat this project adds.\n\n\u003e [!WARNING]\n\u003e **Experimental. Not for production.** This is early-days software. The underlying engine\n\u003e contains unaudited cryptography and carries no stability or compatibility guarantees, and the\n\u003e daemon layer here is a young MVP. Do not rely on it for data privacy yet.\n\n## What works today (MVP)\n\n- **Joins a real tailnet** non-interactively with a pre-auth key, obtains a tailnet IP, and\n  reaches `Running` over DERP-relayed connectivity.\n- **IPN-style state machine** — `NoState → NeedsLogin → Starting → Running → Stopped`, with the\n  reported state *derived* from live engine/netmap reality (never stored, so it can't drift).\n- **Persisted preferences** — the node's intent (`up`/`down`, hostname, accept-routes) survives a\n  restart.\n- **LocalAPI over a Unix domain socket** — the daemon (`tailnetd`) serves a local control surface;\n  the CLI (`tnet up` / `down` / `status`) is a thin client over it.\n\n## Not yet (the road to a full daemon)\n\nTUN-mode by default and per-OS routing/DNS programming, interactive (browser) login,\n`netmon`-driven endpoint re-binding on network change, service installation\n(systemd/launchd/Windows), MagicDNS OS integration, exit-node/subnet-router operation, Tailscale\nSSH / Serve / Funnel, and Tailnet Lock enforcement. The MVP runs in **userspace-networking** mode\n(no TUN, no OS routing/DNS changes) — applications reach the tailnet via the daemon rather than\nthe kernel. See [`docs/DESIGN.md`](docs/DESIGN.md) for the full architecture and phased plan.\n\n## Quick start\n\n```bash\n# Build\ncargo build --release\n\n# The engine requires an explicit acknowledgement that it is experimental:\nexport TS_RS_EXPERIMENT=this_is_unstable_software\n\n# Run the daemon (foreground)\n./target/release/tailnetd\n\n# In another shell: join a tailnet with a pre-auth key, then check status\n./target/release/tnet up --authkey tskey-auth-XXXX --hostname my-node\n./target/release/tnet status\n./target/release/tnet down\n```\n\nState (node keys + prefs) lives in `$XDG_STATE_HOME/tailnetd` (override with `TAILNETD_STATE_DIR`);\nthe control socket is `\u003cstate-dir\u003e/tailnetd.sock` (override with `TAILNETD_SOCKET`).\n\n## Architecture\n\n```mermaid\nflowchart LR\n    CLI[\"tnet (CLI)\"] --\u003e|\"up / down / status\u003cbr/\u003eover Unix socket\"| D\n    subgraph D[\"tailnetd (daemon)\"]\n        IPN[\"IPN state machine\u003cbr/\u003e+ persisted Prefs\"]\n        API[\"LocalAPI server\"]\n        API --\u003e IPN\n        IPN --\u003e|\"build Config,\u003cbr/\u003ebring up / tear down\"| ENG\n        ENG[\"tailscale-rs engine\u003cbr/\u003e(control · magicsock · DERP · WireGuard · netstack)\"]\n    end\n    ENG \u003c--\u003e|\"Noise control protocol\"| CTRL[\"Control server\"]\n    ENG \u003c--\u003e|\"WireGuard / DERP\"| PEERS[\"Tailnet peers\"]\n```\n\nThe daemon owns the **lifecycle and intent**; the engine owns the **cryptography and data plane**.\nSee [`docs/DESIGN.md`](docs/DESIGN.md) for the component graph, the state machine, and what each\nlayer is responsible for.\n\n## Developing against a local engine\n\n`tailscaled-rs` depends on a pinned revision of `tailscale-rs` (see `Cargo.toml`), and `Cargo.lock`\nis committed so every build is reproducible. If you are co-developing the engine, point Cargo at a\nlocal checkout with a **gitignored** `.cargo/config.toml`:\n\n```toml\n# .cargo/config.toml  (gitignored — never committed)\npaths = [\"/path/to/your/tailscale-rs\"]\n```\n\nCargo transparently substitutes the local source when its version matches the pinned one — edit the\nengine, rebuild the daemon, no manifest change. To bump the pinned engine deliberately, update the\n`rev` in `Cargo.toml` and run `cargo update -p tailscale-rs`.\n\n## Relationship to Tailscale and WireGuard\n\nThis is an **independent, unofficial** project. It is **not affiliated with, endorsed by, or\nsponsored by Tailscale Inc.** \"Tailscale\" is a trademark of Tailscale Inc.; this project uses the\nname only nominatively, to describe the protocol it is compatible with. \"WireGuard\" is a registered\ntrademark of Jason A. Donenfeld; this project implements/speaks the WireGuard protocol and is not an\nofficial WireGuard project.\n\nThe bulk of Tailscale's own client is open source (BSD-3-Clause), and this project is offered in the\nsame spirit: a permissively-licensed, community contribution that anyone — including upstream — is\nfree to use, study, and build on.\n\n## License\n\n[BSD-3-Clause](LICENSE). Portions derived from or interoperating with `tailscale-rs` retain the\noriginal Tailscale Inc. copyright notice, as required.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeiserx%2Ftailscaled-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeiserx%2Ftailscaled-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeiserx%2Ftailscaled-rs/lists"}