v1
This commit is contained in:
15
dockerfile
Normal file
15
dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Abhängigkeiten installieren
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Skript kopieren
|
||||
COPY main.py .
|
||||
|
||||
# Environment Variable für unbuffered Output (wichtig für Docker Logs)
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
CMD ["python", "main.py"]
|
||||
24
dyndns.yaml
Normal file
24
dyndns.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
ovh-dyndns:
|
||||
image: deinuser/ovh-dyndns:latest
|
||||
deploy:
|
||||
mode: replicated
|
||||
replicas: 1
|
||||
environment:
|
||||
- OVH_APPLICATION_KEY=a5a8c4d9ca922385
|
||||
- OVH_APPLICATION_SECRET=00cae21017265da8a6d0d6df0b6b2dfb
|
||||
- OVH_CONSUMER_KEY=181952cb55cc3ed2d1e39d45b96263a6
|
||||
|
||||
# Die Hauptdomain (Zone)
|
||||
- DOMAIN=alehn.de
|
||||
|
||||
# HIER DIE LISTE EINTRAGEN:
|
||||
# "www" -> www.deinedomain.de
|
||||
# "vpn" -> vpn.deinedomain.de
|
||||
# "@" -> deinedomain.de (ohne www, die Hauptdomain selbst)
|
||||
- SUBDOMAINS= nextcloud, bitwarden, portainer, traefik, gittea
|
||||
|
||||
# Check alle 5 Minuten
|
||||
- INTERVAL=300
|
||||
82
main.py
Normal file
82
main.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import os
|
||||
import time
|
||||
import ovh
|
||||
import requests
|
||||
from datetime import datetime
|
||||
|
||||
# --- Konfiguration ---
|
||||
AK = os.getenv('OVH_APPLICATION_KEY')
|
||||
AS = os.getenv('OVH_APPLICATION_SECRET')
|
||||
CK = os.getenv('OVH_CONSUMER_KEY')
|
||||
DOMAIN = os.getenv('DOMAIN') # Die Hauptdomain, z.B. "meine-domain.de"
|
||||
INTERVAL = int(os.getenv('INTERVAL', 300))
|
||||
|
||||
# Subdomains auslesen und Liste erstellen
|
||||
# Beispiel Input: "www, vpn, cloud, @"
|
||||
raw_subs = os.getenv('SUBDOMAINS', '')
|
||||
SUBDOMAINS = [s.strip() for s in raw_subs.split(',') if s.strip()]
|
||||
|
||||
def log(message):
|
||||
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {message}", flush=True)
|
||||
|
||||
def get_public_ip():
|
||||
try:
|
||||
return requests.get('https://api.ipify.org', timeout=10).text
|
||||
except Exception as e:
|
||||
log(f"Fehler beim Abrufen der IP: {e}")
|
||||
return None
|
||||
|
||||
def update_ovh_dns(current_ip):
|
||||
client = ovh.Client(endpoint='ovh-eu', application_key=AK, application_secret=AS, consumer_key=CK)
|
||||
|
||||
if not SUBDOMAINS:
|
||||
log("WARNUNG: Keine Subdomains in der Liste 'SUBDOMAINS' gefunden.")
|
||||
return
|
||||
|
||||
for sub in SUBDOMAINS:
|
||||
# OVH Logik: Leerer String = Root Domain. Wir nutzen '@' als Platzhalter für User-Freundlichkeit
|
||||
sub_for_api = '' if sub == '@' else sub
|
||||
fqdn = f"{sub}.{DOMAIN}" if sub != '@' else DOMAIN
|
||||
|
||||
try:
|
||||
# 1. Record ID suchen
|
||||
records = client.get(f'/domain/zone/{DOMAIN}/record',
|
||||
fieldType='A',
|
||||
subDomain=sub_for_api)
|
||||
|
||||
if not records:
|
||||
log(f"Übersprungen: Kein A-Record für '{fqdn}' gefunden.")
|
||||
continue
|
||||
|
||||
for record_id in records:
|
||||
# 2. Details prüfen
|
||||
record_details = client.get(f'/domain/zone/{DOMAIN}/record/{record_id}')
|
||||
|
||||
if record_details['target'] == current_ip:
|
||||
log(f"OK: {fqdn} ist aktuell ({current_ip}).")
|
||||
else:
|
||||
# 3. Update senden
|
||||
client.put(f'/domain/zone/{DOMAIN}/record/{record_id}', target=current_ip)
|
||||
log(f"UPDATE: {fqdn} wurde auf {current_ip} gesetzt.")
|
||||
|
||||
# Refresh anstoßen (nur einmal pro Loop eigentlich nötig, aber sicher ist sicher)
|
||||
client.post(f'/domain/zone/{DOMAIN}/refresh')
|
||||
|
||||
except Exception as e:
|
||||
log(f"Fehler bei {fqdn}: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
log("OVH DynDNS Updater gestartet...")
|
||||
log(f"Domain: {DOMAIN}")
|
||||
log(f"Überwachte Subdomains: {SUBDOMAINS}")
|
||||
|
||||
if not all([AK, AS, CK, DOMAIN]):
|
||||
log("CRITICAL: API Keys oder Domain fehlen.")
|
||||
exit(1)
|
||||
|
||||
while True:
|
||||
public_ip = get_public_ip()
|
||||
if public_ip:
|
||||
update_ovh_dns(public_ip)
|
||||
|
||||
time.sleep(INTERVAL)
|
||||
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
ovh
|
||||
requests
|
||||
Reference in New Issue
Block a user