{"id":19388376,"url":"https://github.com/mk-fg/tinydns-dynamic-dns-updater","last_synced_at":"2026-05-16T00:02:21.358Z","repository":{"id":18628128,"uuid":"21834133","full_name":"mk-fg/tinydns-dynamic-dns-updater","owner":"mk-fg","description":"Tool to generate and keep tinydns zone file with dynamic dns entries for remote hosts","archived":false,"fork":false,"pushed_at":"2019-08-06T06:51:09.000Z","size":38,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-02-24T19:58:15.130Z","etag":null,"topics":["automation","cryptography","djbdns","dynamic-dns-entries","nacl","python","tinydns"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mk-fg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-14T20:15:52.000Z","updated_at":"2020-12-30T10:30:39.000Z","dependencies_parsed_at":"2022-08-20T18:00:19.855Z","dependency_job_id":null,"html_url":"https://github.com/mk-fg/tinydns-dynamic-dns-updater","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mk-fg/tinydns-dynamic-dns-updater","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk-fg%2Ftinydns-dynamic-dns-updater","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk-fg%2Ftinydns-dynamic-dns-updater/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk-fg%2Ftinydns-dynamic-dns-updater/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk-fg%2Ftinydns-dynamic-dns-updater/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mk-fg","download_url":"https://codeload.github.com/mk-fg/tinydns-dynamic-dns-updater/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk-fg%2Ftinydns-dynamic-dns-updater/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33085078,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T20:25:35.270Z","status":"ssl_error","status_checked_at":"2026-05-15T20:25:34.732Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","cryptography","djbdns","dynamic-dns-entries","nacl","python","tinydns"],"created_at":"2024-11-10T10:12:33.764Z","updated_at":"2026-05-16T00:02:21.316Z","avatar_url":"https://github.com/mk-fg.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"tinydns-dynamic-dns-updater\n--------------------\n\nTool to generate and keep [tinydns](http://tinydns.org/)\n(resolver daemon from [djbdns](http://cr.yp.to/djbdns.html))\nzone file with dynamic dns entries for remote hosts.\n\nIt consists of \"client\" part that sends (several) UDP packets with signing key\nid and signed current timestamp to \"server\", which matches key to a name that\nshould be updated and makes sure timestamp is newer than that of the last update\nthere, and if so, uses source address of the packet to update djbdns database\nname-ip binding.\n\nAll configuration for server is contained within djbdns zone file itself, client\nonly needs commandline parameters for server and path to the client key.\n\nThis approach differs from solutions for same task I've seen in that it doesn't\ninvolve php, http server, passwords (usually passed in plaintext over net), tls,\nquerying random net hosts for your IP or similar stuff, but requires running\nsimple python scripts on both client and server instead.\n\n\n\nUsage\n--------------------\n\nSee --help output for each command for full args/opts reference.\n\nExample (\"S\" is for server terminal, \"C\" - client):\n\n```\nS% ./tddu-client.py -g\n\nS: Signing key (for this script only):\nS:    1k_Nf7FSEWHC2I65DfI2SAhtk1q0Ps9RcLy9PinyDLs=\nS:\nS: Verify key (to use on server):\nS:    jLxAZY-vnJfubHr8srYy3mIN2_mCi_OExUwHOluOlLY=\nS:\n\n[...these keys are used in zone_file.example and with tddu-client.py...]\n\nS% cat zone_file.example\n\nS: +some.static.name:213.180.193.3\nS:\nS: # dynamic: 0 jLxAZY-vnJfubHr8srYy3mIN2_mCi_OExUwHOluOlLY=\nS: +some.random.name:37.98.242.143\nS: +extra.random.name:37.98.242.143\nS: 6some.random.name:2a00145040100c080000000000000066\nS:\nS: +another.static.name:93.158.134.3\nS: 6another.static.name:2a0206b8000000000000000000000003\n\nS% cp zone_file.example zone_file.example.tmp \u0026\u0026 ./tddu-server.py --debug zone_file.example.tmp\n\nS: DEBUG:root:Resolving addr: '::' (params: [5533, 0, 2, 0])\nS: DEBUG:root:Binding to: '::' (port: 5533, af: 10, socktype: 2)\n\nC% ./tddu-client.py --debug ::1:5533 1k_Nf7FSEWHC2I65DfI2SAhtk1q0Ps9RcLy9PinyDLs=\n\nC: DEBUG:root:Resolving addr: '::1' (params: [5533, 0, 2, 0])\nC: DEBUG:root:Sending 1 update msg(s) to: '::1' (port: 5533, af: 10, socktype: 2)\n\nS: DEBUG:root:Updating zone entry for name 'some.random.name' (type: 6): 2a00:1450:4010:c08::66 -\u003e ::1\nS: DEBUG:root:Updating zone block (line: 4) ts: 0.00 -\u003e 1405421249.89\n\n[...it's a BAD idea to pass keys on cli like that, so store it to \"./client.key\" file...]\n\nC% ./tddu-client.py --debug 127.0.0.1:5533 ./client.key\n\nC: DEBUG:root:Resolving addr: '127.0.0.1' (params: [5533, 0, 2, 0])\nC: DEBUG:root:Sending 1 update msg(s) to: '127.0.0.1' (port: 5533, af: 2, socktype: 2)\n\nS: DEBUG:root:Updating zone entry for name 'extra.random.name' (type: +): 37.98.242.143 -\u003e 127.0.0.1\nS: DEBUG:root:Updating zone entry for name 'some.random.name' (type: +): 37.98.242.143 -\u003e 127.0.0.1\nS: DEBUG:root:Updating zone block (line: 4) ts: 1405421249.89 -\u003e 1405421540.03\n\nC% ./tddu-client.py 127.0.0.1:5533 ./client.key\n\nS: DEBUG:root:No address changes in valid update packet: key_id=QlH0RDCxXrI2OvL2OUA4DBeDY79X ts=1405423510.34 addr=127.0.0.1\n```\n\n\n### Requirements\n\n * Python 2.7 (not 3.X)\n\n * [PyNaCl](http://pynacl.readthedocs.org/) or\n   [libnacl](https://libnacl.readthedocs.io/) - either one will work,\n   interoperable with each other (and use same libsodium), no difference\n   whatsoever.\n\n * [netaddr](https://github.com/drkjam/netaddr/) - for the server part.\n\n * (optional)\n   [python-systemd](http://www.freedesktop.org/software/systemd/python-systemd/)\n   \\- to use systemd socket activation for server (--systemd option).\n\n\"test.py\" script also needs [plumbum](http://plumbum.readthedocs.org/),\nbut shouldn't be necessary by itself (runs test server + clients, checks that\nall sent updates were applied correctly).\n\n\n\nOperation details\n--------------------\n\n * Payload of sent UDP packets is fixed 100 bytes in size.\n\n   28B key_id (pubkey hash) || 8B timestamp (double) || 64B Ed25519 signature.\n\n * Client doesn't get any confirmation and is expected to just send as much\n   redundant data (and as often), as required by tolerance for stale data and\n   network reliability.\n\n * It makes sense (and is safe) to send any number of UDP update packets, old\n   ones and non-changes are ignored server-side, as well as any otherwise\n   invalid packets in general.\n\n * Since address is determined from UDP packet source, it matters whether it gets\n   sent over IPv4 or IPv6, and whether there's any SNAT translation in-between.\n\n * If hostname is passed anywhere instead of address, it is resolved by\n   getaddrinfo(3), and if there are several different results, error is raised\n   to prevent ambiguity, esp. wrt IPv4/IPv6 resolution (see also\n   `/etc/gai.conf`).\n\n * Signatures are used as a simple means of client id and\n   authentication.\n\n   [Ed25519 public-key signature system](http://ed25519.cr.yp.to/) is used\n   (as implemented in [libsodium](https://github.com/jedisct1/libsodium/)).\n\n * Timestamps are sent to discard obsolete updates and replay attacks.\n\n   They are not considered to be worth hiding, and are cheaper to check on\n   server before validating signature when sent in plaintext.\n\n * It's safe to change zone files when tddu-server.py script is running, as it\n   always checks mtime (and does reload) before building new files, and then\n   again right before replacing (tempfile-rename) old file with a new one.\n\n * It's also safe to run several server pids from the same file, as they do\n   proper locking on reading/writing to it and update old files as well as\n   replace them with new ones, but no idea if doing that might ever be useful.\n\n\n\nLinks\n--------------------\n\n * [tinydns (non-commercial) promotion/community page](http://tinydns.org/)\n\n * [djb's cr.yp.to page for djbdns](http://cr.yp.to/djbdns.html)\n\n * [Ed25519 public-key signature system info](http://ed25519.cr.yp.to/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmk-fg%2Ftinydns-dynamic-dns-updater","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmk-fg%2Ftinydns-dynamic-dns-updater","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmk-fg%2Ftinydns-dynamic-dns-updater/lists"}