Created
January 30, 2024 11:01
-
-
Save touilleMan/ef9539c72bdf5ecf806af407940ad00c to your computer and use it in GitHub Desktop.
Poll Livebox and refresh OVH DynDNS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3 | |
# Most internet box support DynDNS... but not my Livebox ! | |
# Well it's more complicated than that: only a (very) limited | |
# number of DynDNS services are supported, and OVH is not among | |
# them... After all, why would the biggest French internet provider | |
# support the biggest French hosting service ? (╬ ಠ益ಠ) | |
# | |
# Anyway, this script poll the Livebox to retrieve it current IP address, | |
# then (if it has changed) update the OVH DynDNS service accordingly. | |
import urllib.request | |
from pathlib import Path | |
import re | |
import json | |
from base64 import b64encode | |
BASEDIR = Path(__file__).parent | |
# The last know IP is stored in this file, to avoid updating OVH DynDNS if the IP didn't change | |
CURRENT_IP_FILE = BASEDIR / "current_ip.txt" | |
TARGET_HOSTNAME = "<TODO>" # Fill me ! | |
OVH_DYNDNS_AUTH_USER = "<TODO>" # Fill me ! | |
OVH_DYNDNS_AUTH_PASSWORD = "<TODO>" # Fill me ! | |
LIVEBOX_API_ENDPOINT = "http://192.168.1.1/ws" | |
current_ip = CURRENT_IP_FILE.read_text().strip() | |
assert re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", current_ip) | |
# 1) Retreive current IP from the Livebox | |
req = urllib.request.Request( | |
url=LIVEBOX_API_ENDPOINT, | |
method="POST", | |
headers={ | |
"Content-Type": "application/x-sah-ws-1-call+json", | |
}, | |
data=b'{"service":"NMC","method":"getWANStatus","parameters":{}}' | |
) | |
rep = urllib.request.urlopen(req) | |
assert rep.status == 200 | |
new_ip = json.loads(rep.read().decode("utf8"))['result']['data']['IPAddress'].strip() | |
assert re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", new_ip) | |
if new_ip == current_ip: | |
print("IP didn't change, nothing to update") | |
raise SystemExit(0) | |
print(f"IP has changed: {current_ip} -> {new_ip}") | |
# 2) Update OVH DynDNS with the new IP | |
req = urllib.request.Request( | |
url=f"https://www.ovh.com/nic/update?system=dyndns&hostname={TARGET_HOSTNAME}&myip={new_ip}", | |
method="GET", | |
headers={ | |
"Authorization": "Basic {}".format(b64encode(f"{OVH_DYNDNS_AUTH_USER}:{OVH_DYNDNS_AUTH_PASSWORD}".encode("utf8")).decode()), | |
}, | |
) | |
rep = urllib.request.urlopen(req) | |
assert rep.status == 200 | |
rep_status = rep.read().decode("utf8") | |
if rep_status.startswith("nochg"): | |
print("OVH DynDNS updated, but already using this IP !") | |
elif rep_status.startswith("good"): | |
print("OVH DynDNS updated !") | |
else: | |
raise SystemExit("OVH DynDNS rejected the IP update: {}".format(rep_status)) | |
# 3) Finally update the current IP file | |
CURRENT_IP_FILE.write_text(new_ip) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment