BoringTun

repository·master·Indexed 27 days ago

https://github.com/cloudflare/boringtun

A high-performance, portable implementation of the WireGuard protocol. It provides a userspace CLI for Linux and macOS, as well as a library for integration into server and mobile applications (iOS/Android) via C ABI (FFI) and JNI bindings.

Tokens
2.3K
Snippets
5
Records
25
Agent score
93%

What's inside boringtun

  1. Configure Linux permissions for boringtun

    master

    On Linux, boringtun drops privileges by default. To allow the executable to manage network interfaces without running the entire process as root, grant it the CAP_NET_ADMIN capability:

    sudo setcap cap_net_admin+epi boringtun

    sudo setcap cap_net_admin+epi boringtun
  2. Run boringtun-cli

    master

    To start a tunnel using the CLI, use the following command syntax:

    boringtun-cli [-f/--foreground] INTERFACE-NAME

    Once the tunnel is running, you can configure it using standard WireGuard tools like wg or wg-quick.

    boringtun-cli [-f/--foreground] INTERFACE-NAME
  3. Build boringtun library or executable

    master

    Use cargo build to compile the project. You can target the library only or the CLI executable. Use --target $(TARGET_TRIPLE) to specify a target architecture.

    • Library only: Builds the boringtun crate without default features.
    • Executable: Builds the boringtun-cli binary.

    By default, the executable is placed in ./target/release. You can install it manually using cargo install --bin boringtun --path ..

  4. Use boringtun-cli with wg-quick

    master

    You can use boringtun-cli as the userspace implementation for wg-quick by setting the WG_QUICK_USERSPACE_IMPLEMENTATION environment variable to boringtun-cli.

    Note: If you need to set fwmark (common with wg-quick), you must also set WG_SUDO=1 or run with the --disable-drop-privileges flag.

    sudo WG_QUICK_USERSPACE_IMPLEMENTATION=boringtun-cli WG_SUDO=1 wg-quick up CONFIGURATION
  5. Integrate boringtun via FFI or JNI

    master

    The boringtun library provides bindings for cross-platform integration:

    • C ABI (FFI): Defined in wireguard_ffi.h. Use these for C/C++, Swift (via bridging headers), or C# (using [DllImport] with CallingConvention.Cdecl).
    • JNI: Java Native Interface bindings are available for Android/Java integration, defined in src/jni.rs.
  6. Configure DeviceConfig for BoringTun Device

    master

    The DeviceConfig struct allows you to tune the performance and behavior of the BoringTun device.

    Key fields:

    • n_threads: Number of worker threads to spawn (defaults to 4).
    • use_connected_socket: If true, uses a connected UDP socket for peers to improve performance (defaults to true).
    • use_multi_queue: (Linux only) Enables multi-queue support for the TUN interface.
    • uapi_fd: (Linux only) A file descriptor for the User API interface.
    let config = DeviceConfig {
        n_threads: 8,
        use_connected_socket: true,
        #[cfg(target_os = "linux")]
        use_multi_queue: true,
        #[cfg(target_os = "linux")]
        uapi_fd: -1,
    };
  7. Configure macOS interface names for boringtun

    master

    On macOS, the interface name must follow the utun[0-9]+ pattern.

    • Use an explicit name like utun0.
    • Use utun to let the kernel select the lowest available interface.
    • If you use utun, you can define the WG_TUN_NAME_FILE environment variable to write the chosen interface name to a specific file.
  8. Initialize a new DeviceHandle

    master

    To start a BoringTun device, use DeviceHandle::new. This function creates a new TUN interface with the specified name, initializes the device with the provided configuration, and spawns the requested number of worker threads. It also automatically opens a listening UDP socket on a random port.

    Returns a DeviceHandle which owns the interface and manages the background threads.

  9. Retrieve tunnel statistics with `Tunn::stats`

    master

    Get performance and health metrics for the tunnel connection. Returns a tuple containing:

    • Option<Duration>: Time since the last successful handshake.
    • usize: Total bytes sent (tx_bytes).
    • usize: Total bytes received (rx_bytes).
    • f32: Estimated packet loss.
    • Option<u32>: Last Round Trip Time (RTT).
  10. Decapsulate network packets with `Tunn::decapsulate`

    master

    Process a received UDP datagram from the network.

    To handle all resulting packets (e.g., when the tunnel needs to respond with a handshake or cookie), you should call decapsulate repeatedly with an empty datagram until it returns TunnResult::Done.

    Returns a TunnResult which may indicate:

    • WriteToNetwork: A packet that needs to be sent back to the network (e.g., a handshake response).
    • WriteToTunnelV4 / WriteToTunnelV6: A decrypted IP packet and its source address to be injected into the tunnel interface.
    • Done: Processing complete.
    • Err: A WireGuardError occurred.