Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
rsnet
Rust bindings for Tailscale's libtailscale C library. Embed a Tailscale node directly into your Rust process — get an IP on your tailnet entirely from userspace, no system daemon required.
Fully async (tokio). Streams implement AsyncRead + AsyncWrite + Unpin.
Prerequisites
- Go (to compile libtailscale from the git submodule)
- Rust stable (edition 2021+)
- A Tailscale auth key
git clone --recurse-submodules <repo-url>
Quick start
let mut server = new?;
server.set_auth_key?;
server.set_dir?;
server.up?;
let listener = server.listen?;
loop
Features
| Feature | Default | Adds |
|---|---|---|
ssl |
yes | TlsListener, listen_tls(), listen_tls_with_pem() via tokio-rustls |
localapi-serde-json |
no | Typed Status, PeerStatus, WhoIsResponse structs, whoami(), fqdn(), whois() |
[]
= "0.1" # ssl only (default)
= { = "0.1", = ["localapi-serde-json"] } # + typed localapi
= { = "0.1", = false } # core only
Examples
Plain HTTP
cargo run --example hello -- <auth-key> <hostname>
curl http://<hostname>.YOUR-TAILNET.ts.net
HTTPS with auto TLS
cargo run --example hello_tls --features localapi-serde-json -- <auth-key> <hostname>
curl https://<hostname>.YOUR-TAILNET.ts.net
Fetches LetsEncrypt certs from Tailscale's LocalAPI automatically. First run takes a few seconds for ACME.
TLS
Three levels of control:
// auto: fetches fqdn + certs from localapi, listens on :443
let tls = server.listen_tls.await?;
// manual certs: bring your own PEM
let tls = server.listen_tls_with_pem?;
// full control: build your own rustls config
let tls = new;
// all return TlsStream<TailscaleStream> from accept
let tls_stream = tls.accept.await?;
LocalAPI
Access Tailscale's node-local HTTP API for status, peer info, certs, and more:
let client = server.local_client?;
// raw requests (always available)
let = client.get.await?;
let cert_pem = client.cert.await?;
let = client.cert_pair.await?;
// typed responses (requires localapi-serde-json feature)
let me = client.whoami.await?; // PeerStatus
let domain = client.fqdn.await?; // String
let status = client.status.await?; // Status (with all peers)
let who = client.whois.await?; // WhoIsResponse
Logging
Go-side logs are piped through tracing at debug level with target libtailscale:
RUST_LOG=libtailscale=debug cargo run --example hello -- ...
State persistence
Set a state directory to avoid re-authentication on every restart:
server.set_dir?;
Without this, libtailscale uses a default path keyed by binary name. Combined with set_ephemeral(true), the node is deleted from your tailnet when the process exits and needs re-auth next run.