Sign inSign up

spaleks/technitium-api-proxy

By spaleks

Updated 5 months ago

Deprecated! Moved to: spaaleks/technitium-api-proxy

Image
0

2.1K

spaleks/technitium-api-proxy repository overview

Technitium API Proxy

A security proxy for Technitium DNS Server that adds fine-grained access control to the Technitium HTTP API. It runs as a standalone FastAPI service, forwarding allowed requests to the upstream Technitium server while enforcing token-based policies.

Clients use the standard Technitium API. They just point at the proxy instead of Technitium directly.


Features

  • YAML-driven configuration (config.yml) with per-token access policies
  • Zone-scoped tokens that restrict which DNS zones a token can access
  • Operation filtering to limit tokens to specific CRUD operations (get, add, update, delete)
  • Record type filtering to restrict tokens to specific DNS record types (A, AAAA, CNAME, TXT, etc.)
  • Subdomain filtering to limit tokens to manage records under a specific subdomain prefix
  • Global read-only tokens that allow full read access across all zones without write permissions
  • Tiered endpoint classification where only record and zone-list endpoints are proxied; zone management and admin endpoints are blocked
  • Zone list filtering where /api/zones/list responses only show zones the token is allowed to access
  • Structured audit logging via structlog
  • Multi-arch Docker images (linux/amd64, linux/arm64)
  • Standalone binary builds via PyInstaller

How It Works

The proxy sits between clients and the Technitium DNS Server:

Client --> Proxy (port 31399) --> Technitium (port 5380)
  1. Client sends a request with their token (via X-API-Token header or ?token= query param)
  2. Proxy validates the token against the configured policy
  3. If allowed, the request is forwarded to Technitium
  4. The response is returned to the client (with zone list filtering applied if applicable)
Endpoint Tiers
TierEndpointsAccess
Tier 1/api/zones/records/*, /api/zones/listAllowed (with policy checks)
Tier 2/api/zones/create, /api/zones/delete, /api/zones/enable, /api/zones/disable, /api/zones/import, /api/zones/exportBlocked
Tier 3All other /api/* (admin, settings, etc.)Blocked

Docker

Docker Compose
services:
  technitium-api-proxy:
    image: spaleks/technitium-api-proxy:latest
    # or quay.io/spaleks/technitium-api-proxy:latest
    ports:
      - "31399:31399"
    volumes:
      - ./config.yml:/app/config.yml:ro
Standalone
docker run --rm \
  -p 31399:31399 \
  -v "$(pwd)/config.yml:/app/config.yml:ro" \
  spaleks/technitium-api-proxy:latest

Configuration (config.yml)

technitium:
  url: "http://localhost:5380"
  token: "your-admin-api-token"
  verify_ssl: true

tokens:
  # Full access to a zone
  - name: "full-access"
    token: "client-secret-token"
    zones:
      - name: "example.com"
        allowed_record_types: ["A", "AAAA", "CNAME", "TXT"]
        allowed_operations: ["list", "get", "add", "update", "delete"]

  # Only manage records under app.example.com
  # Allows: app.example.com, api.app.example.com, v2.app.example.com
  # Denies: www.example.com, mail.example.com
  - name: "app-team"
    token: "app-team-secret"
    zones:
      - name: "example.com"
        subdomain_filter: "app."
        allowed_record_types: ["A", "AAAA", "CNAME"]
        allowed_operations: ["list", "get", "add", "update", "delete"]

  # Read-only access to all zones (no zone scoping)
  - name: "monitoring"
    token: "monitoring-secret"
    global_read_only: true
Token Options
FieldTypeDefaultDescription
namestringrequiredDisplay name for audit logs
tokenstringrequiredThe secret token clients use to authenticate
global_read_onlyboolfalseAllow read-only access to all zones (ignores zones)
zoneslist[]Zone-level access policies
Zone Policy Options
FieldTypeDefaultDescription
namestringrequiredDNS zone name (e.g. example.com)
allowed_record_typeslist[] (all)Restrict to specific record types (A, AAAA, CNAME, TXT, MX, etc.)
allowed_operationslist[] (all)Restrict to specific operations (get, add, update, delete)
subdomain_filterstringnullOnly allow records whose domain starts with this prefix

Empty lists mean "all allowed". Omit allowed_record_types to allow all record types, omit allowed_operations to allow all operations.


Usage (Local)

Binary

Download the binary from the releases page:

chmod +x technitium-api-proxy
CONFIG_PATH=./config.yml ./technitium-api-proxy
From Source
git clone https://github.com/spaaleks/technitium-api-proxy.git
cd technitium-api-proxy
bin/start.sh

Environment Variables

VariableDefaultDescription
CONFIG_PATHconfig.ymlPath to the YAML configuration file
HOST0.0.0.0Host/IP to bind
PORT31399Port to bind
LOG_LEVELinfoLog level (debug, info, warning, error)

Authentication

Clients authenticate by passing their token in one of two ways:

Header (preferred):

curl -H "X-API-Token: your-token" http://proxy:31399/api/zones/list

Query parameter:

curl http://proxy:31399/api/zones/list?token=your-token

The header takes precedence if both are provided.


Credits

Inspired by powerdns-api-proxy and the Technitium feature request TechnitiumSoftware/DnsServer#958.


License

MIT

Tag summary

Content type

Image

Digest

sha256:d154554a4

Size

50.1 MB

Last updated

6 months ago

docker pull spaleks/technitium-api-proxy