commit d55df0606864f2a48a47ef92db937296d4c67e89 Author: Ruben van de Ven Date: Tue Apr 2 16:53:10 2019 +0200 Simple DNS updater diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b6b072 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.yaml diff --git a/README.md b/README.md new file mode 100644 index 0000000..e72158a --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# DNS Updater + +A dyndns-like updater for the DNS service of PCExtreme, called Aurora. Their service is supported by Apache's libcloud ([docs](https://libcloud.readthedocs.io/en/latest/dns/drivers/auroradns.html)). This simple script helps to use these domains for some [homebrewing](https://homebrewserver.club/). + +## Usage + +It works fairly simple. Create a `config.yaml` file: + +```yaml +client_key: YOURKEY +client_secret: YOURSECRET + +zones: + - domainname.com: + - name: www + type: AAAA + - name: "" + type: AAAA + - name: www + type: A + - name: "" + type: A + + +``` + +and run: + +```bash +python dnsupdate.py -c config.yaml +``` + +You should probably run it with cron to keep your DNS up to date. If you have any issues, add `-v` for some verbosity. + +The script is _very_ basic: so `AAAA` records will be set to your IPv6 address, all other record types to IPv4. diff --git a/dnsupdate.py b/dnsupdate.py new file mode 100644 index 0000000..ecb002d --- /dev/null +++ b/dnsupdate.py @@ -0,0 +1,81 @@ +from libcloud.dns.types import Provider, RecordType +from libcloud.dns.providers import get_driver +import requests +import yaml +import logging +import argparse + + +logger = logging.getLogger('dns') + +def update_or_create_record_for_zone(driver, zone, name, type, ip): + for r in driver.iterate_records(zone): + rname = "" if r.name is None else r.name # glitch with empty name + if rname == name and r.type == type: + if r.data == ip: + logger.info( + "Record ok: {}".format(r) + ) + return r + + logger.info( + "Update {}".format(r) + ) + return driver.update_record( + r, name=name, type=type, data=ip + ) + + logger.info("Create {} {}".format(type, name)) + return zone.create_record(name=name, type=type, data=ip) + + +def run_config(config): + cls = get_driver(Provider.AURORADNS) + print(config) + + ipv6 = requests.get('http://ip6only.me/api').text.split(',')[1] + logger.info("IPv6: {}".format(ipv6)) + ipv4 = requests.get('http://ip4.me/api').text.split(',')[1] + logger.info("IPv4: {}".format(ipv4)) + + driver = cls(config['client_key'],config['client_secret']) + for z in config['zones']: + for name, records in z.items(): + zone = driver.get_zone(name) + logger.info("Zone: {} - {}".format(name, zone.id)) + for record in records: + logger.debug("Record: {}".format(record)) + if record['type'] not in RecordType.__dict__: + raise Exception("Invalid record type: {}".format(record['type'])) + + # Following assumption is not 100% valid, but works for me + # adjust it if you need anything else. + ip = ipv6 if record['type'] == RecordType.AAAA else ipv4 + update_or_create_record_for_zone(driver, zone, record['name'], record['type'], ip) + +if __name__ == '__main__': + argParser = argparse.ArgumentParser( + description='Connect with PCExtreme Aurora DNS and set records from config based on current ip.') + argParser.add_argument( + '--config', + '-c', + required=True, + type=str, + help='The yaml config file to load' + ) + argParser.add_argument( + '--verbose', + '-v', + action='store_true' + ) + + args = argParser.parse_args() + + logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO) + + with open(args.config, 'r') as fp: + config = yaml.load(fp) + run_config(config) + + + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..708f0e3 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +requests +apache-libcloud +yaml