diff --git a/dns/ddclient/Makefile b/dns/ddclient/Makefile index bd849f880..4b731c124 100644 --- a/dns/ddclient/Makefile +++ b/dns/ddclient/Makefile @@ -1,7 +1,6 @@ PLUGIN_NAME= ddclient -PLUGIN_VERSION= 1.14 -PLUGIN_REVISION= 1 -PLUGIN_DEPENDS= ddclient-devel +PLUGIN_VERSION= 1.15 +PLUGIN_DEPENDS= ddclient-devel py${PLUGIN_PYTHON}-boto3 PLUGIN_COMMENT= Dynamic DNS client PLUGIN_MAINTAINER= ad@opnsense.org diff --git a/dns/ddclient/src/opnsense/mvc/app/controllers/OPNsense/DynDNS/forms/dialogAccount.xml b/dns/ddclient/src/opnsense/mvc/app/controllers/OPNsense/DynDNS/forms/dialogAccount.xml index 7afd4b9c4..12aedb288 100644 --- a/dns/ddclient/src/opnsense/mvc/app/controllers/OPNsense/DynDNS/forms/dialogAccount.xml +++ b/dns/ddclient/src/opnsense/mvc/app/controllers/OPNsense/DynDNS/forms/dialogAccount.xml @@ -62,7 +62,7 @@ account.zone text - + Zone containing the host entry. @@ -73,6 +73,13 @@ true Hostname to update + + account.ttl + + text + + Time to Live for the DNS entry + account.checkip diff --git a/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.xml b/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.xml index 7557c5fe4..5a3b4dd37 100644 --- a/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.xml +++ b/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.xml @@ -171,6 +171,12 @@ 1 Y + + 300 + Y + 1 + 604800 + N N diff --git a/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/aws.py b/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/aws.py new file mode 100644 index 000000000..7d66b0d19 --- /dev/null +++ b/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/aws.py @@ -0,0 +1,71 @@ +""" + AWS Route53 DNS provider + Usage: + AWS access key: username + AWS secret key: password + Route53 Hosted Zone ID: resource ID (use advanced settings) +""" +import syslog +import boto3 +from . import BaseAccount + + +class AWS(BaseAccount): + _services = ['aws'] + + def __init__(self, account: dict): + super().__init__(account) + + @staticmethod + def known_services(): + return AWS._services + + @staticmethod + def match(account): + return account.get('service') in AWS._services + + def execute(self): + """ AWS DNS update + """ + + if super().execute(): + if not self.current_address: + syslog.syslog( + syslog.LOG_WARNING, + f"No address found for {self.description}" + ) + return False + client = boto3.client('route53', + aws_access_key_id = self.settings.get('username'), + aws_secret_access_key = self.settings.get('password')) + ip = str(self.current_address) + if ':' in ip: + addrType = 'AAAA' + else: + addrType = 'A' + TTL = self.settings.get('ttl') + changeBatch = { + 'Changes': [{ + 'Action': 'UPSERT', + 'ResourceRecordSet': { + 'Name': host, + 'Type': addrType, + 'TTL': int(TTL), + 'ResourceRecords': [{'Value': ip}] + } + } for host in self.settings.get('hostnames').split(",")] + } + try: + response = client.change_resource_record_sets( + HostedZoneId = self.settings.get('zone'), + ChangeBatch = changeBatch) + except Exception as e: + syslog.syslog(syslog.LOG_ERR, str(e)) + return False + + syslog.syslog( + syslog.LOG_NOTICE, + f"Account {self.description} set new ip {self.current_address}, ID {response['ChangeInfo']['Id']}") + + self.update_state(address=self.current_address) + return True diff --git a/dns/ddclient/src/opnsense/service/templates/OPNsense/ddclient/ddclient.json b/dns/ddclient/src/opnsense/service/templates/OPNsense/ddclient/ddclient.json index 3e2b8cfed..97895c809 100644 --- a/dns/ddclient/src/opnsense/service/templates/OPNsense/ddclient/ddclient.json +++ b/dns/ddclient/src/opnsense/service/templates/OPNsense/ddclient/ddclient.json @@ -24,6 +24,7 @@ "checkip": "{{ account.checkip }}", "checkip_timeout": {{ account.checkip_timeout }}, "force_ssl": {{ "true" if account.force_ssl == '1' else "false"}}, + "ttl": "{{ account.ttl }}", "interface": "{%if account.interface %}{{physical_interface(account.interface)}}{% endif%}", "description": "{{ account.description }}" }{{ "," if not loop.last else ""}}