DDNS is pain, most of the times. It's not reliable and you may end up breaching something you did not expect to be breached. Therefor pdns has a even more dangerous way to modify the zones. There is an API.

Poor mans dns updater

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/usr/bin/env python3
from isc_dhcp_leases import Lease, IscDhcpLeases
import requests, json

PDNS_API="http://127.0.0.1:8081/api/v1/servers/localhost/zones/my.lan."
leases = IscDhcpLeases('/var/lib/dhcp/dhcpd.leases')

for mac, lease in leases.get_current().items():
    d={"rrsets":[]}
    if not lease.valid: continue
    ip_addr=lease.ip
    if lease.hostname!="":
        d['rrsets'].append(
            {
                "name": f"{lease.hostname}.my.lan.",
                "ttl": 60,
                "type": "A",
                "changetype": "replace",
                "records": [
                    {
                        "content": f"{lease.ip}",
                        "disabled": False,
                    },
                ],
            }
        )
    d['rrsets'].append(
        {
            "name": f"mac-{mac.lower().replace(':','')}.my.lan.",
            "ttl": 60,
            "type": "A",
            "changetype": "replace",
            "records": [
                {
                    "content": f"{lease.ip}",
                    "disabled": False,
                },
            ],
        }
    )
    requests.patch(PDNS_API, json.dumps(d), headers={'X-API-Key': 'PASSWORD'})

This is not a product, but a proof of concept.

This script runs every few seconds and updates the DNS zone for the local network.