summaryrefslogtreecommitdiff
path: root/he-dns/he-dyndns
diff options
context:
space:
mode:
authorJason D. McCormick <jason@mfamily.org>2022-12-11 13:20:54 -0500
committerJason D. McCormick <jason@mfamily.org>2022-12-11 13:20:54 -0500
commit97459518fad82b19059d7e5cd796ead961c38db6 (patch)
tree0708732142bfc279005065d65a9974bc95747d6f /he-dns/he-dyndns
parentcb0e1dd0e84ab16110d1f377ba27872f771fb9af (diff)
go back to the original orgHEADmaster
Diffstat (limited to 'he-dns/he-dyndns')
-rwxr-xr-xhe-dns/he-dyndns162
1 files changed, 0 insertions, 162 deletions
diff --git a/he-dns/he-dyndns b/he-dns/he-dyndns
deleted file mode 100755
index bec3b60..0000000
--- a/he-dns/he-dyndns
+++ /dev/null
@@ -1,162 +0,0 @@
-#!/usr/bin/env python3
-
-import argparse
-import base64
-import configparser
-import dns.resolver
-import ipaddress
-import logging
-import logging.handlers
-import os.path
-import socket
-import sys
-import urllib
-
-
-HE_DNS_API_HOST = "dyn.dns.he.net"
-
-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 haveIPv6():
- haveIPv6 = True
- try:
- s = socket.socket(socket.AF_INET6)
- s.connect((HE_DNS_API_HOST,80))
- except socket.gaierror as e:
- log.debug("Exception {}".format(e.__class__))
- log.error("Testing IPv6 connection: " + str(e))
- sys.exit(1)
- except OSError as e:
- log.debug("Exception {}".format(e.__class__))
- log.debug(str(e))
- haveIPv6 = False
- except TimeoutError as e:
- log.error("Testing IPv6 connection: " + str(e))
- sys.exit(1)
- except Exception as e:
- log.debug("Exception {}".format(e.__class__))
- log.error(str(e))
- haveIPv6 = False
- return haveIPv6
-
-def getKey(keyfile, record):
- if not os.path.exists(keyfile):
- raise Exception("missing keyfile {}".format(keyfile))
-
- config = configparser.ConfigParser()
- config.read(keyfile)
-
- if not "keys" in config:
- raise Exception("keyfile lacks [keys] section")
-
- if not record in config["keys"]:
- raise Exception("keyfile has no entry for {}".format(record))
-
- return config["keys"][record]
-
-def main():
- ap = argparse.ArgumentParser(description="Update Hurricane Electric DNS dynamic record")
- ap.add_argument("record", help="DNS record to update")
- ap.add_argument("--v4", help="Update IPv4 A record (default)", action="store_true", default=True)
- ap.add_argument("--v6", help="Update IPv6 AAAA record", action="store_true", default=False)
- ap.add_argument("--addr4", help="Update A record with provided IP rather than detected IP")
- ap.add_argument("--addr6", help="Update AAAA record with provided IP rather than detected IP")
- ap.add_argument("--keyfile", help="Alternate location for key config file (default /etc/he-dns-secret.conf)")
- ap.add_argument("--key", help="HE DDNS key for record (by default read from /etc/he-dns-secret.conf or --keyfile)")
- 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:
- log.debug("KEYFILE: {}".format(args.keyfile))
- keyfile = args.keyfile
- else:
- log.debug("KEYFILE: /etc/he-dyndns.conf")
- keyfile = "/etc/he-dyndns.conf"
-
- if args.addr4:
- ip = build_ip(args.addr4)
-
- if args.addr6:
- ip = build_ip(args.addr6)
-
- if args.v6:
- if not haveIPv6 and not args.addr6:
- log.error("no IPv6 detected and --v6 specified without --addr6 (try --debug?)")
- sys.exit(1)
-
- try:
-
- if args.key:
- log.debug("--key override; ignore --kefile")
- apikey = args.key
- else:
- apikey = getKey(keyfile, args.record)
-
- if args.v6:
- ans = dns.resolver.resolve(HE_DNS_API_HOST, "AAAA")[0]
- log.debug("DNS resolved: {}".format(ans.to_text()))
- apihost = "[{}]".format(ans.to_text())
- else:
- ans = dns.resolver.resolve(HE_DNS_API_HOST, "A")[0]
- log.debug("DNS resolved: {}".format(ans.to_text()))
- apihost = ans.to_text()
-
- # build the API URL to be called
- url = "http://{}/nic/update?hostname={}".format(apihost, args.record)
- if args.addr4 or args.addr6:
- url += "&myip={}".format(ip)
- log.debug("API request URL: " + url)
-
- # make the HTTP request
- authstr = base64.b64encode(bytes("%s:%s" % ( args.record, apikey ), "ascii"))
- log.debug("auth string: %s" % authstr.decode("utf-8"))
- req = urllib.request.Request(url)
- req.add_header("Host", HE_DNS_API_HOST)
- req.add_header("Authorization", "Basic %s" % authstr.decode("utf-8"))
- with urllib.request.urlopen(req) as response:
- this_page = response.read()
- log.debug("HE response: " + this_page.decode("utf-8"))
- res = this_page.decode("utf-8").split()[0]
-
- if res == "good":
- return True
- elif res == "badauth":
- raise Exception("HE badauth: wrong key or record not configured for dynamic updates")
- elif res == "nochg":
- return True
- else:
- raise Exception("HE returned {}: unknown response code".format(res))
-
- except dns.resolver.NXDOMAIN as e:
- log.debug("Exception class: {}".format(e.__class__))
- log.error(str(e))
- 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("he-dyndns")
- lh = logging.StreamHandler()
- lf = logging.Formatter(fmt='%(name)s: %(levelname)s: %(message)s')
- lh.setFormatter(lf)
- log.addHandler(lh)
- main()
- sys.exit(0)