Tundra

HexDocsLicensegithub actions badge

TUN device support for Elixir.

Tundra provides a simple API for creating and using TUN devices on Linux and Darwin.

Architecture

TUN device creation is a privileged operation requiring root on both platforms. Tundra supports two modes of operation:

  1. Direct creation: When the BEAM VM runs with sufficient privileges (root or CAP_NET_ADMIN on Linux), Tundra creates TUN devices directly via the NIF without requiring a server process.

  2. Server-based creation: When the BEAM VM lacks privileges, Tundra uses a client-server architecture with a separate privileged daemon (tundra_server) that creates and configures TUN devices on behalf of unprivileged clients.

Tundra automatically attempts direct creation first and falls back to the server if privileges are insufficient. Communication with the server happens via a Unix domain socket (/var/run/tundra.sock), and file descriptors are passed using SCM_RIGHTS.

Once created, the device is represented within the Elixir runtime with process-ownership semantics:

Installation

Elixir Library

Add tundra to your list of dependencies in mix.exs:

def deps do
  [
    {:tundra, "~> 0.1"}
  ]
end

Server (Optional)

The server is only required for unprivileged operation. If your application runs with root privileges (or CAP_NET_ADMIN on Linux), Tundra will create devices directly and the server is not needed.

For unprivileged operation, build and run the server with elevated privileges:

cd c_src/server
make
sudo ./tundra_server

Users connecting to the server must be members of the tundra group:

# Linux
sudo usermod -aG tundra $USER

# macOS
sudo dseditgroup -o edit -a $USER -t user tundra

Log out and back in after adding yourself to the group.

See c_src/server/README.md for detailed server documentation.

Platform Support

Usage

Use Tundra.create/2 to create a new TUN device with full configuration:

{:ok, {dev, name}} = Tundra.create("fd11:b7b7:4360::2",
  dstaddr: "fd11:b7b7:4360::1",
  netmask: "ffff:ffff:ffff:ffff::",
  mtu: 1500)

See the module documentation for complete API details.