#!/usr/bin/env python3 import requests import sys from datetime import datetime # ----------------------------- # CONFIG - only edit this: API_TOKEN = "HLNmBZ-4fyCSvR6BErdFtch4jQj3GACePD4yD0xs" DOMAINS = [ "snieznykoczkodan.com", # root domain "proxy.snieznykoczkodan.com", # Nginx Proxy Manager .102 "proxmox.snieznykoczkodan.com", # Proxmox GUI .5 "nas.snieznykoczkodan.com", # Synology - rafnasbox .3 "jellyfin.snieznykoczkodan.com", # Jellyfin .104 "seer.snieznykoczkodan.com", # jellyseer .105 "prowlarr.snieznykoczkodan.com", # porwlarr .105 9696 "radarr.snieznykoczkodan.com", # radarr .105 7878 "sonarr.snieznykoczkodan.com", # sonarr .105 8989 "torrent.snieznykoczkodan.com", # qbitorrent .106 "grafana.snieznykoczkodan.com", # grafana .108 "git.snieznykoczkodan.com" # gittea .111 3000 ] TTL = 120 # 2 minutes PROXIED = False # True = Cloudflare proxy (orange cloud), False = DNS only # ----------------------------- BASE_URL = "https://api.cloudflare.com/client/v4" HEADERS = { "Authorization": f"Bearer {API_TOKEN}", "Content-Type": "application/json" } def log(msg): now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") print(f"[{now}] {msg}") def get_public_ip(): try: return requests.get("https://api.ipify.org", timeout=10).text.strip() except Exception as e: log(f"❌ Failed to get public IP: {e}") sys.exit(1) def get_zone_id(domain): try: # extract the root domain (last two parts) parts = domain.split('.') root_domain = '.'.join(parts[-2:]) r = requests.get(f"{BASE_URL}/zones?name={root_domain}", headers=HEADERS) r.raise_for_status() zones = r.json()["result"] if not zones: log(f"❌ No zone found for {root_domain}") sys.exit(1) return zones[0]["id"] except Exception as e: log(f"❌ Error fetching Zone ID for {domain}: {e}") sys.exit(1) def get_record_id(zone_id, domain): try: r = requests.get(f"{BASE_URL}/zones/{zone_id}/dns_records?type=A&name={domain}", headers=HEADERS) r.raise_for_status() records = r.json()["result"] if not records: log(f"❌ No A record found for {domain}") sys.exit(1) return records[0]["id"], records[0]["content"] except Exception as e: log(f"❌ Error fetching DNS record for {domain}: {e}") sys.exit(1) def update_dns_record(zone_id, record_id, domain, ip): data = { "type": "A", "name": domain, "content": ip, "ttl": TTL, "proxied": PROXIED } try: r = requests.put(f"{BASE_URL}/zones/{zone_id}/dns_records/{record_id}", headers=HEADERS, json=data) r.raise_for_status() return r.json().get("success", False) except Exception as e: log(f"❌ Failed to update DNS record for {domain}: {e}") return False def main(): ip = get_public_ip() log(f"🌍 Current public IP: {ip}") for domain in DOMAINS: zone_id = get_zone_id(domain) record_id, current_ip = get_record_id(zone_id, domain) if current_ip == ip: log(f"✅ {domain} already up to date") else: log(f"🔄 Updating {domain} from {current_ip} → {ip}") if update_dns_record(zone_id, record_id, domain, ip): log(f"✅ {domain} updated successfully") else: log(f"❌ {domain} update failed") if __name__ == "__main__": main()