Files
Charon/docs/issues/hectate.md

5.5 KiB

Hecate: Tunnel & Pathway Manager

1. Overview

Hecate is the internal module within Charon responsible for managing third-party tunneling services. It serves as the "Goddess of Pathways," allowing Charon to route traffic not just to local ports, but through encrypted tunnels to remote networks without exposing ports on the public internet.

2. Architecture

Hecate is not a separate binary; it is a Go package (internal/hecate) running within the main Charon daemon.

2.1 The Provider Interface

To support multiple services (Tailscale, Cloudflare, Netbird), Hecate uses a strict Interface pattern.

type TunnelProvider interface {
    // Name returns the unique ID of the provider (e.g., "tailscale-01")
    Name() string

    // Status returns the current health (Connected, Connecting, Error)
    Status() TunnelState

    // Start initiates the tunnel daemon
    Start(ctx context.Context) error

    // Stop gracefully terminates the connection
    Stop() error

    // GetAddress returns the internal IP/DNS routed through the tunnel
    GetAddress() string
}

2.2 Supported Integrations (Phase 1)

Cloudflare Tunnels (cloudflared)

  • Mechanism: Charon manages the cloudflared binary via os/exec.
  • Config: User provides the Token via the UI.
  • Outcome: Exposes Charon directly to the edge without opening port 80/443 on the router.

Tailscale / Headscale

  • Mechanism: Uses tsnet (Tailscale's Go library) to embed the node directly into Charon, OR manages the tailscaled socket.
  • Outcome: Charon becomes a node on the Mesh VPN.

3. Dashboard Implementation (Frontend)

A new tab "Hecate / Tunnels" will be added to the Charon Dashboard.

  • Tunnel Cards: Display status of connected services.
  • Auth Manager: Input fields for API Keys/Auth Tokens.
  • Routing Table: A visual map showing which external domains map to which tunnel.

4. API Endpoints

  • GET /api/hecate/status - Returns health of all tunnels.
  • POST /api/hecate/configure - Accepts auth tokens and provider types.
  • POST /api/hecate/logs - Streams logs from the underlying tunnel binary (e.g., cloudflared logs) for debugging.

5. Security (Cerberus Integration)

Traffic entering through Hecate must still pass through Cerberus.

  • Tunnels terminate before the middleware chain.
  • Requests from a Cloudflare Tunnel are tagged source:tunnel and subjected to the same WAF rules as standard traffic.

6. Implementation Details

6.1 Process Supervision

Hecate will act as a process supervisor for external binaries like cloudflared.

  • Supervisor Pattern: A TunnelManager struct will maintain a map of active TunnelProvider instances.
  • Lifecycle:
    • On startup, TunnelManager loads enabled configs from the DB.
    • It launches the binary using os/exec.
    • It monitors the process state. If the process exits unexpectedly, it triggers a Restart Policy (Exponential Backoff: 5s, 10s, 30s, 1m).
  • Graceful Shutdown: When Charon shuts down, Hecate must send SIGTERM to all child processes and wait (with timeout) for them to exit.

6.2 Secrets Management

API tokens and sensitive credentials must not be stored in plaintext.

  • Encryption: Sensitive fields (like Cloudflare Tokens) will be encrypted at rest in the SQLite database using AES-GCM.
  • Key Management: An encryption key will be generated on first run and stored in data/keys/hecate.key (secured with 600 permissions), or provided via CHARON_SECRET_KEY env var.

6.3 Logging & Observability

  • Capture: The TunnelProvider implementation will attach to the Stdout and Stderr pipes of the child process.
  • Storage:
    • Hot Logs: A circular buffer (Ring Buffer) in memory (last 1000 lines) for real-time dashboard viewing.
    • Cold Logs: Rotated log files stored in data/logs/tunnels/<provider>.log.
  • Streaming: The frontend will consume logs via a WebSocket endpoint (/api/ws/hecate/logs/:id) or Server-Sent Events (SSE) to display real-time output.

6.4 Frontend Components

  • TunnelStatusBadge: Visual indicator (Green=Connected, Yellow=Starting, Red=Error/Stopped).
  • LogViewer: A terminal-like component (using xterm.js or a virtualized list) to display the log stream.
  • ConfigForm: A dynamic form that renders fields based on the selected provider (e.g., "Token" for Cloudflare, "Auth Key" for Tailscale).

7. Database Schema

We will introduce a new GORM model TunnelConfig in internal/models.

package models

import (
	"time"
	"github.com/google/uuid"
	"gorm.io/datatypes"
)

type TunnelProviderType string

const (
	ProviderCloudflare TunnelProviderType = "cloudflare"
	ProviderTailscale  TunnelProviderType = "tailscale"
)

type TunnelConfig struct {
	ID        uuid.UUID          `gorm:"type:uuid;primaryKey" json:"id"`
	Name      string             `gorm:"not null" json:"name"` // User-friendly name (e.g., "Home Lab Tunnel")
	Provider  TunnelProviderType `gorm:"not null" json:"provider"`

	// EncryptedCredentials stores the API token or Auth Key.
	// It is encrypted at rest and decrypted only when starting the process.
	EncryptedCredentials []byte `gorm:"not null" json:"-"`

	// Configuration stores provider-specific settings (JSON).
	// e.g., Cloudflare specific flags, region settings, etc.
	Configuration datatypes.JSON `json:"configuration"`

	IsActive  bool      `gorm:"default:false" json:"is_active"` // User's desired state
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}