Skip to content

Instantly share code, notes, and snippets.

@touilleMan
Created January 30, 2024 11:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save touilleMan/ef9539c72bdf5ecf806af407940ad00c to your computer and use it in GitHub Desktop.
Save touilleMan/ef9539c72bdf5ecf806af407940ad00c to your computer and use it in GitHub Desktop.
Poll Livebox and refresh OVH DynDNS
#! /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