summaryrefslogtreecommitdiff
path: root/ddns-update-rfc2136
diff options
context:
space:
mode:
authorJason D. McCormick <jason@mfamily.org>2023-12-20 13:09:20 -0500
committerJason D. McCormick <jason@mfamily.org>2023-12-20 13:09:20 -0500
commit93f370195a4178aefce312027ad042559dd51a64 (patch)
treebb4c40c46f98e003a118c7e006441a0018eef6a8 /ddns-update-rfc2136
parent914ec229e8d4d1ba375874fb460651dab587951f (diff)
reorg repo
Diffstat (limited to 'ddns-update-rfc2136')
-rwxr-xr-xddns-update-rfc2136147
1 files changed, 0 insertions, 147 deletions
diff --git a/ddns-update-rfc2136 b/ddns-update-rfc2136
deleted file mode 100755
index 6bd07ce..0000000
--- a/ddns-update-rfc2136
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/usr/bin/env python3
-
-import argparse
-import ipaddress
-import netifaces
-import logging
-import logging.handlers
-import os.path
-import socket
-import subprocess
-import sys
-
-
-def build_ip(ip_string):
- try:
- ip = ipaddress.ip_address(ip_string)
- except ValueError:
- log.error("manually specified address is invalid format: %s" % ip_string)
- sys.exit(1)
- except:
- log.error(str(e))
- sys.exit(1)
-
- return ip
-
-def get_interface_addrs(iface, addrtype):
- try:
- iaddrs = netifaces.ifaddresses(iface)
- i = iaddrs[addrtype]
- log.debug("interface {} addrs of type {}: {}".format(iface,addrtype,i))
- except ValueError as e:
- log.debug("Exception class: {}".format(e.__class__))
- log.error("No interface named {} found".format(iface))
- sys.exit(1)
- except KeyError as e:
- log.debug("Exception class: {}".format(e.__class__))
- log.error("No address of type {} found on interface {}".format(addrtype, iface))
- sys.exit(1)
- except Exception as e:
- log.debug("Exception class: {}".format(e.__class__))
- log.error(str(e))
- sys.exit(1)
-
- return i
-
-def build_nsupdate_cmd(server, zone, record, rrtype, ttl, addr):
- log.debug("BNC: server: {}".format(server))
- log.debug("BNC: zone: {}".format(zone))
- log.debug("BNC: record: {}".format(record))
- log.debug("BNC: rrtype: {}".format(rrtype))
- log.debug("BNC: ttl: {}".format(ttl))
- log.debug("BNC: addr: {}".format(addr))
-
- cmdstr = "server {}\n".format(server)
- cmdstr += "zone {}\n".format(zone)
- cmdstr += "update delete {} {}\n".format(record, rrtype)
- cmdstr += "update add {} {} {} {}\n".format(record, ttl, rrtype, addr)
- cmdstr += "send\n"
- cmdstr += "quit\n"
-
- return cmdstr
-
-def main():
- ap = argparse.ArgumentParser(description="Update dynamic DNS records using RFC2136")
- ap.add_argument("interface", help="interface to obtain IP from (for IPv6, takes the numerically first global address on the interface)")
- ap.add_argument("record", help="DNS record to update")
- ap.add_argument("zone", help="Zone name to update (e.g. example.com)")
- ap.add_argument("server", help="Server to update (IP or FQDN)")
- ap.add_argument("--v4", help="Update IPv4 A record", action="store_true", default=False)
- ap.add_argument("--v6", help="Update IPv6 AAAA record (default)", action="store_true", default=True)
- ap.add_argument("--addr4", help="Update A record with provided IP rather than detected IP (causes 'interface' to be ignored)")
- ap.add_argument("--addr6", help="Update AAAA record with provided IP rather than detected IP (causes 'interface' to be ignored)")
- ap.add_argument("--ttl", help="TTL to assign to record (default 300)", default=300)
- ap.add_argument("--keyfile", help="Alternate location for key config file (default /etc/ddns-RECORD.key where RECORD is the record name provided as the argument)")
- ap.add_argument("--debug", help="Enable debug logging", action="store_true", default=False)
- args = ap.parse_args()
-
- if args.debug:
- log.setLevel(logging.DEBUG)
- else:
- log.setLevel(logging.ERROR)
-
- if args.keyfile:
- keyfile = args.keyfile
- else:
- keyfile = "/etc/ddns-{}.key".format(args.record)
- log.debug("KEYFILE: {}".format(keyfile))
-
- if args.v4:
- addrtype = netifaces.AF_INET
- else:
- addrtype = netifaces.AF_INET6
-
- ip = False
- if args.addr4:
- ip = build_ip(args.addr4)
-
- if args.addr6:
- ip = build_ip(args.addr6)
-
- try:
- if not os.path.exists(keyfile):
- raise Exception("missing key file {}".format(keyfile))
-
- if ip:
- addr = ip
- log.debug("Manual IP: {}".format(addr))
- else:
- addrarr = get_interface_addrs(args.interface, addrtype)
- addr = addrarr.pop(0)['addr']
- log.debug("Found IP: {}".format(addr))
-
- rrtype = "AAAA"
- if args.v4:
- rrtype = "A"
-
- nsupdatecmd = build_nsupdate_cmd(args.server, args.zone, args.record, rrtype, args.ttl, addr)
-
- nsupdate = subprocess.run(
- "nsupdate -k {}".format(keyfile),
- shell=True,
- check=True,
- input = bytes(nsupdatecmd,'utf-8'),
- capture_output = True
- )
-
- log.debug("nsupdate return code: {}".format(nsupdate.returncode))
-
- except subprocess.CalledProcessError as e:
- log.debug("Exception class: {}".format(e.__class__))
- log.error("Error executing: " + e.cmd)
- log.error("nsupdate stderr: " + e.stderr.decode("utf-8").strip())
- sys.exit(1)
-
- except Exception as e:
- log.debug("Exception class: {}".format(e.__class__))
- log.error(str(e))
- sys.exit(1)
-
-if __name__ == "__main__":
- log = logging.getLogger("ddns-update-rfc2136")
- lh = logging.StreamHandler()
- lf = logging.Formatter(fmt='%(name)s: %(levelname)s: %(message)s')
- lh.setFormatter(lf)
- log.addHandler(lh)
- main()
- sys.exit(0)