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