Skip to content

DNS Load Balancer

DNS-based load balancing across multiple backend servers with health checks.

All endpoints below are mounted under /api. Authentication: Authorization: Bearer <token> unless noted as public.

Endpoint count: 28

Endpoints

Method Path Handler Guards
GET /api/dnslb/address-lists getDnslbAddressLists RequirePermission(db, "administrative_operations")
POST /api/dnslb/address-lists saveDnslbAddressList RequirePermission(db, "administrative_operations")
DELETE /api/dnslb/address-lists/:name deleteDnslbAddressList RequirePermission(db, "administrative_operations")
GET /api/dnslb/config getDnslbConfig RequirePermission(db, "administrative_operations")
POST /api/dnslb/config saveDnslbConfig RequirePermission(db, "administrative_operations")
GET /api/dnslb/domain-lists getDnslbDomainLists RequirePermission(db, "administrative_operations")
POST /api/dnslb/domain-lists saveDnslbDomainList RequirePermission(db, "administrative_operations")
DELETE /api/dnslb/domain-lists/:name deleteDnslbDomainList RequirePermission(db, "administrative_operations")
POST /api/dnslb/domain-lists/reorder reorderDnslbDomainLists RequirePermission(db, "administrative_operations")
GET /api/dnslb/multi-servers getDnslbMultiServers RequirePermission(db, "administrative_operations")
POST /api/dnslb/multi-servers addDnslbMultiServer RequirePermission(db, "administrative_operations")
DELETE /api/dnslb/multi-servers/:id deleteDnslbMultiServer RequirePermission(db, "administrative_operations")
POST /api/dnslb/multi-servers/:id/sync syncDnslbMultiServer RequirePermission(db, "administrative_operations")
POST /api/dnslb/multi-servers/:id/test testDnslbMultiServer RequirePermission(db, "administrative_operations")
POST /api/dnslb/multi-servers/sync-all syncAllDnslbMultiServers RequirePermission(db, "administrative_operations")
POST /api/dnslb/restart dnslbAction RequirePermission(db, "administrative_operations")
GET /api/dnslb/rules getDnslbRules RequirePermission(db, "administrative_operations")
POST /api/dnslb/rules addDnslbRule RequirePermission(db, "administrative_operations")
DELETE /api/dnslb/rules/:id deleteDnslbRule RequirePermission(db, "administrative_operations")
POST /api/dnslb/rules/reorder reorderDnslbRules RequirePermission(db, "administrative_operations")
GET /api/dnslb/servers getDnslbServers RequirePermission(db, "administrative_operations")
POST /api/dnslb/servers addDnslbServer RequirePermission(db, "administrative_operations")
DELETE /api/dnslb/servers/:name deleteDnslbServer RequirePermission(db, "administrative_operations")
POST /api/dnslb/start dnslbAction RequirePermission(db, "administrative_operations")
GET /api/dnslb/stats getDnslbStats RequirePermission(db, "administrative_operations")
GET /api/dnslb/status getDnslbStatus RequirePermission(db, "administrative_operations")
POST /api/dnslb/stop dnslbAction RequirePermission(db, "administrative_operations")
POST /api/dnslb/sync-files syncDnslbFiles RequirePermission(db, "administrative_operations")

Source

Handlers for this section live in api/routes/handlers_*.go in the StarkOne source. Each handler binds its request body with gin.ShouldBindJSON(&req) and responds with the standard envelope:

{ "data": { ... } }

On error:

{ "error": { "code": "string", "message": "string" } }

Reference

GET /api/dnslb/address-lists

Lists all saved address (IP/CIDR) lists by reading the *.json files in /etc/dnsdist/lists/.

Guards: RequirePermission(db, "administrative_operations")

Response - 200 OK

Note: this handler returns a flat body (not the { "data": ... } envelope).

{
  "lists": [
    {
      "name": "office",
      "action": "allow",
      "addresses": ["203.0.113.0/24"],
      "rate_limit": 0
    }
  ]
}

If the lists directory cannot be read, returns { "lists": [] }.

Example

curl https://panel.example.com:2087/api/dnslb/address-lists \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/address-lists

Creates or overwrites an address list (stored as a JSON file) and regenerates the address-list rules section in dnsdist.conf.

Guards: RequirePermission(db, "administrative_operations")

Request body

{
  "name": "string (required)",
  "action": "string (required)",
  "addresses": ["string (required)"],
  "rate_limit": "int (optional)"
}
Field Type Required Description
name string yes List name. Non-[a-zA-Z0-9_-] characters are stripped; must be non-empty after sanitizing. Used as the JSON filename.
action string yes One of allow, block, ratelimit. (Not enforced beyond the rule-generation switch; unknown values produce no rule.)
addresses string[] yes IP addresses or CIDR masks added via addMask().
rate_limit int no Max QPS per IP, only used when action is ratelimit. Defaults to 10 if <= 0.

Response - 200 OK

{ "success": true }

Errors

Status Code Meaning
400 bad_request Body failed JSON binding, or name was empty after sanitizing.
500 write_failed Could not write the list JSON file.
500 config_failed Rule regeneration / config write failed.

Side effects

  • Creates /etc/dnsdist/lists/ (if missing) and writes <name>.json (mode 0640).
  • Rewrites the "Address Lists (managed by panel)" section of /etc/dnsdist/dnsdist.conf.
  • Validates config (dnsdist --check-config) and runs systemctl restart dnsdist.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/address-lists \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"office","action":"allow","addresses":["203.0.113.0/24"]}'

DELETE /api/dnslb/address-lists/:name

Deletes an address list JSON file and regenerates the address-list rules section.

Guards: RequirePermission(db, "administrative_operations")

Path parameters

Name Type Description
name string List name. Non-[a-zA-Z0-9_-] characters are stripped before resolving <name>.json.

Response - 200 OK

{ "success": true }

Errors

Status Code Meaning
500 config_failed Rule regeneration / config write failed.

Side effects

  • Removes /etc/dnsdist/lists/<name>.json (missing file is ignored).
  • Rewrites the address-list section of dnsdist.conf and runs systemctl restart dnsdist.

Example

curl -X DELETE https://panel.example.com:2087/api/dnslb/address-lists/office \
  -H "Authorization: Bearer $TOKEN"

GET /api/dnslb/config

Returns the full raw contents of /etc/dnsdist/dnsdist.conf as a string.

Guards: RequirePermission(db, "administrative_operations")

Response - 200 OK

Flat body (not enveloped). Returns { "config": "" } if the file cannot be read.

{ "config": "-- dnsdist.conf contents ..." }

Example

curl https://panel.example.com:2087/api/dnslb/config \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/config

Overwrites dnsdist.conf with the supplied content after backing up the current file and validating syntax.

Guards: RequirePermission(db, "administrative_operations")

Request body

{ "config": "string (required)" }
Field Type Required Description
config string yes Full replacement contents for dnsdist.conf.

Response - 200 OK

{ "success": true }

Errors

Status Code Meaning
400 bad_request Body failed JSON binding.
400 invalid_config dnsdist --check-config rejected the new config; old config was backed up.
500 write_failed Could not write dnsdist.conf.

Side effects

  • Backs up the existing config to /etc/dnsdist/backups/dnsdist.conf.<unixtime> (mode 0640).
  • Writes the new dnsdist.conf (mode 0640), validates it, then runs systemctl restart dnsdist.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/config \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"config":"setLocal(\"0.0.0.0:53\")"}'

GET /api/dnslb/domain-lists

Lists all domain lists by reading starkone-domains-*.txt files in /etc/dnsdist/, returning each list's domains, count, and configured action.

Guards: RequirePermission(db, "administrative_operations")

Response - 200 OK

Flat body (not enveloped). Returns { "lists": [] } if the directory cannot be read.

{
  "lists": [
    {
      "name": "ads",
      "action": "block",
      "domains": ["ads.example.com"],
      "count": 1
    }
  ]
}

The action comes from /etc/dnsdist/domain-lists-meta.json (defaults to block). Lists are sorted by the in-memory saved order when one exists.

Example

curl https://panel.example.com:2087/api/dnslb/domain-lists \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/domain-lists

Creates or overwrites a domain list text file, records its action in metadata, and regenerates the Lua domain-matching rules in dnsdist.conf.

Guards: RequirePermission(db, "administrative_operations")

Request body

{
  "name": "string (required)",
  "action": "string (required)",
  "domains": "string (required)"
}
Field Type Required Description
name string yes Lowercased; must be [a-z]+ only and at most 10 characters.
action string yes Must be block or whitelist.
domains string yes Newline-separated domains. Each is lowercased and stripped to [a-z0-9.-]; only entries containing a . are kept. At least one valid domain is required.

Response - 200 OK

{ "success": true, "count": 12 }

Errors

Status Code Meaning
400 bad_request Binding failed, name too long, name not [a-z]+, invalid action, or no valid domains.
500 write_error Could not write the domain text file.
500 config_error Regenerating domain rules / writing config failed.

Side effects

  • Writes /etc/dnsdist/starkone-domains-<name>.txt (mode 0644).
  • Updates /etc/dnsdist/domain-lists-meta.json with the action.
  • Rewrites the "Domain Lists (managed by panel)" section of dnsdist.conf and runs systemctl reload dnsdist.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/domain-lists \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"ads","action":"block","domains":"ads.example.com\ntrack.example.com"}'

DELETE /api/dnslb/domain-lists/:name

Deletes a domain list file and its metadata entry, then regenerates the domain rules.

Guards: RequirePermission(db, "administrative_operations")

Path parameters

Name Type Description
name string Domain list name (resolves starkone-domains-<name>.txt).

Response - 200 OK

{ "success": true }

Errors

Status Code Meaning
400 bad_request Empty name.
500 delete_error Removing the file failed (a missing file is not an error).
500 config_error Regenerating domain rules / writing config failed.

Side effects

  • Removes /etc/dnsdist/starkone-domains-<name>.txt.
  • Removes the entry from domain-lists-meta.json.
  • Rewrites the domain section of dnsdist.conf and runs systemctl reload dnsdist.

Example

curl -X DELETE https://panel.example.com:2087/api/dnslb/domain-lists/ads \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/domain-lists/reorder

Stores a new ordering for domain lists (in process memory) and regenerates the domain rules in that order.

Guards: RequirePermission(db, "administrative_operations")

Request body

{ "order": ["ads", "malware"] }
Field Type Required Description
order string[] no Domain list names in the desired order. Not marked binding:"required".

Response - 200 OK

{ "success": true }

Errors

Status Code Meaning
400 bad_request Body failed JSON binding.
500 config_error Regenerating domain rules / writing config failed.

Side effects

  • Updates the in-memory dnslbDomainOrder (not persisted across restarts).
  • Rewrites the domain section of dnsdist.conf and runs systemctl reload dnsdist.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/domain-lists/reorder \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"order":["ads","malware"]}'

GET /api/dnslb/multi-servers

Lists registered downstream DNSLB servers from the dnslb_servers database table.

Guards: RequirePermission(db, "administrative_operations")

Response - 200 OK

Flat body (not enveloped). Returns { "servers": [] } on query error or when empty.

{
  "servers": [
    {
      "id": 1,
      "name": "edge-1",
      "host": "203.0.113.10",
      "port": 2087,
      "api_key": "...",
      "status": "online",
      "last_check": "2026-06-17T10:00:00Z",
      "last_sync": null,
      "created_at": "2026-06-01T00:00:00Z"
    }
  ]
}

Example

curl https://panel.example.com:2087/api/dnslb/multi-servers \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/multi-servers

Registers a new downstream DNSLB server after verifying connectivity to its /api/version endpoint.

Guards: RequirePermission(db, "administrative_operations")

Request body

{
  "name": "string (required)",
  "host": "string (required)",
  "port": "int (optional)",
  "api_key": "string (required)"
}
Field Type Required Description
name string yes Display name for the server.
host string yes Hostname or IP of the remote panel.
port int no Remote panel port. Defaults to 2087 when 0.
api_key string yes Bearer token used to authenticate against the remote panel.

Response - 200 OK

{ "success": true, "message": "Server added successfully" }

Errors

Status Code Meaning
400 bad_request Body failed JSON binding.
400 connection_failed Could not connect to https://<host>:<port>/api/version.
400 auth_failed Remote returned 401/403.
400 server_error Remote returned a non-200 status.
400 duplicate A server with this host already exists (unique constraint).
500 db_error Insert failed.

Side effects

  • Makes an outbound HTTPS GET to the remote /api/version (TLS verification disabled).
  • Inserts a row into dnslb_servers with last_status='online'.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/multi-servers \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"edge-1","host":"203.0.113.10","port":2087,"api_key":"REMOTE_TOKEN"}'

DELETE /api/dnslb/multi-servers/:id

Removes a registered downstream server from the dnslb_servers table.

Guards: RequirePermission(db, "administrative_operations")

Path parameters

Name Type Description
id int Database id of the server row to delete.

Response - 200 OK

{ "success": true }

Errors

Status Code Meaning
500 db_error Delete failed.

Side effects

  • Deletes the matching row from dnslb_servers.

Example

curl -X DELETE https://panel.example.com:2087/api/dnslb/multi-servers/1 \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/multi-servers/:id/sync

Pushes this server's config, domain lists, and address lists to a single registered downstream server.

Guards: RequirePermission(db, "administrative_operations")

Path parameters

Name Type Description
id int Database id of the target server.

Request body

Optional. If binding fails, defaults to {rules:true, domains:true, addresses:true} (note: cleanOld defaults to false in that case).

{
  "rules": "bool (optional)",
  "domains": "bool (optional)",
  "addresses": "bool (optional)",
  "cleanOld": "bool (optional)"
}
Field Type Required Description
rules bool no Push dnsdist.conf to the remote /api/dnslb/config.
domains bool no Push starkone-domains-*.txt files and the domain metadata file.
addresses bool no Push address-list JSON files.
cleanOld bool no When set with domains/addresses, instructs the remote to delete its old files first.

Response - 200 OK

{ "success": true, "message": "Sync completed" }

Errors

Status Code Meaning
404 not_found No server with that id.
500 read_failed Local dnsdist.conf could not be read (only when rules is set).
400 sync_failed Config POST to the remote failed (remote also marked offline).

Side effects

  • Reads local dnsdist.conf, domain files, address-list files, and the domain metadata file.
  • Sends outbound HTTPS POSTs to the remote /api/dnslb/config and /api/dnslb/sync-files (TLS verification disabled).
  • Updates the server's last_status, last_check, and last_sync in dnslb_servers.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/multi-servers/1/sync \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rules":true,"domains":true,"addresses":true,"cleanOld":false}'

POST /api/dnslb/multi-servers/:id/test

Tests connectivity to a registered downstream server and records the resulting status.

Guards: RequirePermission(db, "administrative_operations")

Path parameters

Name Type Description
id int Database id of the target server.

Response - 200 OK

{ "status": "online" }

status is online if the remote /api/version returns 200, otherwise offline.

Errors

Status Code Meaning
404 not_found No server with that id.

Side effects

  • Makes an outbound HTTPS GET to the remote /api/version (TLS verification disabled).
  • Updates last_status and last_check in dnslb_servers.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/multi-servers/1/test \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/multi-servers/sync-all

Pushes config and lists to every registered downstream server, returning a per-server result map.

Guards: RequirePermission(db, "administrative_operations")

Request body

Optional. If binding fails, defaults to {rules:true, domains:true, addresses:true}.

{
  "rules": "bool (optional)",
  "domains": "bool (optional)",
  "addresses": "bool (optional)",
  "cleanOld": "bool (optional)"
}
Field Type Required Description
rules bool no Push dnsdist.conf to each remote.
domains bool no Push domain list files and metadata.
addresses bool no Push address-list JSON files.
cleanOld bool no Instruct remotes to delete old files first (with the matching flag).

Response - 200 OK

results maps each server id to one of synced, offline, or not found.

{ "success": true, "results": { "1": "synced", "2": "offline" } }

Errors

Status Code Meaning
500 db_error Failed to query the server list.

Side effects

  • Iterates all rows in dnslb_servers, sending outbound HTTPS POSTs to each remote's /api/dnslb/config and /api/dnslb/sync-files (TLS verification disabled).
  • Updates last_status, last_check, and last_sync per server.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/multi-servers/sync-all \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rules":true,"domains":true,"addresses":true}'

POST /api/dnslb/restart

Restarts the dnsdist service via systemd. Handled by dnslbAction("restart").

Guards: RequirePermission(db, "administrative_operations")

Response - 200 OK

{ "success": true }

Errors

Status Code Meaning
500 action_failed systemctl restart dnsdist returned an error.

Side effects

  • Runs systemctl restart dnsdist.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/restart \
  -H "Authorization: Bearer $TOKEN"

GET /api/dnslb/rules

Lists panel-managed protection rules parsed from the -- [RULE:N:START]/:END markers in dnsdist.conf.

Guards: RequirePermission(db, "administrative_operations")

Response - 200 OK

Flat body (not enveloped). Returns { "rules": [] } if the config cannot be read.

{
  "rules": [
    {
      "id": 0,
      "type": "query",
      "summary": "addAction(MaxQPSIPRule(100, 32, 48), DropAction())",
      "comment": "Rate limit: max 100 queries/sec per IP"
    }
  ]
}

type is response when the summary contains addResponseAction, otherwise query. summary is truncated to 80 chars.

Example

curl https://panel.example.com:2087/api/dnslb/rules \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/rules

Appends a protection rule to the rules section of dnsdist.conf, generating the dnsdist Lua for the chosen rule type.

Guards: RequirePermission(db, "administrative_operations")

Request body

{
  "rule_type": "string (required)",
  "value": "string (optional)",
  "comment": "string (optional)"
}
Field Type Required Description
rule_type string yes One of qps_ip, qtype_block, subnet_block, subnet_allow, regex_block, nxdomain_ratelimit, custom. Any other value returns an error.
value string no Parameter for the rule. Meaning depends on rule_type (max QPS, query type, subnet/CIDR, regex pattern, NXDOMAIN delay ms, or raw Lua for custom).
comment string no Overrides the auto-generated comment. For custom, supplies the comment.

Response - 201 Created

{ "success": true }

Errors

Status Code Meaning
400 bad_request Body failed JSON binding, or rule_type is unknown.
500 read_failed Could not read dnsdist.conf.
500 write_failed Could not write dnsdist.conf.

Side effects

  • Appends a marker-wrapped rule block to dnsdist.conf (mode 0640).
  • Validates config and runs systemctl restart dnsdist.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/rules \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"rule_type":"qps_ip","value":"50"}'

DELETE /api/dnslb/rules/:id

Removes a protection rule from dnsdist.conf, by marker block if present, otherwise by counting addAction/addResponseAction statements.

Guards: RequirePermission(db, "administrative_operations")

Path parameters

Name Type Description
id int Numeric rule id (the N in [RULE:N:...], or the positional index when markers are absent).

Response - 200 OK

{ "success": true }

Errors

Status Code Meaning
400 bad_request id is not an integer.
500 read_failed Could not read dnsdist.conf.
500 write_failed Could not write dnsdist.conf.

Side effects

  • Rewrites dnsdist.conf (mode 0640) with the rule removed and collapses duplicate blank lines.
  • Validates config and runs systemctl restart dnsdist.

Example

curl -X DELETE https://panel.example.com:2087/api/dnslb/rules/0 \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/rules/reorder

Reorders the marker-wrapped rule blocks in dnsdist.conf and reassigns their ids to match the new order.

Guards: RequirePermission(db, "administrative_operations")

Request body

{ "order": [2, 0, 1] }
Field Type Required Description
order int[] no Existing rule ids in the desired order. Position in the array becomes the new id. Not marked binding:"required".

Response - 200 OK

{ "success": true }

Errors

Status Code Meaning
400 bad_request Body failed JSON binding.
500 read_failed Could not read dnsdist.conf.
500 write_failed Could not write dnsdist.conf.

Side effects

  • Rewrites dnsdist.conf (mode 0640) with rule blocks reordered and renumbered.
  • Validates config and runs systemctl restart dnsdist.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/rules/reorder \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"order":[2,0,1]}'

GET /api/dnslb/servers

Lists backend servers parsed from newServer({...}) lines in dnsdist.conf.

Guards: RequirePermission(db, "administrative_operations")

Response - 200 OK

Flat body (not enveloped). Returns { "servers": [] } if the config cannot be read. weight and order default to 1; name falls back to address when absent.

{
  "servers": [
    {
      "name": "backend1",
      "address": "203.0.113.20",
      "pool": "",
      "weight": 1,
      "order": 1
    }
  ]
}

Example

curl https://panel.example.com:2087/api/dnslb/servers \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/servers

Adds (or replaces, by name) a backend newServer() entry in dnsdist.conf.

Guards: RequirePermission(db, "administrative_operations")

Request body

{
  "name": "string (required)",
  "address": "string (required)",
  "pool": "string (optional)",
  "weight": "int (optional)",
  "order": "int (optional)"
}
Field Type Required Description
name string yes Server name. Non-[a-zA-Z0-9_-] characters are stripped; must be non-empty after sanitizing. An existing server with the same name is removed first.
address string yes Backend address (e.g. 203.0.113.20 or 203.0.113.20:53).
pool string no dnsdist pool name. Omitted from the line if empty.
weight int no Server weight. Coerced to 1 if <= 0; only written when not 1.
order int no Server order. Coerced to 1 if <= 0; only written when not 1.

Response - 201 Created

{ "success": true }

Errors

Status Code Meaning
400 bad_request Body failed JSON binding, or name was empty after sanitizing.
500 read_failed Could not read dnsdist.conf.
500 write_failed Could not write dnsdist.conf.

Side effects

  • Rewrites dnsdist.conf (mode 0640) with the new/updated newServer() line.
  • Validates config and runs systemctl restart dnsdist.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/servers \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"backend1","address":"203.0.113.20","weight":2}'

DELETE /api/dnslb/servers/:name

Removes the newServer() line whose name matches the path parameter.

Guards: RequirePermission(db, "administrative_operations")

Path parameters

Name Type Description
name string Backend server name to remove.

Response - 200 OK

{ "success": true }

Errors

Status Code Meaning
500 read_failed Could not read dnsdist.conf.
500 write_failed Could not write dnsdist.conf.

Side effects

  • Rewrites dnsdist.conf (mode 0640) without the matching server.
  • Validates config and runs systemctl restart dnsdist.

Example

curl -X DELETE https://panel.example.com:2087/api/dnslb/servers/backend1 \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/start

Starts the dnsdist service via systemd. Handled by dnslbAction("start").

Guards: RequirePermission(db, "administrative_operations")

Response - 200 OK

{ "success": true }

Errors

Status Code Meaning
500 action_failed systemctl start dnsdist returned an error.

Side effects

  • Runs systemctl start dnsdist.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/start \
  -H "Authorization: Bearer $TOKEN"

GET /api/dnslb/stats

Returns dnsdist runtime statistics by piping showServers() and dumpStats() to the dnsdist console.

Guards: RequirePermission(db, "administrative_operations")

Response - 200 OK

Flat body (not enveloped). stats is a parsed key/value map from dumpStats(); server_stats is the raw text output of showServers(). Returns { "stats": {}, "server_stats": "" } if the console call fails.

{
  "stats": { "queries": 12345, "responses": 12000 },
  "server_stats": "..."
}

Side effects

  • Reads the console key from dnsdist.conf and runs dnsdist -c 127.0.0.1:5199 console commands.

Example

curl https://panel.example.com:2087/api/dnslb/stats \
  -H "Authorization: Bearer $TOKEN"

GET /api/dnslb/status

Reports whether dnsdist is installed and running, plus version and memory usage.

Guards: RequirePermission(db, "administrative_operations")

Response - 200 OK

Flat body (not enveloped). If dnsdist is not on PATH, returns { "installed": false, "running": false }.

{
  "installed": true,
  "running": true,
  "version": "1.8.0",
  "memory_mb": "42.5"
}

Side effects

  • Runs dnsdist --version, systemctl is-active dnsdist, and a ps command to read RSS.

Example

curl https://panel.example.com:2087/api/dnslb/status \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/stop

Stops the dnsdist service via systemd. Handled by dnslbAction("stop").

Guards: RequirePermission(db, "administrative_operations")

Response - 200 OK

{ "success": true }

Errors

Status Code Meaning
500 action_failed systemctl stop dnsdist returned an error.

Side effects

  • Runs systemctl stop dnsdist.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/stop \
  -H "Authorization: Bearer $TOKEN"

POST /api/dnslb/sync-files

Receives a batch of files from a master server and writes them under /etc/dnsdist/. Used as the sync target; it writes files only and does not regenerate rules.

Guards: RequirePermission(db, "administrative_operations")

Request body

{
  "files": [
    { "path": "/etc/dnsdist/starkone-domains-ads.txt", "content": "ads.example.com\n" }
  ],
  "clean_domains": "bool (optional)",
  "clean_lists": "bool (optional)"
}
Field Type Required Description
files object[] yes Each entry has path and content. Only paths under /etc/dnsdist/ are written; others are skipped.
files[].path string yes Absolute destination path (must start with /etc/dnsdist/).
files[].content string yes File contents to write.
clean_domains bool no If true, deletes existing /etc/dnsdist/starkone-domains-*.txt before writing.
clean_lists bool no If true, deletes existing /etc/dnsdist/lists/*.json before writing.

Response - 200 OK

Flat body (not enveloped). count is the number of files in the request.

{ "success": true, "count": 3 }

Errors

Status Code Meaning
400 bad_request Body failed JSON binding.

Side effects

  • Optionally deletes existing domain/address-list files (per the clean flags).
  • Creates parent directories and writes each in-scope file (mode 0644). Does not reload dnsdist.

Example

curl -X POST https://panel.example.com:2087/api/dnslb/sync-files \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"files":[{"path":"/etc/dnsdist/starkone-domains-ads.txt","content":"ads.example.com\n"}],"clean_domains":false}'