Merge the Hetzner DNS migration note
commit
acc0ac0082
|
|
@ -0,0 +1,84 @@
|
|||
# Hetzner-DNS: die alte API ist abgeschaltet
|
||||
|
||||
**Gemessen am 31. Juli 2026, am Live-Server und von außen.**
|
||||
|
||||
```
|
||||
https://dns.hetzner.com/api/v1/zones → 301 → https://console.hetzner.com/ (HTML)
|
||||
https://api.hetzner.cloud/v1/zones → 401 ohne Token, 200 mit dem Token des Betreibers
|
||||
```
|
||||
|
||||
Hetzner hat die DNS-Verwaltung am 7. Oktober 2025 in die Cloud-Konsole verlegt.
|
||||
Die alte DNS-Konsole ging am **20. Mai 2026** in den Nur-Lese-Betrieb; seither
|
||||
leitet der alte Endpunkt auf die Weboberfläche um. **Alte Token und Zonen-IDs
|
||||
sind mit der neuen Konsole nicht kompatibel** und wurden nicht übernommen.
|
||||
|
||||
## Was dadurch kaputt ist
|
||||
|
||||
- `App\Services\Dns\DnsTokenCheck` — meldet `zone_not_found`, obwohl Token und
|
||||
Zone in Ordnung sind. Seit v1.3.77 meldet es immerhin ehrlich
|
||||
`zone_list_unreadable` mit dem Anfang der HTML-Antwort.
|
||||
- `App\Services\Dns\HttpHetznerDnsClient` — **das ist das Teure.** Er legt den
|
||||
A-Eintrag jeder Kundeninstanz an. Solange er auf den alten Endpunkt zeigt,
|
||||
stirbt jede Bereitstellung in `ConfigureDnsAndTls` — nachdem der Kunde bezahlt
|
||||
hat. Genau der Satz steht als Begründung auf der Bereitschaftsseite.
|
||||
- Der Token des Betreibers ist bereits ein Cloud-Token und antwortet mit 200.
|
||||
Es fehlt **nur** der Code.
|
||||
|
||||
## Die neue Schnittstelle
|
||||
|
||||
Aus `https://docs.hetzner.cloud/cloud.spec.json` gezogen, nicht geraten.
|
||||
|
||||
**Anmeldung:** `Authorization: Bearer <token>` — nicht mehr `Auth-API-Token`.
|
||||
|
||||
**Basis:** `https://api.hetzner.cloud/v1`
|
||||
|
||||
| Zweck | Aufruf |
|
||||
|---|---|
|
||||
| Zonen auflisten | `GET /zones` → `{"zones":[{id,name,…}], "meta":{…}}` |
|
||||
| Eine Zone direkt | `GET /zones/{id_or_name}` — **der Name geht direkt**, kein Suchen mehr |
|
||||
| Eintragssatz anlegen | `POST /zones/{zone}/rrsets` |
|
||||
| Eintragssatz ersetzen | `POST /zones/{zone}/rrsets/{name}/{type}/actions/set_records` |
|
||||
| Eintragssatz löschen | `DELETE /zones/{zone}/rrsets/{name}/{type}` |
|
||||
|
||||
**Das Modell hat sich geändert:** keine einzelnen Records mehr, sondern
|
||||
**RRSets**, adressiert über `{name}/{typ}`. Ein RRSet trägt mehrere Werte.
|
||||
`set_records` ersetzt den ganzen Satz — damit wird das Schreiben idempotent, was
|
||||
der alte Client mit Suchen-und-Aktualisieren nachbauen musste.
|
||||
|
||||
Rumpf beim Anlegen, Pflichtfelder `name`, `type`, `records`:
|
||||
|
||||
```json
|
||||
{ "name": "kunde", "type": "A", "ttl": 60,
|
||||
"records": [{"value": "203.0.113.10"}] }
|
||||
```
|
||||
|
||||
**Zwei Fallen im `name`:**
|
||||
|
||||
1. Er darf **nicht** auf den Zonennamen enden. `kunde`, nicht
|
||||
`kunde.clupilot.cloud` — der alte Client hat den vollen Namen geschickt.
|
||||
2. Für die Zonenwurzel ist es `@`, und er muss klein geschrieben sein.
|
||||
|
||||
`PUT /zones/{zone}/rrsets/{name}/{type}` ist **nicht** das Schreiben der Werte —
|
||||
es setzt nur `labels`. Wer dort die Records erwartet, schreibt ins Leere.
|
||||
|
||||
## Was zu tun ist
|
||||
|
||||
1. `HttpHetznerDnsClient` auf Basis, Kopfzeile und RRSets umstellen. Der
|
||||
Zonen-Lookup entfällt: der Name geht direkt in den Pfad.
|
||||
2. `DnsTokenCheck` dito. Die Schreibprobe bleibt der Kern der Prüfung — ein
|
||||
lesender Token sieht sonst genauso aus wie ein schreibender, und der
|
||||
Unterschied fällt erst auf, wenn ein Kunde bezahlt hat.
|
||||
3. `FakeHetznerDnsClient` und die Tests nachziehen.
|
||||
4. Den Namen ohne Zonensuffix bilden — Falle 1 oben. Ein Test, der genau das
|
||||
festhält, ist billiger als der erste Kunde, dessen Adresse
|
||||
`kunde.clupilot.cloud.clupilot.cloud` heißt.
|
||||
|
||||
## Wieso das so lange gesucht wurde
|
||||
|
||||
Die Prüfung stufte nur 401 und 403 als abgelehnt ein und las danach den Rumpf.
|
||||
Jede andere Antwort — hier eine 301 auf eine HTML-Seite — hatte kein `zones`,
|
||||
und `?? []` machte daraus „keine Zone in diesem Konto". Eine Aussage über ein
|
||||
fremdes Hetzner-Konto, hergeleitet aus einer Antwort, die niemand angesehen hat.
|
||||
v1.3.76 und v1.3.77 haben das behoben; die Meldung zeigt jetzt Status und die
|
||||
ersten Zeichen der Antwort. Ohne diese zwei Schritte wäre die Ursache weiter im
|
||||
Dunkeln.
|
||||
Loading…
Reference in New Issue