Skip to content

Commit ed6298e

Browse files
authored
feat: refactor (#94)
* wip: ts migration * wip: working out tests * wip: tests * wip: docs and project metadata * restore gh action * prefer User API Token
1 parent 7548b29 commit ed6298e

15 files changed

Lines changed: 5069 additions & 268 deletions

.devcontainer/devcontainer.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

.editorconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# http://editorconfig.org
2+
root = true
3+
4+
[*]
5+
indent_style = tab
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true
10+
11+
[*.yml]
12+
indent_style = space

.gitignore

Lines changed: 172 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,172 @@
1-
node_modules
2-
.mf/cert
3-
secrets.txt
1+
# Logs
2+
3+
logs
4+
_.log
5+
npm-debug.log_
6+
yarn-debug.log*
7+
yarn-error.log*
8+
lerna-debug.log*
9+
.pnpm-debug.log*
10+
11+
# Diagnostic reports (https://nodejs.org/api/report.html)
12+
13+
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
14+
15+
# Runtime data
16+
17+
pids
18+
_.pid
19+
_.seed
20+
\*.pid.lock
21+
22+
# Directory for instrumented libs generated by jscoverage/JSCover
23+
24+
lib-cov
25+
26+
# Coverage directory used by tools like istanbul
27+
28+
coverage
29+
\*.lcov
30+
31+
# nyc test coverage
32+
33+
.nyc_output
34+
35+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
36+
37+
.grunt
38+
39+
# Bower dependency directory (https://bower.io/)
40+
41+
bower_components
42+
43+
# node-waf configuration
44+
45+
.lock-wscript
46+
47+
# Compiled binary addons (https://nodejs.org/api/addons.html)
48+
49+
build/Release
50+
51+
# Dependency directories
52+
53+
node_modules/
54+
jspm_packages/
55+
56+
# Snowpack dependency directory (https://snowpack.dev/)
57+
58+
web_modules/
59+
60+
# TypeScript cache
61+
62+
\*.tsbuildinfo
63+
64+
# Optional npm cache directory
65+
66+
.npm
67+
68+
# Optional eslint cache
69+
70+
.eslintcache
71+
72+
# Optional stylelint cache
73+
74+
.stylelintcache
75+
76+
# Microbundle cache
77+
78+
.rpt2_cache/
79+
.rts2_cache_cjs/
80+
.rts2_cache_es/
81+
.rts2_cache_umd/
82+
83+
# Optional REPL history
84+
85+
.node_repl_history
86+
87+
# Output of 'npm pack'
88+
89+
\*.tgz
90+
91+
# Yarn Integrity file
92+
93+
.yarn-integrity
94+
95+
# dotenv environment variable files
96+
97+
.env
98+
.env.development.local
99+
.env.test.local
100+
.env.production.local
101+
.env.local
102+
103+
# parcel-bundler cache (https://parceljs.org/)
104+
105+
.cache
106+
.parcel-cache
107+
108+
# Next.js build output
109+
110+
.next
111+
out
112+
113+
# Nuxt.js build / generate output
114+
115+
.nuxt
116+
dist
117+
118+
# Gatsby files
119+
120+
.cache/
121+
122+
# Comment in the public line in if your project uses Gatsby and not Next.js
123+
124+
# https://nextjs.org/blog/next-9-1#public-directory-support
125+
126+
# public
127+
128+
# vuepress build output
129+
130+
.vuepress/dist
131+
132+
# vuepress v2.x temp and cache directory
133+
134+
.temp
135+
.cache
136+
137+
# Docusaurus cache and generated files
138+
139+
.docusaurus
140+
141+
# Serverless directories
142+
143+
.serverless/
144+
145+
# FuseBox cache
146+
147+
.fusebox/
148+
149+
# DynamoDB Local files
150+
151+
.dynamodb/
152+
153+
# TernJS port file
154+
155+
.tern-port
156+
157+
# Stores VSCode versions used for testing VSCode extensions
158+
159+
.vscode-test
160+
161+
# yarn v2
162+
163+
.yarn/cache
164+
.yarn/unplugged
165+
.yarn/build-state.yml
166+
.yarn/install-state.gz
167+
.pnp.\*
168+
169+
# wrangler project
170+
171+
.dev.vars
172+
.wrangler/

.prettierrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"printWidth": 140,
3+
"singleQuote": true,
4+
"semi": true,
5+
"useTabs": true
6+
}

README.md

Lines changed: 68 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,85 @@
11
# Cloudflare DDNS for UniFi OS
22

3-
A Cloudflare Worker script that provides a UniFi-compatible DDNS API to dynamically update the IP address of a DNS A record.
3+
A Cloudflare Worker script that enables UniFi devices (e.g., UDM-Pro, USG) to dynamically update DNS A/AAAA records on Cloudflare.
44

5-
## Why?
5+
## Why Use This?
66

7-
UniFi Dream Machine Pro (UDM-Pro) or UniFi Security Gateway (USG) users may need to update Cloudflare domain name DNS records when their public IP address changes. UniFi does not natively support Cloudflare as a DDNS provider.
7+
UniFi devices do not natively support Cloudflare as a DDNS provider. This script bridges that gap, allowing your UniFi device to keep your DNS records updated with your public IP address.
88

9-
## Configuring Cloudflare
9+
---
1010

11-
Ensure you have a Cloudflare account and your domain is configured to point to Cloudflare nameservers.
11+
## 🚀 **Setup Overview**
1212

13-
### Worker Setup
13+
### 1. **Deploy the Cloudflare Worker**
1414

15-
#### Deploy With Click To Deploy
15+
#### **Option 1: Click to Deploy**
16+
[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/willswire/unifi-ddns)
1617

17-
1. Deploy the Worker: [![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/workerforce/unifi-ddns)
18-
2. Navigate to the Cloudflare Workers dashboard.
19-
3. After deployment, note the `\*.workers.dev` route.
18+
1. Click the button above.
19+
2. Complete the deployment.
20+
3. Note the `*.workers.dev` route.
2021

21-
#### Deploy With Wrangler CLI
22+
#### **Option 2: Deploy with Wrangler CLI**
23+
1. Clone this repository.
24+
2. Install [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/install-and-update/).
25+
3. Run:
26+
```sh
27+
wrangler login
28+
wrangler deploy
29+
```
30+
4. Note the `*.workers.dev` route.
2231

23-
1. Clone or download this project.
24-
2. Ensure you have [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/install-and-update/) installed.
25-
3. Log in with Wrangler and run `wrangler deploy`.
26-
4. Note the `\*.workers.dev` route after creation.
32+
---
2733

28-
### API Token for DNS Record Updates
29-
An API Token will be needed for each UniFi client performing DDNS updates.
30-
To create the token(s):
31-
1. Tokens can now be created at the user level or account level
34+
### 2. **Generate a Cloudflare API Token**
3235

33-
User token:
34-
- Go to https://dash.cloudflare.com/profile/api-tokens
35-
- Key differences:
36-
- Access to all accounts for which the user is a member and has permissions (unless explicitly limited in token settings)
37-
- Actions performed by this token are associated with the user
38-
- Viewable/Editable only by the creating user
36+
1. Go to the [Cloudflare Dashboard](https://dash.cloudflare.com/).
37+
2. Navigate to **Profile > API Tokens**
38+
3. Create a token using the **Edit zone DNS** template.
39+
4. Scope the token to **one** specific zone.
40+
5. Save the token securely.
3941

40-
Account token: (Recommended)
41-
- On the [CloudFlare Dashboard](https://dash.cloudflare.com/), open the account which manages the target zone(s)
42-
- Select Manage Account > Account API Tokens
43-
- Key differences:
44-
- Access limited to only the account for which it is created
45-
- Actions performed by this token are not attributed to a user
46-
- Viewable/Editable by all account members (with the appropriate permissions)
47-
2. Click "Create Token"
48-
3. Click "Use Template" for "Edit zone DNS"
49-
4. Under "Zone Resources," include the target zone or select "All zones from an account."
50-
(If using a user token, "All zones" is also an option.)
51-
Set a token name and/or additional restrictions as desired.
52-
5. Click "Continue to summary" then "Create Token."
53-
Copy and save the generated token for later use configuring the UniFi OS Controller.
42+
---
5443

55-
## Configuring UniFi OS
44+
### 3. **Configure UniFi OS**
5645

5746
1. Log in to your [UniFi OS Controller](https://unifi.ui.com/).
58-
2. Navigate to Settings > Internet > WAN and scroll down to **Dynamic DNS**.
59-
3. Click **Create New Dynamic DNS** and provide:
60-
- `Service`: Choose `custom` or `dyndns`.
61-
- `Hostname`: Full subdomain and hostname to update (e.g., `subdomain.mydomain.com` or `mydomain.com` for root domain).
62-
- `Username`: Domain name containing the record (e.g., `mydomain.com`).
63-
- `Password`: Cloudflare API Token.
64-
- `Server`: Cloudflare Worker route `<worker-name>.<worker-subdomain>.workers.dev/update?ip=%i&hostname=%h`.
65-
- For older UniFi devices, omit the URL path.
66-
- Remove `https://` from the URL.
67-
68-
### Testing Changes - UDM-Pro
69-
To test the configuration and force an update on a UDM-Pro:
70-
71-
1. SSH into your UniFi device.
72-
2. Run `ps aux | grep inadyn`.
73-
3. Note the configuration file path.
74-
4. Run `inadyn -n -1 --force -f <config-path>` (e.g., `inadyn -n -1 --force -f /run/ddns-eth4-inadyn.conf`).
75-
5. Check `/var/log/messages` for related error messages.
76-
77-
### Testing Changes - USG
78-
To test the configuration and force an update on a USG:
79-
80-
1. SSH into your USG device.
81-
2. Run `ls /run/ddclient/` (e.g.: `/run/ddclient/ddclient_eth0.pid`)
82-
3. Note the pid file path as this will tell you what configuration to use. (e.g.: `ddclient_eth0`)
83-
4. Run `sudo ddclient -daemon=0 -verbose -noquiet -debug -file /etc/ddclient/<config>.conf` (e.g., `sudo ddclient -daemon=0 -verbose -noquiet -debug -file /etc/ddclient/ddclient_eth0.conf`).
84-
5. This should output `SUCCESS` when the DNS record is set.
85-
86-
### Important Notes!
87-
88-
- For subdomains (`sub.example.com`), create an A record manually in Cloudflare dashboard first.
89-
- If you encounter a hostname resolution error (`inadyn[2173778]: Failed resolving hostname https: Name or service not known`), remove `https://` from the `Server` field.
90-
- If you are using wildcard subdomains, be sure to enter your `Hostname` in UniFi OS as `*.mydomain.com`
91-
- There seems to be a bug in the UniFi OS UI that makes it impossible to edit the Dynamic DNS settings, you may need to remove the configuration and create a new one each time you need to make a change.
47+
2. Go to **Settings > Internet > WAN > Dynamic DNS**.
48+
3. Create New Dynamic DNS with the following information:
49+
- **Service:** `custom`
50+
- **Hostname:** `subdomain.example.com` or `example.com`
51+
- **Username:** Cloudflare Account Email Address (e.g., `you@example.com`)
52+
- **Password:** Cloudflare User API Token *(not an Account API Token)*
53+
- **Server:** `<worker-name>.<worker-subdomain>.workers.dev/update?ip=%i&hostname=%h`
54+
*(Omit `https://`)*
55+
56+
---
57+
58+
## 🛠️ **Testing & Troubleshooting**
59+
60+
### **UDM-Pro Testing**
61+
1. SSH into your UDM-Pro.
62+
2. Run:
63+
```sh
64+
ps aux | grep inadyn
65+
inadyn -n -1 --force -f /run/ddns-eth4-inadyn.conf
66+
```
67+
3. Check `/var/log/messages` for errors.
68+
69+
### **USG Testing**
70+
1. SSH into your USG.
71+
2. Run:
72+
```sh
73+
sudo ddclient -daemon=0 -verbose -noquiet -debug -file /etc/ddclient/ddclient_eth0.conf
74+
```
75+
3. Look for `SUCCESS` in the output.
76+
77+
---
78+
79+
## ⚠️ **Important Notes**
80+
81+
- Updates occur approximately every two minutes. You can tail the worker logs to validate updates from your UniFi device.
82+
- For **subdomains** (`sub.example.com`), manually create an A record in Cloudflare first.
83+
- Remove `https://` from the **Server** field.
84+
- **Wildcard domains:** Use `*.example.com` in the **Hostname** field.
85+
- UniFi OS may require recreating DDNS entries instead of editing them.

0 commit comments

Comments
 (0)