Skip to content

Commit

Permalink
feat: refactor (#94)
Browse files Browse the repository at this point in the history
* wip: ts migration

* wip: working out tests

* wip: tests

* wip: docs and project metadata

* restore gh action

* prefer User API Token
  • Loading branch information
willswire authored Dec 30, 2024
1 parent 7548b29 commit ed6298e
Show file tree
Hide file tree
Showing 15 changed files with 5,069 additions and 268 deletions.
5 changes: 0 additions & 5 deletions .devcontainer/devcontainer.json

This file was deleted.

12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# http://editorconfig.org
root = true

[*]
indent_style = tab
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.yml]
indent_style = space
175 changes: 172 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,172 @@
node_modules
.mf/cert
secrets.txt
# Logs

logs
_.log
npm-debug.log_
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)

report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json

# Runtime data

pids
_.pid
_.seed
\*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover

lib-cov

# Coverage directory used by tools like istanbul

coverage
\*.lcov

# nyc test coverage

.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)

.grunt

# Bower dependency directory (https://bower.io/)

bower_components

# node-waf configuration

.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)

build/Release

# Dependency directories

node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)

web_modules/

# TypeScript cache

\*.tsbuildinfo

# Optional npm cache directory

.npm

# Optional eslint cache

.eslintcache

# Optional stylelint cache

.stylelintcache

# Microbundle cache

.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history

.node_repl_history

# Output of 'npm pack'

\*.tgz

# Yarn Integrity file

.yarn-integrity

# dotenv environment variable files

.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)

.cache
.parcel-cache

# Next.js build output

.next
out

# Nuxt.js build / generate output

.nuxt
dist

# Gatsby files

.cache/

# Comment in the public line in if your project uses Gatsby and not Next.js

# https://nextjs.org/blog/next-9-1#public-directory-support

# public

# vuepress build output

.vuepress/dist

# vuepress v2.x temp and cache directory

.temp
.cache

# Docusaurus cache and generated files

.docusaurus

# Serverless directories

.serverless/

# FuseBox cache

.fusebox/

# DynamoDB Local files

.dynamodb/

# TernJS port file

.tern-port

# Stores VSCode versions used for testing VSCode extensions

.vscode-test

# yarn v2

.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.\*

# wrangler project

.dev.vars
.wrangler/
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"printWidth": 140,
"singleQuote": true,
"semi": true,
"useTabs": true
}
142 changes: 68 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,91 +1,85 @@
# Cloudflare DDNS for UniFi OS

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

## Why?
## Why Use This?

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.
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.

## Configuring Cloudflare
---

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

### Worker Setup
### 1. **Deploy the Cloudflare Worker**

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

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)
2. Navigate to the Cloudflare Workers dashboard.
3. After deployment, note the `\*.workers.dev` route.
1. Click the button above.
2. Complete the deployment.
3. Note the `*.workers.dev` route.

#### Deploy With Wrangler CLI
#### **Option 2: Deploy with Wrangler CLI**
1. Clone this repository.
2. Install [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/install-and-update/).
3. Run:
```sh
wrangler login
wrangler deploy
```
4. Note the `*.workers.dev` route.

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

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

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

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

## Configuring UniFi OS
### 3. **Configure UniFi OS**

1. Log in to your [UniFi OS Controller](https://unifi.ui.com/).
2. Navigate to Settings > Internet > WAN and scroll down to **Dynamic DNS**.
3. Click **Create New Dynamic DNS** and provide:
- `Service`: Choose `custom` or `dyndns`.
- `Hostname`: Full subdomain and hostname to update (e.g., `subdomain.mydomain.com` or `mydomain.com` for root domain).
- `Username`: Domain name containing the record (e.g., `mydomain.com`).
- `Password`: Cloudflare API Token.
- `Server`: Cloudflare Worker route `<worker-name>.<worker-subdomain>.workers.dev/update?ip=%i&hostname=%h`.
- For older UniFi devices, omit the URL path.
- Remove `https://` from the URL.

### Testing Changes - UDM-Pro
To test the configuration and force an update on a UDM-Pro:

1. SSH into your UniFi device.
2. Run `ps aux | grep inadyn`.
3. Note the configuration file path.
4. Run `inadyn -n -1 --force -f <config-path>` (e.g., `inadyn -n -1 --force -f /run/ddns-eth4-inadyn.conf`).
5. Check `/var/log/messages` for related error messages.

### Testing Changes - USG
To test the configuration and force an update on a USG:

1. SSH into your USG device.
2. Run `ls /run/ddclient/` (e.g.: `/run/ddclient/ddclient_eth0.pid`)
3. Note the pid file path as this will tell you what configuration to use. (e.g.: `ddclient_eth0`)
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`).
5. This should output `SUCCESS` when the DNS record is set.

### Important Notes!

- For subdomains (`sub.example.com`), create an A record manually in Cloudflare dashboard first.
- If you encounter a hostname resolution error (`inadyn[2173778]: Failed resolving hostname https: Name or service not known`), remove `https://` from the `Server` field.
- If you are using wildcard subdomains, be sure to enter your `Hostname` in UniFi OS as `*.mydomain.com`
- 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.
2. Go to **Settings > Internet > WAN > Dynamic DNS**.
3. Create New Dynamic DNS with the following information:
- **Service:** `custom`
- **Hostname:** `subdomain.example.com` or `example.com`
- **Username:** Cloudflare Account Email Address (e.g., `[email protected]`)
- **Password:** Cloudflare User API Token *(not an Account API Token)*
- **Server:** `<worker-name>.<worker-subdomain>.workers.dev/update?ip=%i&hostname=%h`
*(Omit `https://`)*

---

## 🛠️ **Testing & Troubleshooting**

### **UDM-Pro Testing**
1. SSH into your UDM-Pro.
2. Run:
```sh
ps aux | grep inadyn
inadyn -n -1 --force -f /run/ddns-eth4-inadyn.conf
```
3. Check `/var/log/messages` for errors.

### **USG Testing**
1. SSH into your USG.
2. Run:
```sh
sudo ddclient -daemon=0 -verbose -noquiet -debug -file /etc/ddclient/ddclient_eth0.conf
```
3. Look for `SUCCESS` in the output.

---

## ⚠️ **Important Notes**

- Updates occur approximately every two minutes. You can tail the worker logs to validate updates from your UniFi device.
- For **subdomains** (`sub.example.com`), manually create an A record in Cloudflare first.
- Remove `https://` from the **Server** field.
- **Wildcard domains:** Use `*.example.com` in the **Hostname** field.
- UniFi OS may require recreating DDNS entries instead of editing them.
Loading

0 comments on commit ed6298e

Please sign in to comment.