← Back to docs

DNS API

Language: SV | EN | SV

DNS API

Översikt

DNS-API:et exponeras under /api/dns.

Använd det när du vill:

  • lista zoner som den aktuella användaren/tokenen får se
  • läsa zondata via cache-först eller AXFR-baserade flöden
  • söka i cachade zonrader utan att trigga en ny zontransfer
  • lägga till, radera, uppdatera eller bulk-skriva vanliga DNS-poster

Base URL: https://tools.tornevall.net/api/dns


Snabbstart

Webbläsare / webbapp

Använd samma inloggade session som Tools webbgränssnitt.

const response = await fetch('https://tools.tornevall.net/api/dns/zones', {
  method: 'GET',
  credentials: 'include'
});
const data = await response.json();

API-nyckel

Stödda transportsätt:

  • Authorization: Bearer <token>
  • X-API-Key: <token>
  • ?api_key=<token>

Exempel:

curl -s "https://tools.tornevall.net/api/dns/zones" \
  -H "Authorization: Bearer YOUR_API_KEY"

Vilka auth-lägen stöds?

Nuvarande /api/dns/*-controller accepterar:

  • autentiserad webbsession
  • API-nyckel (personlig eller global)
  • IP-whitelist-fallback när det är aktiverat server-side

Typiska svar från list zones kan innehålla:

  • access_type="authenticated"
  • access_type="api_key_global"
  • access_type="ip_whitelist"

Autentisering och åtkomst

Zonlista

GET /api/dns/zones är inte längre admin-only.

Nuvarande beteende:

  • admins ser alla zoner
  • vanliga användare ser bara zoner som delegerats via dns_zone_permissions
  • globala API-nycklar kan returnera alla zoner utan bunden användare
  • IP-whitelistade klienter kan läsa även utan vanlig användarsession

Zonläsningar

För GET /api/dns/zones/{zone} och relaterade cache-/sökanrop gäller:

  • admins kan läsa alla zoner
  • icke-admin måste ha en matchande delegerad zonrättighet
  • oautentiserade klienter måste matcha en server-side IP-whitelistregel

Vanliga auth-fel

{
  "ok": false,
  "reason": "unauthenticated"
}
{
  "ok": false,
  "reason": "forbidden"
}

Vanliga svarsfält

Dessa fält förekommer ofta i zonläsningssvar:

Fält Betydelse
ok Success-flagga
zone Begärd zonnamn
zoneData Paginerade postrader
record_count Totalt antal matchande rader före pagination
page Aktuell sida
per_page Aktuell sidstorlek
has_more Om fler sidor finns
display_signature Hash för synliga rader + pagineringsläge
cache_ttl_seconds Effektiv cache-TTL
cache_policy Aktuell invalidate/clear-policy för zonen

Typisk rad i zoneData:

{
  "name": "www.tornevall.net",
  "ttl": 3600,
  "class": "IN",
  "type": "A",
  "rdata": "192.168.1.100"
}

Läs-endpoints

1) Lista zoner

Endpoint: GET /api/dns/zones

Exempel:

curl -s "https://tools.tornevall.net/api/dns/zones" \
  -H "Authorization: Bearer YOUR_API_KEY"

Exempelsvar:

{
  "ok": true,
  "count": 2,
  "zones": [
    {
      "zone": "tornevall.net",
      "file": "master/tornevall/tornevall.net",
      "key": "tornevall.net"
    },
    {
      "zone": "10.10.10.in-addr.arpa",
      "file": "master/reverse/10.10.10.in-addr.arpa",
      "key": "10.10.10.in-addr.arpa"
    }
  ],
  "is_admin": false,
  "access_type": "authenticated"
}

2) Hämta en zon

Endpoint: GET /api/dns/zones/{zone}

Defaultbeteendet är cache-först.

Användbara query-parametrar:

  • method=cache - defaultflöde
  • method=axfr - tvinga AXFR-väg
  • method=file - läs från lokal zonfil
  • page=<n> - sidnummer
  • limit=<n> - sidstorlek

Exempel:

curl -s "https://tools.tornevall.net/api/dns/zones/tornevall.net?method=cache&page=1&limit=50" \
  -H "Authorization: Bearer YOUR_API_KEY"

Exempelsvar:

{
  "ok": true,
  "zone": "tornevall.net",
  "method": "CACHE",
  "zoneData": [
    {
      "name": "tornevall.net",
      "ttl": 3600,
      "class": "IN",
      "type": "NS",
      "rdata": "ns1.tornevall.net."
    }
  ],
  "record_count": 120,
  "page": 1,
  "per_page": 50,
  "has_more": true,
  "display_signature": "7f0d...",
  "cached_at": "2026-04-24T08:15:00+00:00",
  "cache_age": 12,
  "cache_ttl_seconds": 300,
  "cache_policy": {
    "invalidate_enabled": false,
    "invalidate_interval_seconds": 259200,
    "last_invalidated_at": null,
    "protect_from_clear": false
  }
}

3) Kontrollera cacheläge

Endpoint: GET /api/dns/zones/{zone}/cache

Det här är cache-först-hjälpendpointen för DNS-editorn.

Nuvarande source-värden:

  • from_database
  • from_database_stale
  • needs_axfr

Exempel på stale/fresh-cache-svar:

{
  "ok": true,
  "source": "from_database_stale",
  "zone": "tornevall.net",
  "zoneData": [],
  "record_count": 0,
  "page": 1,
  "per_page": 50,
  "has_more": false,
  "display_signature": "abc123",
  "cached_at": "2026-04-24T07:55:00+00:00",
  "cache_age": 1240,
  "cache_is_stale": true,
  "cache_ttl_seconds": 300,
  "cache_policy": {
    "invalidate_enabled": false,
    "invalidate_interval_seconds": 259200,
    "last_invalidated_at": null,
    "protect_from_clear": false
  }
}

Exempel på cache miss:

{
  "ok": true,
  "source": "needs_axfr",
  "zone": "tornevall.net",
  "message": "Cache miss or expired, AXFR required",
  "cache_ttl_seconds": 300,
  "cache_policy": {
    "invalidate_enabled": false,
    "invalidate_interval_seconds": 259200,
    "last_invalidated_at": null,
    "protect_from_clear": false
  }
}

4) Tvinga AXFR-väg

Endpoint: GET /api/dns/zones/{zone}/axfr

Använd när du uttryckligen vill ha transfer-baserad läsning eftersom journaluppdateringar kan vara nyare än den lokala filvyn.

5) Sök i cachade zonrader

Endpoint: GET /api/dns/zones/{zone}/search?q=...

Viktigt beteende:

  • söker endast i cache
  • triggar aldrig AXFR själv
  • kan returnera from_database_stale när bara stale cache finns
  • stöder exakt IP, CIDR och vanlig textsökning

Exempel:

curl -s "https://tools.tornevall.net/api/dns/zones/dnsbl.tornevall.org/search?q=203.0.113.4" \
  -H "Authorization: Bearer YOUR_API_KEY"

Exempelsvar:

{
  "ok": true,
  "zone": "dnsbl.tornevall.org",
  "source": "from_database",
  "cache_age": 31,
  "cache_is_stale": false,
  "query": "203.0.113.4",
  "search_mode": "ip",
  "zoneData": [],
  "record_count": 0,
  "page": 1,
  "per_page": 50,
  "has_more": false
}

6) Töm cache för en zon

Endpoint: POST /api/dns/zones/{zone}/cache/clear

Den här endpointen är policy-styrd.

Den kan misslyckas med:

  • cache_invalidation_disabled
  • cache_clear_protected
  • forbidden
  • unauthenticated

Exempel på lyckat svar:

{
  "ok": true,
  "zone": "tornevall.net",
  "message": "Cache cleared",
  "cache_policy": {
    "invalidate_enabled": true,
    "invalidate_interval_seconds": 259200,
    "last_invalidated_at": null,
    "protect_from_clear": false
  }
}

Write-endpoints

Aktiva vanliga DNS-write-endpoints är:

  • POST /api/dns/records/add
  • POST /api/dns/records/delete
  • POST /api/dns/records/update
  • POST /api/dns/records/bulk

ACME-hjälpendpoints

DNS-API:t exponerar nu också smala ACME-hjälpare under samma /api/dns-authmodell:

  • POST /api/dns/acme/present
  • POST /api/dns/acme/cleanup
  • POST /api/dns/acme/cleanup-stale

Dessa endpoints är tänkta för DNS-01-baserade consoleflöden och framtida certifikatflöden inne i Tools.

De normaliserar domänen till ett enda owner-namn (_acme-challenge.<domän>), skriver eller raderar TXT-rader via den vanliga DNS-update-servicen och håller den radbaserade zoncachen synkad.

För manuell server-side-städning finns samma stale-cleanup-logik också som Artisan-kommando via php artisan dns:acme:cleanup-stale <domän>.

Lägg till ett challenge-värde

curl -s "https://tools.tornevall.net/api/dns/acme/present" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com",
    "challenge": "demo-acme-value",
    "ttl": 60
  }'

Ta bort ett exakt challenge-värde

curl -s "https://tools.tornevall.net/api/dns/acme/cleanup" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com",
    "challenge": "demo-acme-value"
  }'

Rensa gamla challenge-värden men behåll de aktiva

Använd detta när gamla _acme-challenge-TXT-rader har samlats och du vill städa dem explicit i stället för att enbart lita på exact-cleanup-hooken.

curl -s "https://tools.tornevall.net/api/dns/acme/cleanup-stale" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com",
    "keep_challenges": ["demo-acme-value"],
    "dry_run": false,
    "refresh_zone_cache": true
  }'

Typiska fält i stale-cleanup-svaret:

  • owner
  • zone
  • dry_run
  • removed[]
  • removed_count
  • kept[]
  • errors[]

Lägg till en post

curl -s "https://tools.tornevall.net/api/dns/records/add" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "test.example.com",
    "type": "A",
    "target": "192.0.2.20",
    "ttl": 300
  }'

Radera en post

target är obligatoriskt så att API:t inte råkar ta bort hela RRset:et.

curl -s "https://tools.tornevall.net/api/dns/records/delete" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "test.example.com",
    "type": "A",
    "target": "192.0.2.20"
  }'

Uppdatera en post

old_target är valfritt i nuvarande controller, men bör skickas med när du verkligen ersätter en befintlig post.

curl -s "https://tools.tornevall.net/api/dns/records/update" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "test.example.com",
    "type": "A",
    "old_target": "192.0.2.20",
    "new_target": "192.0.2.21",
    "ttl": 300
  }'

Bulk-write

Nuvarande gränser för vanlig DNS-bulk:

  • operations krävs
  • minst 1 rad
  • högst 100 rader
  • varje rad måste innehålla action, domain, type och target

Exempel:

{
  "operations": [
    {
      "action": "ADD",
      "domain": "one.example.com",
      "type": "A",
      "target": "192.0.2.30",
      "ttl": 300
    },
    {
      "action": "DELETE",
      "domain": "two.example.com",
      "type": "A",
      "target": "192.0.2.31"
    }
  ]
}

Typiskt write-svar

{
  "ok": true,
  "message": "DNS update completed successfully.",
  "results": [],
  "operation_count": 2
}

Cachebeteende att känna till

Radbaserad cache-synk

DNS-cachen är nu radbaserad.

Write-anrop använder inte längre full-zone-invalidate som normalläge.

I stället synkar lyckade add, delete, update och bulk de matchande cacheraderna efter att uppdateringen mot master DNS har lyckats.

Stale cache som fallback

GET /api/dns/zones/{zone}/cache och cachade sökningar kan returnera source="from_database_stale".

Det är avsiktligt: UI:t kan rendera senaste kända sidan direkt medan en senare AXFR-körning uppdaterar i bakgrunden.

Display signature

display_signature är additiv metadata för cache-först-gränssnitt.

Använd den för att avgöra om en avslutad AXFR faktiskt förändrade den synliga sidan innan tabellen ritas om.


JavaScript-exempel

const apiBase = 'https://tools.tornevall.net/api/dns';

async function loadZone(zoneName) {
  const response = await fetch(`${apiBase}/zones/${zoneName}/cache?page=1&limit=50`, {
    method: 'GET',
    credentials: 'include'
  });

  const data = await response.json();

  if (!data.ok) {
    throw new Error(data.reason || 'DNS request failed');
  }

  if (data.source === 'needs_axfr') {
    const axfrResponse = await fetch(`${apiBase}/zones/${zoneName}/axfr?page=1&limit=50`, {
      method: 'GET',
      credentials: 'include'
    });
    return axfrResponse.json();
  }

  return data;
}

Felguide

Reason Typisk status Betydelse
unauthenticated 401 Ingen accepterad session, API-nyckel eller IP-whitelist-access
forbidden 403 Klienten är autentiserad men får inte läsa just den zonen
required_paths_missing_or_unreadable 404 Serverns DNS zone/key-sökvägar är inte läsbara
missing_query 422 Sök-endpointen kallades utan q
cache_unavailable 409 Sökning begärdes innan någon cache alls fanns
cache_invalidation_disabled 403 Manuell clear blockeras av zonens policy
cache_clear_protected 403 Full cache clear är spärrad för zonen
validation_failed 400 Write-payloaden klarade inte valideringen

Relaterad dokumentation


Support

Om en integration beter sig oväntat, kontrollera detta först:

  1. Anropar du verkligen /api/dns/... och inte en äldre icke-API-sökväg?
  2. Har användaren/tokenet faktiskt delegerad access till zonen?
  3. Förväntar du dig färsk AXFR-data när du egentligen läser cache?
  4. Är en manuell cache clear blockerad av zonens cache_policy?

Senast uppdaterad: 2026-04-24