Tuxvador's Blog
Présentation de WorkItOut — Trouve ton partenaire de sport Rapports quotidiens automatisés CrowdSec par e-mail Gestion programmatique du DNS avec l'API IONOS Premiers pas avec Proxmox VE pour votre laboratoire maison Mon Homelab Proxmox VE : Aperçu de l'infrastructure
EN

Gestion programmatique du DNS avec l'API IONOS


Si vous gérez plusieurs domaines et sous-domaines pour un homelab, modifier les enregistrements DNS via une interface web devient vite fastidieux. L’API DNS IONOS (anciennement 1&1) vous permet de gérer tous vos enregistrements par programmation — lister les zones, ajouter des enregistrements A/AAAA/CNAME/MX/TXT, et nettoyer les anciennes entrées.

Cet article couvre les mécanismes de l’API basés sur ma propre configuration homelab, où je gère le DNS pour trois domaines répartis sur une douzaine de sous-domaines.

Identifiants API

Les clés API IONOS se composent de deux parties :

  • Un préfixe public (identifiant de type UUID)
  • Une clé secrète (longue chaîne aléatoire)

Elles sont générées depuis le portail client IONOS sous Accès API. Stockez-les de manière sécurisée — elles donnent un accès complet à la gestion DNS.

Authentification

L’API utilise l’en-tête d’authentification X-API-Key. La valeur est le préfixe et le secret joints par un point :

PREFIX="your-public-prefix"
SECRET="***"
AUTH="X-API-Key: ${PREFIX}.${SECRET}"

curl -s "https://api.hosting.ionos.com/dns/v1/zones" \
  -H "$AUTH" -H "Accept: application/json"

L’authentification HTTP Basic (-u prefix:secret) retourne « Missing or invalid credentials » — l’en-tête X-API-Key est la méthode correcte.

Lister les Zones DNS

curl -s "https://api.hosting.ionos.com/dns/v1/zones" \
  -H "$AUTH" | jq

Réponse :

[
  {
    "name": "tuxvador.fr",
    "id": "72f9874f-26e3-11ec-bda4-0a5864441f49",
    "type": "NATIVE"
  },
  ...
]

Chaque zone possède un ID unique utilisé pour les opérations ultérieures. Le champ type indique si le DNS est géré par IONOS (NATIVE) ou externe (MASTER/SLAVE).

Lire les Enregistrements d’une Zone

ZONE_ID="72f9874f-..."
curl -s "https://api.hosting.ionos.com/dns/v1/zones/$ZONE_ID" \
  -H "$AUTH" | jq '.records[] | {name, type, content, ttl}'

Les enregistrements incluent tous les champs standard : name, rootName, type, content, ttl, disabled, et un id unique pour chaque enregistrement.

Ajouter des Enregistrements via PUT (Remplacement Complet de Zone)

La façon la plus simple d’ajouter des enregistrements est de lire la zone actuelle, modifier la liste des enregistrements, puis renvoyer la zone entière avec PUT :

import urllib.request, json

BASE = f"https://api.hosting.ionos.com/dns/v1/zones/{ZONE_ID}"
HEADERS = {"X-API-Key": f"{PREFIX}.{SECRET}", "Content-Type": "application/json"}

# Lire les enregistrements actuels
req = urllib.request.Request(BASE, headers=HEADERS)
zone = json.loads(urllib.request.urlopen(req).read())

# Ajouter un nouvel enregistrement
zone["records"].append({
    "name": "api-test.tuxvador.fr",
    "type": "A",
    "content": "192.168.1.1",
    "ttl": 60
})

# PUT la zone mise à jour
data = json.dumps(zone).encode()
req = urllib.request.Request(BASE, data=data, method="PUT", headers=HEADERS)
resp = urllib.request.urlopen(req)

Important : Le PUT remplace TOUS les enregistrements. Lisez toujours la zone d’abord, modifiez le tableau, puis réécrivez-la. Si vous omettez des enregistrements existants, ils sont supprimés.

Supprimer des Enregistrements Individuels

Pour des suppressions ciblées, utilisez le point de terminaison DELETE pour un enregistrement spécifique :

ZONE_ID = "72f9874f-..."
RECORD_ID = "ad432f9a-b097-..."  # issu d'une réponse GET de zone

url = f"https://api.hosting.ionos.com/dns/v1/zones/{ZONE_ID}/records/{RECORD_ID}"
req = urllib.request.Request(url, method="DELETE", headers=HEADERS)
resp = urllib.request.urlopen(req)  # HTTP 200 = succès

C’est plus propre que PUT pour supprimer des enregistrements spécifiques sans toucher au reste.

Limitations

La clé API utilisée ici a uniquement les permissions de gestion des zones DNS. La création de nouveaux enregistrements de domaine (achat de nouveaux noms de domaine) retourne UNAUTHORIZED — cela nécessite l’API Domaines ou un jeton élevé.

Opérations disponibles :

  • ✅ Lister toutes les zones
  • ✅ Lire tous les enregistrements d’une zone
  • ✅ Ajouter des enregistrements (via PUT de zone)
  • ✅ Supprimer des enregistrements individuels
  • ❌ Créer de nouvelles zones DNS
  • ❌ Enregistrer de nouveaux domaines

Cas d’Usage : Nettoyer d’Anciens Services

Dans ma configuration, j’avais un service Honcho fonctionnant sur un sous-domaine avec 11 enregistrements DNS (A, AAAA, MX, TXT, CNAME, autodiscover). Après avoir décommissionné le service, j’ai supprimé tous les enregistrements par programmation :

for honcho_id in record_ids:
    url = f"https://api.hosting.ionos.com/dns/v1/zones/{Z}/records/{honcho_id}"
    urllib.request.Request(url, method="DELETE", headers=HEADERS)

C’est beaucoup plus rapide que de cliquer dans une interface web pour une douzaine d’enregistrements.

Notes de Sécurité

  • Les clés API ne peuvent pas être limitées à des domaines spécifiques — elles ont un accès complet à toutes vos zones
  • Stockez la clé dans votre environnement (ex. ~/.hermes/.env) plutôt que de l’écrire en dur dans le code
  • Les identifiants sont réutilisables entre sessions — définissez IONOS_API_PREFIX et IONOS_API_SECRET dans votre environnement
  • Les modifications DNS prennent effet immédiatement via le backend de l’API

Script de Flux de Travail Complet

Voici un script complet pour lister tous les enregistrements dans toutes vos zones :

import urllib.request, json

PREFIX = "your-prefix"
SECRET="***"
HEADERS = {"X-API-Key": f"{PREFIX}.{SECRET}"}

# Lister toutes les zones
req = urllib.request.Request(
    "https://api.hosting.ionos.com/dns/v1/zones", headers=HEADERS)
zones = json.loads(urllib.request.urlopen(req).read())

for z in zones:
    req = urllib.request.Request(
        f"https://api.hosting.ionos.com/dns/v1/zones/{z['id']}", headers=HEADERS)
    zone_data = json.loads(urllib.request.urlopen(req).read())
    print(f"\n## {z['name']}")
    for r in zone_data.get("records", []):
        if r["type"] not in ("NS", "SOA"):
            print(f"  {r['name']:40s} {r['type']:6s} {r['content']:40s}")

L’API DNS IONOS est bien adaptée à l’automatisation de homelab — authentification simple, design RESTful et effet immédiat. Combinée avec CI/CD ou une tâche cron, vous pouvez gérer le DNS dynamique, la découverte de services et la documentation d’infrastructure entièrement via du code.