libtailscale

repository·main·Indexed 43 days ago

https://github.com/tailscale/libtailscale

A C library that allows developers to embed Tailscale functionality directly into applications, providing userspace networking on a tailnet. It includes language-specific bindings and wrappers for Python, Ruby, and Swift (TailscaleKit) for macOS and iOS.

Tokens
4.9K
Snippets
32
Records
37
Agent score
56%

What's inside libtailscale

  1. What is libtailscale?

    main
    libtailscale is a C library designed to embed Tailscale directly into a process. It allows you to compile Tailscale into your own program, enabling your application to obtain an IP address on a tailnet entirely from userspace.
  2. Use LocalAPI to track Tailscale state

    main
    TailscaleKit includes an implementation of LocalAPI. This allows you to track the state of the embedded Tailscale instance in detail. While the implementation is noted as somewhat incomplete, it is intended for monitoring the node's status and the tailnet state.
  3. Build TailscaleKit for macOS or iOS

    main

    Before using the TailscaleKit examples, you must build the TailscaleKit framework for your target platform.

    • For macOS, run make macos from the /swift directory.
    • For iOS (supporting both physical devices and simulators), run make ios-fat from the /swift directory. This produces a universal xcframework required by the iOS target.
    # From the /swift directory
    make macos
    make ios-fat
  4. Install the tailscale Python package

    main

    To install the tailscale package, you must first ensure you have the following build requirements installed on your system:

    • Python 3.9 or greater
    • A recent Go compiler in $PATH
    • CMake (and a C compiler)
    • Git

    Follow these steps to set up a virtual environment and build the package:

    1. Create and activate a virtual environment:
      python3 -m venv venv
      source venv/bin/activate
    2. Build the c-archive and install the Python package using make:
      make build
    python3 -m venv venv
    source venv/bin/activate
    make build
  5. Initialize and use TailscaleKit in Swift

    main

    To use TailscaleKit, you must create a TailscaleNode with a Configuration object. Nodes require authorization, which can be provided via the authKey parameter in the configuration or by watching the ipn bus for a browseToURL field for interactive web-based auth.

    Once the node is initialized, call try await node.up() to bring the interface online. To make network requests to nodes on your Tailnet, use the URLSessionConfiguration.tailscaleSession(tailscale) extension to create a specialized URLSession.

    func start() -> TailscaleNode {
        let dataDir = getDocumentDirectoryPath().absoluteString + "tailscale"
        let authKey = "tsnet-auth-put-your-auth-key-key-here"
        let config = Configuration(hostName: "TSNet-Test",
                                   path: dataDir,
                                   authKey: authKey,
                                   controlURL: Configuration.defaultControlURL,
                                   ephemeral: false)
    
        // The logger is configurable. The default will just print.
        let node = try TailscaleNode(config: config, logger: DefaultLogger())
        
        // Bring the node up 
        try await node.up()
        return node
    }
    
    // Do a URL request via the loopback proxy
    // Where url is a node on your tailnet such as https://server.fiesty-pangolin.ts.net/thing
    func fetchURL(_ url: URL, tailscale: TailscaleNode) async throws -> Data {
        // You can cache this. It will not change once the node is up.
        let sessionConfig = try await URLSessionConfiguration.tailscaleSession(tailscale)
        let session = URLSession(configuration: sessionConfig)
        
        // Make the request
        let req = URLRequest(url: url)
        let (data, _) = try await session.data(for: req)
        return data
    }
  6. Build and Install TailscaleKit

    main

    TailscaleKit provides a Swift package for an embedded network interface. You can build different variants of TailscaleKit.framework using make from the /swift directory.

    Requirements:

    • Xcode 16.1 or newer
    • Swift 6 support is included.

    Build Variants:

    • make macos: Builds for macOS.
    • make ios: Builds for iOS (suitable for App Store submissions; contains no simulator segments).
    • make ios-sim: Builds for the iOS Simulator.
    • make ios-fat: Produces an xcframework bundle containing both device and simulator frameworks.

    Static Libraries (C/C++): If you are writing pure C or C++, you can build static libraries from the root directory and link against the generated tailscale.h header:

    • make c-archive: Builds for the local machine architecture/platform.
    • make c-archive-ios: Builds for iOS.
    • make c-archive-ios-sim: Builds for the iOS Simulator.

    Note: The generated frameworks are not signed and must be signed when embedded in your application.

    # From /swift
    $ make macos
    $ make ios
    $ make ios-sim
    $ make ios-fat
    
    # From / (to build static libraries)
    $ make c-archive
    $ make c-archive-ios 
    $ make c-archive-ios-sim
  7. Build libtailscale as a static archive

    main

    To build libtailscale as a static archive (libtailscale.a), use the latest version of Go and run one of the following commands:

    go build -buildmode=c-archive

    Or use the provided Makefile:

    make archive

    Once built, link libtailscale.a into your binary and use the tailscale.h header file to interface with the library.

  8. Develop with the tailscale gem

    main

    To set up a local development environment for this gem:

    1. Run bin/setup to install necessary dependencies.
    2. Use bin/console to open an interactive prompt for experimentation.
    3. Run rake test to execute the test suite.

    To install the gem locally from the source repository, run:

    bundle exec rake install
  9. Install the tailscale gem

    main

    You can install the tailscale gem using Bundler or by installing it directly via RubyGems. Note that source installations require a recent Go compiler to be available in your $PATH to build the extension.

    If using Bundler:

    $ bundle add tailscale

    If not using Bundler:

    $ gem install tailscale
  10. Use the tailscale gem to create a network interface

    main

    The tailscale gem provides an embedded network interface. To use it, you must first initialize a Tailscale instance and call .up to start the node.

    Authorization: The node must be authorized to function. You can authorize it by:

    1. Setting an auth key using the set_auth_key method.
    2. Setting the $TS_AUTHKEY environment variable.
    3. Watching the libtailscale log stream and manually visiting the printed authorization URL.

    Once the node is up, you can use standard Ruby socket-like methods such as .listen to accept connections over the Tailscale network.

    require 'tailscale'
    
    # Initialize and start the Tailscale node
    t = Tailscale.new
    t.up
    
    # Listen for TCP connections on a specific port
    l = t.listen "tcp", ":1999"
    
    while c = l.accept
        c.write "hello world"
        c.close
    end
  11. Authorize a tailscale node

    main

    A Tailscale node must be authorized before it can function. You can authorize a node using one of the following methods:

    1. Environment Variable: Set the $TS_AUTHKEY environment variable before running your application.
    2. Programmatic API: Use TSNet.set_authkey to provide an authentication key.
    3. Manual Authorization: Watch the log stream and manually visit the printed authorization URL to authorize the node.