Tundra
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:
Direct creation: When the BEAM VM runs with sufficient privileges (root or
CAP_NET_ADMINon Linux), Tundra creates TUN devices directly via the NIF without requiring a server process.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:
- Only the owning process can read from or write to the device and receive i/o notifications
- The TUN device is automatically removed when the owning process exits
Installation
Elixir Library
Add tundra to your list of dependencies in mix.exs:
def deps do
[
{:tundra, "~> 0.1"}
]
endServer (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 tundraLog out and back in after adding yourself to the group.
See c_src/server/README.md for detailed server documentation.
Platform Support
- Linux: TUN devices via
/dev/net/tun, configured with netlink. Supports both direct creation (when privileged) and server-based creation. - Darwin/macOS: utun devices via kernel control API, configured with ioctl. Supports both direct creation (when privileged) and server-based creation.
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.