Local tools: an unpacked Chrome extension for daily site jobs, and a Cloudflare DDNS client plus Worker.
| Path | What it is |
|---|---|
userscripts/ |
One unpacked Chrome/Chromium extension |
ddns/ |
Go client + Cloudflare Worker that keeps a DNS record on a changing IP |
- Clone this repository.
- Chrome →
chrome://extensions→ Developer mode → Load unpacked → selectuserscripts/extension/. - Copy
userscripts/config.example.yamltouserscripts/extension/config.yamland fill notify, ingest, and site cadence there. Reload the unpacked extension after edits.
| Site | What it does |
|---|---|
| linux.do | Three random browse sessions per day; like cap 2 |
| nodeseek.com | Daily check-in while logged in |
| member.expireddomains.net | Run saved searches in this tab (5 pages each) and POST rows to a local URL |
Stay time, like cap, NodeSeek check-in, and ExpiredDomains pages live in config.yaml. Ingest POSTs only to 127.0.0.1 or ::1. Alerts go through the notify adapter in that file. One job at a time: the extension opens its own tab, then closes it.
The older .user.js files are still under userscripts/ if you prefer a userscript manager.
cd userscripts && node --test test/*.test.jsKeep a Cloudflare DNS record pointed at a machine whose public IP changes. A small Worker receives updates. A Go client on the machine looks up its public IP and reports in. The client checks often locally and only contacts the Worker when the address changes, or on a heartbeat (default 10 minutes).
Needs Node.js 20+ and a Cloudflare account with permission to edit DNS.
git clone https://github.com/fennlee/mytools.git
cd mytools/ddns/worker
npx wrangler deploy
npx wrangler secret put CF_API_TOKEN
npx wrangler secret put DDNS_HOSTSCF_API_TOKEN is a Cloudflare API token that can edit DNS in the zone.
DDNS_HOSTS is a JSON array (see ddns/examples/hosts.json):
[
{
"id": "home",
"secret": "a-long-random-string",
"zone_id": "0123456789abcdef0123456789abcdef",
"name": "home.example.com",
"ttl": 120,
"proxied": false
}
]Set proxied to false when the name should resolve to the machine itself. Orange-cloud records hide the origin IP.
GET /health on the Worker URL should return {"ok":true}.
Needs Go 1.24+:
cd ddns/client
go build -o ddns-client ./cmd/ddns-client
sudo install -m 755 ddns-client /usr/local/bin/ddns-client
sudo mkdir -p /etc/ddns /var/lib/ddns
sudo cp ../examples/config.json /etc/ddns/config.jsonEdit /etc/ddns/config.json so endpoint is your Worker URL plus /v1/update. Put the same secret as in DDNS_HOSTS in a file:
sudo install -m 600 /dev/null /etc/ddns/secret
sudo tee /etc/ddns/secret >/dev/null
# paste the secret, then Ctrl-DOne-shot check:
ddns-client -once -config /etc/ddns/config.jsonsystemd unit: ddns/examples/ddns-client.service.
| Field | Default | Meaning |
|---|---|---|
endpoint |
required | POST URL, usually https://…workers.dev/v1/update |
secret_file |
— | path to the report secret (chmod 600) |
secret |
— | secret inline (prefer secret_file) |
interval |
10m |
heartbeat if the IP has not changed |
check_interval |
30s |
how often to look up the public IP locally |
cache_path |
/var/lib/ddns/last-ip |
last address that was accepted |
ip_urls |
ipify / ifconfig.me / icanhazip | HTTP sources for the public IP |
timeout |
8s |
per-request timeout |
Environment variables override the file: DDNS_ENDPOINT, DDNS_SECRET, DDNS_SECRET_FILE, DDNS_INTERVAL, DDNS_CHECK_INTERVAL, DDNS_CACHE_PATH, DDNS_TIMEOUT, DDNS_CONFIG.
cd ddns/worker && node --test src/*.test.js
cd ../client && go test ./...userscripts/— GPL-3.0-or-later. The NodeSeek check-in path is derived from NodeSeekXsignIn.js(GPL-3.0).ddns/— MIT.