first commit

This commit is contained in:
2026-03-21 14:00:33 +01:00
parent 6de8fb938e
commit 595720a129
3 changed files with 145 additions and 0 deletions

10
example_config.json Normal file
View File

@@ -0,0 +1,10 @@
{
"ip_server":"https://api.ipify.org",
"dns_endpoint":"https://dns.eu.ovhapis.com/nic/update",
"username":"username",
"password":"password",
"domains":[
"example.com"
],
"delay":3600
}

45
readme.md Normal file
View File

@@ -0,0 +1,45 @@
# VYDNS
A simple DynDNS v2 client written in Python, compatible with providers such as OVH DynHost.
## Features
- Periodically checks the public IP address
- Updates DNS records only when the IP changes
- Uses a local cache to avoid unnecessary updates
- No external dependencies except `requests` module
## Usage
Run the script with Python. It will periodically:
- Query a web endpoint that returns the public IP in plain text
- Compare it with the cached IP
- If the IP has not changed, sleep for the configured delay
- If the IP has changed, update the DNS records and refresh the cache
- If no cache exists, create it and perform an initial update
## Configuration
The script relies on a JSON configuration file named `config.json` located in the working directory.
It must contain the following keys:
- `ip_server`: URL of the endpoint used to retrieve the public IP (must return plain text)
- `dns_endpoint`: DynDNS v2 API endpoint of the provider
- `username`: DynDNS account username
- `password`: DynDNS account password
- `domains`: list of domain names to update
- `delay`: interval in seconds between checks
You can find an example configuration file in this repo.
**Warning:** the password is stored in plain text. Changing config file permissions is recommended.
## Supported DynDNS providers
To this day, these DynDNS providers have been found to work well with the script:
- OVH
## License
This script and the provided examples are under the MIT license.

90
vydns.py Normal file
View File

@@ -0,0 +1,90 @@
import requests
import os
import json
import ipaddress
import time
def recreate_cache(ip_server:str):
print("[VYDNS] Obtaining public IP using server '"+ip_server+"'")
ip=""
try:
ip=requests.get(ip_server,timeout=10).text.strip()
ipaddress.ip_address(ip)
except Exception as e:
print("[VYDNS] Error: counldn't obtain IP or IP isn't valid. Exception: "+str(e))
exit()
print("[VYDNS] "+ip)
cache={"ip":ip}
with open("cache.json","w") as f:
json.dump(cache,f)
print("[VYDNS] Succesfully obtained IP.")
return ip
def obtain_ip(ip_server:str):
print("[VYDNS] Obtaining public IP using server '"+ip_server+"'")
ip=""
try:
ip=requests.get(ip_server,timeout=10).text.strip()
ipaddress.ip_address(ip)
except Exception as e:
print("[VYDNS] Error: counldn't obtain IP or IP isn't valid. Exception: "+str(e))
exit()
print("[VYDNS] "+ip)
print("[VYDNS] Succesfully obtained IP.")
return ip
def update_ip(ip:str,dns_endpoint:str,domains:str,username:str,password:str):
print("[VYDNS] Updating "+str(len(domains))+" domains:")
for d in domains:
print("[VYDNS] Updating '"+d+"' :")
params={
"system":"dyndns",
"hostname":d,
"myip":ip
}
r=requests.get(dns_endpoint,params=params,auth=(username,password),timeout=10)
print(r.text)
if "good" in r.text or "nochg" in r.text:
print("[VYDNS] Update OK.")
else:
print("[VYDNS] Update failed.")
conffile={}
if os.path.exists("config.json"):
conffile=json.load(open("config.json","r"))
else:
print("[VYDNS] Error: config file doesn't exist.")
exit()
if ("ip_server" not in conffile) or ("dns_endpoint" not in conffile) or ("username" not in conffile) or ("password" not in conffile) or ("domains" not in conffile) or ("delay" not in conffile):
print("[VYDNS] Error: config file isn't formatted as expected.")
exit()
if (conffile["ip_server"]=="") or (conffile["dns_endpoint"]=="") or (conffile["username"]=="") or (conffile["password"]=="") or (conffile["delay"]<=0):
print("[VYDNS] Error: one of the key is empty or invalid.")
exit()
if (conffile["domains"]==[]):
print("[VYDNS] Error: no domains provided.")
exit()
while True:
obtained_ip=""
if not os.path.exists("cache.json"):
print("[VYDNS] Cache file doesn't exist, recreating it.")
obtained_ip=recreate_cache(conffile["ip_server"])
update_ip(obtained_ip,conffile["dns_endpoint"],conffile["domains"],conffile["username"],conffile["password"])
print("[VYDNS] Sleeping for "+str(conffile["delay"])+" seconds.")
time.sleep(conffile["delay"])
continue
else:
print("[VYDNS] Cache file exist, obtaining current IP for comparaison.")
obtained_ip=obtain_ip(conffile["ip_server"])
with open("cache.json","r") as f:
cachefile=json.load(f)
if cachefile["ip"]==obtained_ip:
print("[VYDNS] According to cache file, IP didn't change.")
print("[VYDNS] Sleeping for "+str(conffile["delay"])+" seconds.")
time.sleep(conffile["delay"])
continue
else:
print("[VYDNS] According to cache file, IP did changed.")
update_ip(obtained_ip,conffile["dns_endpoint"],conffile["domains"],conffile["username"],conffile["password"])
cache={"ip":obtained_ip}
with open("cache.json","w") as f:
json.dump(cache,f)
print("[VYDNS] Sleeping for "+str(conffile["delay"])+" seconds.")
time.sleep(conffile["delay"])
continue