Last active 1 day ago

mathias.hurler's Avatar mathias.hurler revised this gist 1 day ago. Go to revision

1 file changed, 55 insertions

hetzner-ddns-update.py(file created)

@@ -0,0 +1,55 @@
1 + import requests
2 + import logging
3 + from datetime import datetime
4 + from hcloud import Client
5 + from hcloud.zones.domain import ZoneRecord
6 +
7 + # --- KONFIGURATION ---
8 + TOKEN = "DEIN_HETZNER_API_TOKEN"
9 + DOMAIN = "domain.de"
10 + SUBDOMAINS = ["forms", "api", "cloud"] # Hier einfach erweitern
11 + LOG_FILE = "/home/ddns_update.log"
12 +
13 + # --- LOGGING SETUP ---
14 + logging.basicConfig(
15 + filename=LOG_FILE,
16 + level=logging.INFO,
17 + format='%(asctime)s - %(levelname)s - %(message)s',
18 + datefmt='%Y-%m-%d %H:%M:%S'
19 + )
20 +
21 + def update_ddns():
22 + try:
23 + client = Client(token=TOKEN)
24 +
25 + # 1. Aktuelle öffentliche IP abrufen
26 + try:
27 + current_ip = requests.get('https://api.ipify.org', timeout=10).text.strip()
28 + except Exception as e:
29 + logging.error(f"Konnte öffentliche IP nicht abrufen: {e}")
30 + return
31 +
32 + # 2. Zone laden
33 + zone = client.zones.get(DOMAIN)
34 +
35 + # 3. Alle Subdomains durchgehen
36 + for sub in SUBDOMAINS:
37 + try:
38 + rrset = client.zones.get_rrset(zone, name=sub, type="A")
39 + existing_ip = rrset.records[0].value if rrset.records else None
40 +
41 + if current_ip != existing_ip:
42 + client.zones.set_rrset_records(rrset, records=[ZoneRecord(value=current_ip)])
43 + logging.info(f"UPDATE: {sub}.{DOMAIN} von {existing_ip} auf {current_ip} geändert.")
44 + else:
45 + # Optional: Loggen, dass alles okay ist (kann man auch weglassen, um Log klein zu halten)
46 + logging.info(f"OK: {sub}.{DOMAIN} ist aktuell ({current_ip}).")
47 +
48 + except Exception as e:
49 + logging.error(f"Fehler bei Subdomain {sub}: {e}")
50 +
51 + except Exception as e:
52 + logging.critical(f"Kritischer Fehler im Hauptprozess: {e}")
53 +
54 + if __name__ == "__main__":
55 + update_ddns()
Newer Older