Skip to content

toreanjoel/tunneld

Repository files navigation

Tunneld

CI Status Elixir Phoenix Nginx Zrok Platform

A wireless-first software-defined gateway for ARM single-board computers. Tunneld bridges Wi-Fi and Ethernet to create a private subnet, manages devices via DHCP, resolves DNS securely, reverse-proxies local services with auto-SSL, and optionally exposes them through Zrok overlay tunnels.

Designed to be lightweight and portable — run it at home as a smarter router, or take it anywhere as a self-contained network appliance.

Prerequisites

  • Hardware: An ARM64 SBC with both wireless and ethernet interfaces (Raspberry Pi, NanoPi, etc.)
  • Operating System: Debian-based OS
  • Zrok (optional): A self-hosted Zrok control plane or account for overlay networking

Features

Wireless-First Gateway

Connects upstream via Wi-Fi and serves a private subnet over Ethernet. Devices plug in and receive IPs, DNS, and internet access — no existing router UI needed. Everything is controlled through the Tunneld dashboard.

Smart Queue Management (SQM)

Implements the CAKE algorithm to eliminate bufferbloat and reduce latency. Choose between latency-optimized, balanced, or no shaping — applied in real-time via tc.

Local PKI & Auto-SSL

Generates a Root CA on first run. Every resource gets a TLS certificate signed by your CA, served through nginx. Install the Root CA on your devices for trusted HTTPS across your subnet.

DNS Server

All DNS queries on the subnet are intercepted via iptables and routed through a user-configured DNS server. Point the gateway at any resolver — Cloudflare (1.1.1.1), Google (8.8.8.8), or a local Pi-hole on your network. Same-subnet DNS servers are supported via automatic prerouting rules.

Resource Management & Health Monitoring

Define resources that point to services running on your subnet. Each resource has a pool of backends that are health-checked via TCP probes. Nginx load-balances across healthy backends with auto-generated configs.

Quick Expose

Devices on the subnet can create, list, and remove public Zrok shares with a single curl — no credentials required. The gateway resolves the caller from its DHCP lease and immediately provisions a public URL. Enable per-device from the dashboard.

Overlay Networking (Zrok/OpenZiti)

Expose resources publicly or privately through Zrok tunnels without port forwarding. Share services across Tunneld instances — bind remote shares locally and add them to your nginx pool for distributed load balancing.

Mesh Networking

Connect multiple Tunneld nodes into a single mesh through a relay coordinator. Each node registers outbound-only over WireGuard, receives a mesh IP, and syncs peers automatically. Tag LAN devices with wg:: prefixes to expose them to the mesh — no port forwarding required.

Distributed Service Pooling

Combine local and remote backends in a single resource pool. Nginx distributes traffic across all entries — whether they're on your subnet or bound from a peer's Tunneld instance over the overlay.

First-Run Setup Wizard

Guided onboarding flow after initial account creation: connect to Wi-Fi, optionally configure the overlay network control plane and mesh relay.

Architecture

Component Role
dnsmasq DHCP server + DNS resolver forwarding to user-configured upstream
nginx Reverse proxy with per-resource SSL and upstream load balancing
iptables NAT, packet forwarding, and DNS interception
Zrok v2/OpenZiti Overlay tunnel orchestration (namespace names, share, access)
WireGuard Mesh networking interface (wg-mesh) for node-to-node connectivity via relay
Elixir/Phoenix Application server, LiveView dashboard, GenServer process management

Diagrams

Detailed architecture diagrams with Mermaid (rendered on GitHub):

Installation

Tunneld is designed for Debian-based SBCs such as Raspberry Pi, NanoPi, or any custom ARM64 setup.

curl -sSf https://raw.githubusercontent.com/toreanjoel/tunneld-installer/main/install.sh | sudo bash

The installer handles all dependencies: dnsmasq, dhcpcd, nginx, iptables, and zrok2.

Project Structure

lib/
  tunneld/
    application.ex          # OTP supervision tree
    config.ex               # Shared config helpers
    persistence.ex          # Atomic JSON file persistence with backup recovery
    iptables.ex             # iptables firewall rule management
    cert_manager.ex         # SSL certificate lifecycle (root CA + per-resource)
    servers/
      session.ex            # In-memory IP-keyed auth sessions
      auth.ex               # Login credentials (bcrypt + WebAuthn)
      resources.ex          # Resource registry (CRUD, Zrok shares, nginx, DNS, health)
      devices.ex            # DHCP lease monitoring and revocation
      services.ex           # systemd service monitoring (dnsmasq, dhcpcd, etc.)
      wlan.ex               # Wi-Fi interface management (wpa_supplicant)
      nginx.ex              # Nginx reverse proxy config generation
      dns_config.ex         # DNS server IP configuration
      zrok.ex               # Zrok v2 CLI orchestration (names, shares, access units)
      sqm.ex                # Smart Queue Management (tc/CAKE)
      wireguard.ex          # WireGuard keypair and wg-mesh interface
      mesh.ex               # Mesh relay coordinator client
      updater.ex            # OTA update checking
      system_resources.ex   # CPU, memory, disk monitoring
  tunneld_web/
    live/
      dashboard.ex          # Main dashboard LiveView
      dashboard/actions.ex  # Action dispatcher
      setup.ex              # First-run setup wizard
      login.ex              # Login/signup with WebAuthn support
      components/           # LiveView components (devices, resources, services, sidebar, etc.)

Development

Run Tunneld locally with mocked hardware interactions:

  1. Install Elixir 1.18+ and Erlang/OTP 27+
  2. Install dependencies: mix deps.get
  3. Install JS/CSS tooling: mix assets.setup
  4. Start the server: MOCK_DATA=true mix phx.server

Visit localhost:4000 in your browser.

The MOCK_DATA=true flag stubs all system commands (systemctl, wpa_cli, iw, tc, etc.) with fake data so you can develop on any OS without hardware.

Running Tests

MOCK_DATA=true mix test

Version Management

mix version          # show current version
mix version patch    # bump patch (0.10.5 -> 0.10.6)
mix version minor    # bump minor (0.10.5 -> 0.11.0)
mix version major    # bump major (0.10.5 -> 1.0.0)

Updates both mix.exs and config/config.exs.

Contributing

See CONTRIBUTING.md for guidelines on setting up your dev environment, running tests, and submitting changes.

License

Apache 2.0

Releases

No releases published

Contributors