Skip to main content

Crate tailscale

Crate tailscale 

Source
Expand description

A work-in-progress Tailscale library.

tailscale allows Rust programs to connect to a tailnet and exchange traffic with peers over TCP and UDP. It can communicate with other tailscale-based peers, tailscaled (the Tailscale Go client), tsnet, and libtailscale via public DERP servers.

`tailscale` is unstable and insecure.

We welcome enthusiasm and interest, but please do not build production software using these libraries or rely on it for data privacy until we have a chance to batten down some hatches and complete a third-party audit.

See the Caveats section for more details.

For language bindings, see the following crates:

For instructions on how to run tests, lints, etc., see CONTRIBUTING.md. For the high-level architecture and repository layout, see ARCHITECTURE.md.

§Code Sample

A simple UDP client that periodically sends messages to a tailnet peer at 100.64.0.1:5678:

// Open a new connection to the tailnet
let dev = tailscale::Device::new(
    &tailscale::Config {
        key_state: tailscale::load_key_file("tsrs_key.json", Default::default()).await?,
        ..Default::default()
    },
    Some("YOUR_AUTH_KEY_HERE".to_owned()),
).await?;

// Bind a UDP socket on our tailnet IP, port 1234
let sock = dev.udp_bind((dev.ipv4_addr().await?, 1234).into()).await?;

// Send a packet containing "hello, world!" to 100.64.0.1:5678 once per second
loop {
    sock.send_to((Ipv4Addr::new(100, 64, 0, 1), 5678).into(), b"hello, world!").await?;
    tokio::time::sleep(Duration::from_secs(1)).await;
}

Additional examples of using the tailscale crate can be found in the examples/ directory.

§Using tailscale

To use this crate or the language bindings, you will need to set the TS_RS_EXPERIMENT env var to this_is_unstable_software. We’ll remove this requirement after a third-party code/cryptography audit and any necessary fixes.

Under the hood, we use Tokio for our async runtime. You must also use Tokio, any kind and most configurations of Tokio runtimes should work, but there must be one available when you call any async API functions. The easiest way to do this is to use #[tokio::main], see the Tokio docs for more information. In the future, we would like to limit our reliance on Tokio so that there are alternatives for users of other async runtimes.

§Caveats

This software is still a work-in-progress! We are providing it in the open at this stage out of a belief in open-source and to see where the community runs with it, but please be aware of a few important considerations:

  • This implementation contains unaudited cryptography and hasn’t undergone a comprehensive security analysis. Conservatively, assume there could be a critical security hole meaning anything you send or receive could be in the clear on the public Internet.
  • There are no compatibility guarantees at the moment. This is early-days software - we may break dependent code in order to get things right.
  • We currently rely on DERP relays for all communication. Direct connections via NAT holepunching will be a seamless upgrade in the future, but for now, this puts a cap on data throughput.

§Feature Flags

§Platform Support

tailscale currently supports the following platforms:

  • Linux (x86_64 and ARM64)
  • macOS (ARM64)

§Component crates

The following crates are part of the tailscale-rs project and are dependencies of this one. For many tasks, just this crate should be sufficient and these other crates are an implementation detail. There are other crates too, see ARCHITECTURE.md or the GitHub repo.

  • ts_runtime: for each API-level Device, the runtime uses an actor architecture to manage the lifecycle of the control client, data plane components, netstack, etc. A message bus passes updates and communications between these top-level actors.
  • ts_netcheck: checks network availability and reports latency to DERP servers in different regions.
  • ts_netstack_smoltcp: a smoltcp-based network stack that processes Layer 3+ packets to/from the overlay network.
  • ts_control: control plane client that handles registration, authorization/authentication, configuration, and streaming updates.
  • ts_dataplane: wires all the individual data plane functions together, flowing inbound and outbound packets through the components in the correct order.
  • ts_tunnel: a partial implementation of the WireGuard specification that protects all data plane traffic, and is interoperable with other WireGuard clients, including Tailscale clients.
  • ts_cli_util: helpers for writing command line tools and initializing logging, used in examples.
  • ts_disco_protocol: incomplete implementation of Tailscale’s discovery protocol (disco).

Modules§

axum
Support for the axum http server wrapping TcpListener.

Structs§

Config
Config for connecting to Tailscale.
Device
How a program connects to a tailnet and communicates with peers.
NodeInfo
A node in a tailnet.
NodeState
The complete key state for a Tailscale node.
TcpListener
A TCP listener waiting to accept connections.
TcpStream
A TCP stream.
UdpSocket
A UDP socket.

Enums§

BadFormatBehavior
What to do if the key file can’t be parsed.
Error
Errors that may occur while interacting with a device.

Functions§

load_key_file
Load key state from a path on the filesystem, or create a file with a new key state if one doesn’t exist.