Initial files push for DDNS Updater

This commit is contained in:
root
2026-04-13 09:08:09 +01:00
commit 5f683ca307
3 changed files with 181 additions and 0 deletions

107
ddns.py Executable file
View File

@@ -0,0 +1,107 @@
#!/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()