lazydns

Admin API Usage Guide

The Admin API provides runtime management and monitoring capabilities for the Lazy DNS server without requiring a restart. This document covers all available endpoints, configuration, and usage examples.

Table of Contents

Overview

The Admin API is a separate HTTP server that runs alongside your main DNS servers. It provides endpoints for:

Features

Limitations

Configuration

Basic Setup

Enable the Admin API in your config.yaml:

admin:
  enabled: true
  addr: "127.0.0.1:8080"

Configuration Options

Option Type Default Description
enabled boolean false Enable/disable the admin API
addr string 127.0.0.1:8080 Listen address and port

Environment Variables

You can override the admin configuration using environment variables:

# Enable the admin API
export ADMIN_ENABLED=true

# Set the listen address
export ADMIN_ADDR=0.0.0.0:8080

# Start the server
lazydns

Supported boolean values for ADMIN_ENABLED: true, 1, yes (case-insensitive)

Examples

admin:
  enabled: true
  addr: "127.0.0.1:8080"

Internal Network

admin:
  enabled: true
  addr: "192.168.1.100:8080"

All Interfaces (Use with Caution)

admin:
  enabled: true
  addr: "0.0.0.0:8080"

Security Considerations

Important: The Admin API has no built-in authentication. Anyone who can connect to the configured address can:

Security Recommendations

  1. Bind to Localhost: Use 127.0.0.1:8080 (default) for single-machine setups
  2. Firewall Rules: Restrict access via network-level firewall
  3. Reverse Proxy with Auth: Use a reverse proxy (nginx, HAProxy) with authentication:
    location /api/ {
        auth_basic "Admin API";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass http://127.0.0.1:8080;
    }
    
  4. VPN/Private Network: Run the server on a private network, access via VPN
  5. Application-Level Auth: Implement auth in a reverse proxy layer

Example: nginx Reverse Proxy with Basic Auth

server {
    listen 8443 ssl http2;
    server_name admin.example.com;

    # SSL configuration
    ssl_certificate /etc/ssl/certs/cert.pem;
    ssl_certificate_key /etc/ssl/private/key.pem;

    location / {
        auth_basic "Admin API";
        auth_basic_user_file /etc/nginx/.htpasswd;

        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

API Reference

Server Status

Endpoint: GET /api/server/status

Returns basic information about the server’s operational status.

Request

curl http://127.0.0.1:8080/api/server/status

Response

{
  "status": "running",
  "version": "0.2.8"
}

HTTP Status Codes

Use Cases


Cache Statistics

Endpoint: GET /api/cache/stats

Retrieves detailed statistics about cache performance and utilization.

Request

curl http://127.0.0.1:8080/api/cache/stats

Response

{
  "size": 245,
  "hits": 5800,
  "misses": 1200,
  "evictions": 42,
  "hit_rate": 82.86
}

Response Fields

Field Type Description
size number Current number of entries in the cache
hits number Total cache hits since server start
misses number Total cache misses since server start
evictions number Entries removed by LRU eviction policy
hit_rate number Cache hit rate as percentage (0-100)

HTTP Status Codes

Interpretation

The hit rate tells you how often cached results are used:

hit_rate = (hits / (hits + misses)) * 100

Use Cases


Cache Control

Endpoint: POST /api/cache/control

Perform control operations on the cache system.

Request

Clear Cache

curl -X POST http://127.0.0.1:8080/api/cache/control \
  -H "Content-Type: application/json" \
  -d '{"action": "clear"}'

Request Body

{
  "action": "clear"
}

Response (Success)

{
  "message": "Cache cleared successfully"
}

Response (Error)

{
  "error": "Cache not configured"
}

HTTP Status Codes

Supported Actions

Action Description
clear Remove all entries from the cache

Use Cases

Important Notes


Configuration Reload

Endpoint: POST /api/config/reload

Reload configuration from a file and validate it. This is a hot-reload operation that updates the in-memory configuration.

Request

With Custom Path

curl -X POST http://127.0.0.1:8080/api/config/reload \
  -H "Content-Type: application/json" \
  -d '{"path": "/etc/lazydns/config.yaml"}'

With Default Path

curl -X POST http://127.0.0.1:8080/api/config/reload \
  -H "Content-Type: application/json" \
  -d '{"path": null}'

Or:

curl -X POST http://127.0.0.1:8080/api/config/reload \
  -H "Content-Type: application/json" \
  -d '{}'

Request Body

{
  "path": "/etc/lazydns/config.yaml"
}

Response (Success)

{
  "message": "Configuration reloaded from /etc/lazydns/config.yaml"
}

Response (Error)

{
  "error": "Configuration validation failed: invalid port number"
}

HTTP Status Codes

Behavior

  1. Loads the configuration file from disk
  2. Validates the configuration structure
  3. Updates the in-memory configuration
  4. Does not restart plugins (requires full server restart for some changes)

Configuration Fields That Take Effect Immediately

Configuration Fields That Require Server Restart

Use Cases

Important Notes


Examples

curl Examples

Check if server is running

curl -s http://127.0.0.1:8080/api/server/status | jq .

Get cache statistics and parse with jq

curl -s http://127.0.0.1:8080/api/cache/stats | jq .

Get only the hit rate

curl -s http://127.0.0.1:8080/api/cache/stats | jq .hit_rate

Clear cache and show result

curl -s -X POST http://127.0.0.1:8080/api/cache/control \
  -H "Content-Type: application/json" \
  -d '{"action": "clear"}' | jq .

Monitor cache in real-time (every 5 seconds)

watch -n 5 'curl -s http://127.0.0.1:8080/api/cache/stats | jq .'

Reload config with error checking

response=$(curl -s -w "\n%{http_code}" -X POST \
  http://127.0.0.1:8080/api/config/reload \
  -H "Content-Type: application/json" \
  -d '{}')

body=$(echo "$response" | head -n -1)
code=$(echo "$response" | tail -n 1)

if [ "$code" = "200" ]; then
  echo "Config reloaded successfully"
  echo "$body" | jq .
else
  echo "Config reload failed with code $code"
  echo "$body" | jq .error
fi

HTTP Status Codes

Code Meaning Common Causes
200 OK Request succeeded
400 Bad Request Invalid action, malformed JSON, validation error
404 Not Found Cache not configured, plugin not available
500 Internal Server Error Plugin downcast failed, file I/O errors

Status Code Decision Tree

Request fails?
├─ Network error → Retry with backoff
├─ 404 Not Found → Check configuration
├─ 400 Bad Request → Check request format and action
├─ 500 Internal Server Error → Check logs and plugin status
└─ 200 OK → Operation succeeded

Monitoring Integration

Prometheus Integration

The Admin API complements the separate Monitoring Server which provides:

For production monitoring, use both:

admin:
  enabled: true
  addr: "127.0.0.1:8080"

monitoring:
  enabled: true
  addr: "127.0.0.1:9090"

Example Prometheus Scrape Config

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: "lazydns"
    static_configs:
      - targets: ["localhost:9090"]

Grafana Dashboards

You can create dashboards using metrics from the monitoring server:

For real-time management, use Admin API endpoints directly in dashboard plugins.

Cache metrics mapping & Prometheus usage

The cache subsystem exposes the following Prometheus metrics when the crate is built with the metrics feature (enabled by default):

Notes:

Useful PromQL examples
(sum(rate(dns_cache_hits_total[5m]))
  / (sum(rate(dns_cache_hits_total[5m])) + sum(rate(dns_cache_misses_total[5m]))))
- alert: LowCacheHitRate
  expr: (sum(rate(dns_cache_hits_total[5m]))
    / (sum(rate(dns_cache_hits_total[5m])) + sum(rate(dns_cache_misses_total[5m])))) < 0.7
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "Cache hit rate below 70%"
    description: "Cache hit rate is below 70% for at least 5 minutes."
- alert: HighCacheSize
  expr: max(dns_cache_size) > 10000
  for: 10m
  labels:
    severity: warning
  annotations:
    summary: "Cache size exceeds threshold"
    description: "Cache size is larger than expected (threshold = 10000)."
Cross-check with Admin API

For quick, on-demand verification you can cross-check Prometheus metrics against the Admin API snapshot:

curl http://127.0.0.1:8080/api/cache/stats | jq .
# compare size/hits/misses with Prometheus values for sanity checks

Alerting Examples

Alert: Low Cache Hit Rate

- alert: LowCacheHitRate
  expr: cache_hit_rate < 0.7
  for: 5m
  annotations:
    summary: "Cache hit rate below 70%"

Alert: High Cache Evictions

- alert: HighEvictions
  expr: increase(cache_evictions_total[5m]) > 1000
  for: 5m
  annotations:
    summary: "High number of cache evictions"

Troubleshooting

Connection Refused

Problem: curl: (7) Failed to connect

Causes:

Solution:

# Verify enabled in config
grep -A 2 'admin:' config.yaml

# Check if port is listening
netstat -tlnp | grep 8080

# Check firewall
sudo ufw allow 8080

404 Not Found on Cache Endpoints

Problem: {"error": "Cache not configured"}

Causes:

Solution:

# Ensure cache is in plugin chain
plugins:
  - type: cache
    args:
      size: 10000

High Latency After Cache Clear

Problem: DNS queries slow after clearing cache

Expected Behavior: This is normal. Cache clear forces upstream queries for all domains.

Solution:

Admin API Not Responding

Problem: Admin API hangs or times out

Diagnostic Steps:

# Test connectivity
timeout 5 curl -v http://127.0.0.1:8080/api/server/status

# Check server logs
tail -f /var/log/lazydns/main.log

# Check system resources
ps aux | grep lazydns
free -h
df -h

Unicode/Special Characters in Error Messages

If you see mojibake (garbled characters) in responses, it’s likely a terminal encoding issue:

# Force UTF-8
export LANG=en_US.UTF-8
curl http://127.0.0.1:8080/api/cache/stats | jq .