Skip to content

Instantly share code, notes, and snippets.

@H3wastooshort
Last active March 20, 2025 16:01
Show Gist options
  • Save H3wastooshort/c46277d13a9c9d6b380ee3ce3ca7ecde to your computer and use it in GitHub Desktop.
Save H3wastooshort/c46277d13a9c9d6b380ee3ce3ca7ecde to your computer and use it in GitHub Desktop.
script for updating DNS records dynamically via RFC 2136
from json import load
from sys import argv
import subprocess
from time import sleep, monotonic
with open(argv[1],"r") as file:
config=load(file)
def send_nsupdate(ip,domain,keyfile,server,zone,ttl=60):
cmd=f"""server {server}
zone {zone}
update delete {domain} AAAA
send
update add {domain} {ttl} AAAA {ip[1]}
send
update delete {domain} A
send
update add {domain} {ttl} A {ip[0]}
send
quit"""
#print(cmd)
sp = subprocess.run(['nsupdate', '-k', keyfile], input=cmd, text=True)
if sp.returncode != 0:
print("ERROR, return code",sp.returncode)
else:
print(domain,"OK")
def update_ip(conf,ip):
for host in config["hosts"]:
send_nsupdate(ip,host["domain"],host["keyfile"],host["server"],host["zone"],host["ttl"])
def get_ip(conf):
v4=subprocess.check_output(config["ipv4_cmd"]).decode('utf-8').strip()
v6=subprocess.check_output(config["ipv6_cmd"]).decode('utf-8').strip()
return (v4,v6)
prev_ip=(None,None)
last_update_time=0
while True:
ip=get_ip(config)
seconds_since_last_update = monotonic() - last_update_time
if ip != prev_ip or seconds_since_last_update > config['max_interval']:
print("Updating to",ip)
update_ip(config,ip)
prev_ip=ip
last_update_time=monotonic()
else:
print("IP has not changed")
print()
sleep(int(config["interval"]))
[Unit]
Description=RFC 2136 Dynamic DNS Update Client
Wants=network-online.target
After=network-online.target nss-lookup.target
[Service]
Type=exec
User=dyndns
ExecStart=python3 /opt/rfc2136_updater.py /etc/rfc2136/conf.json
Restart=on-failure
[Install]
WantedBy=multi-user.target
{
"interval": 10,
"max_interval": 3600,
"ipv4_cmd": ["bash","/opt/fritzbox_ipv4.sh"],
"ipv6_cmd": ["bash","/opt/interface_ipv6.sh"],
"hosts": [
{
"server": "45.129.95.255",
"keyfile": "/etc/rfc2136/glauca-aaaa.private",
"ttl": "120",
"zone": "example.com",
"domain": "aaaa.example.com"
},
{
"server": "45.129.95.255",
"keyfile": "/etc/rfc2136/glauca-bbbb.private",
"ttl": "120",
"zone": "example.com",
"domain": "bbbb.example.com"
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment