{"id":15762159,"url":"https://github.com/harshkapadia2/dynamic-dns","last_synced_at":"2026-02-15T12:37:40.325Z","repository":{"id":193148573,"uuid":"686716901","full_name":"HarshKapadia2/dynamic-dns","owner":"HarshKapadia2","description":"A utility to update an existing DNS record on Cloudflare when the public IP changes.","archived":false,"fork":false,"pushed_at":"2023-09-17T22:30:06.000Z","size":6,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-06T16:35:42.877Z","etag":null,"topics":["ddns","ddns-script","dynamic-dns"],"latest_commit_sha":null,"homepage":"https://networking.harshkapadia.me/dns#dynamic-dns","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HarshKapadia2.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-03T18:01:45.000Z","updated_at":"2024-01-04T07:00:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"bf78e70f-0253-4784-aeec-19de4345e98e","html_url":"https://github.com/HarshKapadia2/dynamic-dns","commit_stats":{"total_commits":5,"total_committers":1,"mean_commits":5.0,"dds":0.0,"last_synced_commit":"f248beda8f58ebe4223c44f0111c47d2fc3535e9"},"previous_names":["harshkapadia2/dynamic-dns"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/HarshKapadia2/dynamic-dns","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HarshKapadia2%2Fdynamic-dns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HarshKapadia2%2Fdynamic-dns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HarshKapadia2%2Fdynamic-dns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HarshKapadia2%2Fdynamic-dns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HarshKapadia2","download_url":"https://codeload.github.com/HarshKapadia2/dynamic-dns/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HarshKapadia2%2Fdynamic-dns/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29478355,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-15T11:35:25.641Z","status":"ssl_error","status_checked_at":"2026-02-15T11:34:57.128Z","response_time":118,"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":["ddns","ddns-script","dynamic-dns"],"created_at":"2024-10-04T11:07:25.257Z","updated_at":"2026-02-15T12:37:40.309Z","avatar_url":"https://github.com/HarshKapadia2.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dynamic DNS\n\nA simple utility to update an existing DNS record on\n[Cloudflare](https://cloudflare.com) when the public IP changes.\n\n## Working\n\nThe main working is in the [`ddns` script](ddns).\n\nThe script gets the public IP from [ipinfo.io/ip](https://ipinfo.io/ip) and\nconducts a rudimentary IP RegEx check.\n\nThe script stores the previously used public IP address in a file called\n`public-ip-in-use.txt`. (Obviously this file does not exist when the script is\nrun for the first time.)\n\nThe script compares the newly found public IP address and the previously used\nIP address stored in `public-ip-in-use.txt`. If the IP addresses are the same,\nthen it does nothing, but if the IP addresses don't match, it replaces the IP\naddress in the `public-ip-in-use.txt` file with the newly found IP address, and\nupdates it on Cloudflare as well.\n\nA CRON job runs this script every 10 minutes, so that the DNS record on\nCloudflare always has the current public IP address.\n\n## Usage\n\n-   Clone the repository.\n\n    ```bash\n    $ cd ~\n    $ git clone https://github.com/HarshKapadia2/dynamic-dns.git\n    ```\n\n-   On the Cloudflare dashboard, create a new `A` record with a dummy IP\n    address. Turn off Cloudflare's proxying for that DNS record and leave it at\n    'DNS Only'.\n\n-   In the repository, create two files `run-ddns` and `list-all-dns-records`,\n    add content to it as described in the [`run-ddns`](#run-ddns) and\n    [`list-all-dns-records`](#list-all-dns-records) sections, and give them\n    executable permissions.\n\n    ```bash\n    $ cd ~/dynamic-ddns\n    $ vim run-ddns # Add content from the 'run-ddns' section below.\n    $ vim list-all-dns-records # Add content from the 'list-all-dns-records' section below.\n    $ sudo chmod +x run-ddns\n    $ sudo chmod +x list-all-dns-records\n    ```\n\n-   Run the `list-all-dns-records` script and make a note of the Record ID of\n    the DNS record to be updated. Add that to the `run-ddns` script.\n\n-   Follow the instructions in the ['CRON Script' section](#cron-script) to set\n    up a CRON job that will run the `run-ddns` script periodically, so that the\n    DNS record on Cloudflare always has the current public IP address.\n\n## Scripts\n\n### `run-ddns`\n\nThis script is used to provide sensitive variables to the [`ddns` script](ddns)\nand then run it.\n\n\u003e NOTE:\n\u003e\n\u003e -   [Cloudflare Zone ID](https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids)\n\u003e -   [Cloudflare API Token](https://adamtheautomator.com/cloudflare-dynamic-dns/#:~:text=on%20PowerShell%207.1.-,Getting%20a%20the%20Cloudflare%20API%20Token,-When%20updating%20the)\n\u003e -   The Cloudflare Record ID can be found by running the [`list-all-dns-records` script](#list-all-dns-records).\n\n```bash\n#! /bin/bash\n\nset -Eeuo pipefail\n\n# Set 'dynamic-dns' repository directory path\nddns_repo_path=\"$(dirname \"$0\")\"\n\nif [[ \"${ddns_repo_path}\" == \".\" ]]; then\n\tddns_repo_path=\"$(pwd)\"\nfi\n\n# Provide environment variables and run `ddns` script\nCLOUDFLARE_ZONE_ID=\"\u003czone_id_here\u003e\" \\\n\tCLOUDFLARE_AUTH_KEY=\"\u003capi_token_here\u003e\" \\\n\tCLOUDFLARE_DNS_RECORD_NAME=\"\u003c[subdomain.]domainname.tld\u003e\" \\\n\tCLOUDFLARE_DNS_RECORD_ID=\"\u003cid_of_record_to_be_updated_here\u003e\" \\\n\tbash \"${ddns_repo_path}/ddns\"\n```\n\n\u003e [Setting environment variables just for one command/script](https://unix.stackexchange.com/questions/495161/import-environment-variables-in-a-bash-script#:~:text=to%20set%20the%20environment%20variable%20just%20for%20this%20script)\n\n### CRON Script\n\nIn Ubuntu, this script is to be placed at `/etc/cron.d/dynamic-dns`. It runs a\nCRON job every 10 minutes to run the `run-ddns` script.\n\n\u003e NOTE: Replace the `HOME` variable with the path to the `dynamic-dns` repo\n\u003e location. Also, replace the `\u003cusername\u003e` with the name of the user that should\n\u003e run the script (`root` or any other user).\n\n```\n# This is to set up a public IP address.\nSHELL=/bin/bash\nHOME=/home/harsh/dynamic-dns\n#\n*/10 * * * * \u003cusername\u003e ./run-ddns\n```\n\n### `list-all-dns-records`\n\nThis script lists information about all DNS records. It is used to to get the\nRecord ID of the DNS record that needs to be updated by the `ddns` script.\n\n\u003e NOTE:\n\u003e\n\u003e -   [Cloudflare Zone ID](https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids)\n\u003e -   [Cloudflare API Token](https://adamtheautomator.com/cloudflare-dynamic-dns/#:~:text=on%20PowerShell%207.1.-,Getting%20a%20the%20Cloudflare%20API%20Token,-When%20updating%20the)\n\n```bash\n#! /bin/bash\n\nset -Eeuo pipefail\n\nCLOUDFLARE_ZONE_ID=\"\u003czone_id_here\u003e\"\nCLOUDFLARE_AUTH_KEY=\"\u003capi_token_here\u003e\"\n\ncurl --request GET \\\n\t--url \"https://api.cloudflare.com/client/v4/zones/${CLOUDFLARE_ZONE_ID}/dns_records\" \\\n\t--header \"Content-Type: application/json\" \\\n\t--header \"Authorization: Bearer ${CLOUDFLARE_AUTH_KEY}\"\n```\n\n## Resources\n\n-   [What Is Dynamic DNS (DDNS), and How Do You Set It Up?](https://www.howtogeek.com/866573/what-is-dynamic-dns-ddns-and-how-do-you-set-it-up)\n-   [How to Setup Cloudflare Dynamic DNS](https://adamtheautomator.com/cloudflare-dynamic-dns)\n-   CRON Jobs\n    -   [Scheduling Cron Jobs with Crontab](https://linuxize.com/post/scheduling-cron-jobs-with-crontab)\n    -   [How to Run Cron Jobs Every 5, 10, or 15 Minutes](https://linuxize.com/post/scheduling-cron-jobs-with-crontab)\n    -   [Creating a file in `/etc/cron.d`](https://stackoverflow.com/a/64450726/11958552)\n    -   [How to view a cron job running currently?](https://stackoverflow.com/a/36883237/11958552)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharshkapadia2%2Fdynamic-dns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fharshkapadia2%2Fdynamic-dns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharshkapadia2%2Fdynamic-dns/lists"}