Tools¶
Operator tools: DNS servers, /etc/hosts, port utilities, DNS resolution.
All endpoints below are mounted under /api. Authentication: Authorization: Bearer <token> unless noted as public.
Endpoint count: 6
Endpoints¶
| Method | Path | Handler | Guards |
|---|---|---|---|
GET |
/api/tools/dns-servers |
getToolsDNSServers |
RequireSuperuser() |
POST |
/api/tools/dns-servers |
postToolsDNSServers |
RequireSuperuser() |
GET |
/api/tools/hosts |
getToolsHosts |
RequireSuperuser() |
POST |
/api/tools/hosts |
postToolsHosts |
RequireSuperuser() |
GET |
/api/tools/ports |
getToolsPorts |
RequireSuperuser() |
GET |
/api/tools/resolve |
getToolsResolve |
RequireSuperuser() |
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:
On error:
Reference¶
GET /api/tools/dns-servers¶
Returns the list of nameserver entries parsed from /etc/resolv.conf.
Guards: RequireSuperuser()
Response - 200 OK
The data field is an array of server objects (one per nameserver line).
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
read_failed |
/etc/resolv.conf could not be opened. |
Side effects - none (reads /etc/resolv.conf).
Example
curl -X GET https://panel.example.com:2087/api/tools/dns-servers \
-H "Authorization: Bearer $TOKEN"
POST /api/tools/dns-servers¶
Resets /etc/resolv.conf to a fixed set of public DNS servers (Cloudflare and Google); it ignores any request body.
Guards: RequireSuperuser()
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
write_failed |
/etc/resolv.conf could not be written. |
Side effects
- Overwrites
/etc/resolv.conf(mode0644) with a fixed list of public nameservers (1.1.1.1,8.8.8.8,1.0.0.1,8.8.4.4). The request body is not read or used.
Example
curl -X POST https://panel.example.com:2087/api/tools/dns-servers \
-H "Authorization: Bearer $TOKEN"
GET /api/tools/hosts¶
Reads /etc/hosts and returns it as a structured list of parsed lines.
Guards: RequireSuperuser()
Response - 200 OK
data.lines is an array of objects. Comment lines have comment: true with empty ip/hostname; entry lines carry the parsed ip and hostname. Every object includes the original raw line. Blank lines are skipped.
{
"data": {
"lines": [
{ "ip": "", "hostname": "", "comment": true, "raw": "# static entries" },
{ "ip": "203.0.113.20", "hostname": "host.example.com", "comment": false, "raw": "203.0.113.20 host.example.com" }
]
}
}
Errors
| Status | Code | Meaning |
|---|---|---|
500 |
read_failed |
/etc/hosts could not be read. |
Side effects - none (reads /etc/hosts).
Example
POST /api/tools/hosts¶
Overwrites the entire /etc/hosts file with the supplied raw content.
Guards: RequireSuperuser()
Request body
| Field | Type | Required | Description |
|---|---|---|---|
content |
string | no (binding) | Full replacement text for /etc/hosts. No binding:"required" tag is set, but an empty/absent value writes an effectively empty file. A trailing newline is appended automatically. |
Response - 200 OK
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
invalid_body |
Request body is not valid JSON. |
500 |
write_failed |
/etc/hosts could not be written. |
Side effects
- Overwrites
/etc/hosts(mode0644) withcontentplus a trailing newline.
Example
curl -X POST https://panel.example.com:2087/api/tools/hosts \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"content": "127.0.0.1 localhost\n203.0.113.20 host.example.com"}'
GET /api/tools/ports¶
Lists listening TCP/UDP ports (via ss), annotates each with whether it is opened in the CSF firewall, and returns the count of established connections.
Guards: RequireSuperuser()
Response - 200 OK
data.ports is a deduplicated, port-sorted array. Entries sharing a port+protocol are merged, with their bind addresses joined by ,. csf_open reflects whether the port appears in TCP_IN/UDP_IN in /etc/csf/csf.conf. data.established is the number of established TCP connections.
{
"data": {
"ports": [
{ "port": 2087, "protocol": "tcp", "address": "0.0.0.0", "process": "starkone", "pid": "1234", "csf_open": true }
],
"established": 5
}
}
Side effects
- Executes
ss -tlnp,ss -ulnp, andss -tn state established(read-only). Reads/etc/csf/csf.confif present (missing/unreadable file is ignored).
Example
GET /api/tools/resolve¶
Resolves a hostname to a single IPv4 (default) or IPv6 address using the system resolver and reports how long the lookup took.
Guards: RequireSuperuser()
Query parameters
| Name | Type | Optional | Description |
|---|---|---|---|
host |
string | no | Hostname to resolve. Required; a missing/empty value returns 400. |
type |
string | yes | Record type. AAAA resolves IPv6 (ip6); any other value (default A) resolves IPv4 (ip4). |
Response - 200 OK
On success, returns the first resolved address. Note that resolution failures also return 200 with an error field inside data and an empty ip (not an HTTP error status).
Failure shape (still 200 OK):
{ "data": { "host": "host.example.com", "ip": "", "time_ms": 12, "error": "resolution failed", "type": "A" } }
Errors
| Status | Code | Meaning |
|---|---|---|
400 |
missing_host |
The host query parameter was absent or empty. |
Side effects - none (performs a DNS lookup only).
Example