154 lines
3.3 KiB
Markdown
154 lines
3.3 KiB
Markdown
# ddns-updater
|
||
|
||
A small Go daemon that keeps Cloudflare A records in sync with your current public IPv4 address.
|
||
It reads a YAML config, checks your IP periodically, compares it to existing DNS records, and only updates when needed.
|
||
|
||
## Features
|
||
|
||
- Uses Cloudflare API token (modern auth)
|
||
- Supports multiple subdomains in one zone
|
||
- IPv4 only (A records)
|
||
- User-defined check interval (minutes)
|
||
- Retries on failure, then logs and skips
|
||
- Structured JSON logging to file
|
||
|
||
## Requirements
|
||
|
||
- Go 1.21+ (tested with 1.23)
|
||
- A Cloudflare account
|
||
- API token with:
|
||
- Zone:DNS:Edit
|
||
- Zone:Zone:Read
|
||
- Existing zone and A records for your subdomains
|
||
|
||
## Installation
|
||
|
||
```bash
|
||
# 1. Create project directory
|
||
mkdir ddns-updater
|
||
cd ddns-updater
|
||
|
||
# 2. Initialize module
|
||
go mod init github.com/yourname/ddns-updater
|
||
|
||
# 3. Add files
|
||
# - main.go
|
||
# - config.yaml
|
||
# - (this README.md)
|
||
|
||
# 4. Fetch dependencies
|
||
go mod tidy
|
||
|
||
# 5. Build binary (current platform)
|
||
go build -o ddns-updater
|
||
|
||
# 6. Build for Linux (LXC, etc.)
|
||
GOOS=linux GOARCH=amd64 go build -o ddns-updater-linux
|
||
```
|
||
|
||
Copy the resulting binary and `config.yaml` onto your target machine or LXC container, e.g. `/opt/ddns-updater`.
|
||
|
||
## Configuration
|
||
|
||
Create `config.yaml` in the same directory as the binary:
|
||
|
||
```yaml
|
||
check_interval: 5 # minutes (e.g. 5, 15, 30)
|
||
|
||
cloudflare:
|
||
api_token: "YOUR_CF_API_TOKEN"
|
||
zone_id: "YOUR_ZONE_ID"
|
||
subdomains:
|
||
- name: "lc"
|
||
proxied: false
|
||
- name: "git"
|
||
proxied: false
|
||
- name: "mempool"
|
||
proxied: false
|
||
|
||
logging:
|
||
file: "ddns-updater.log"
|
||
level: "info" # debug, info, warn, error
|
||
|
||
retry:
|
||
max_attempts: 3
|
||
delay_seconds: 5
|
||
|
||
webhook:
|
||
enabled: false
|
||
url: ""
|
||
```
|
||
|
||
- `check_interval`: how often to check your current IP (in minutes).
|
||
- `subdomains`: just the left part of the name (e.g. `git` for `git.example.com`).
|
||
- `proxied`: `true` for orange-cloud (proxied), `false` for DNS only.
|
||
- `logging.file`: log file path, relative to the working directory.
|
||
- `retry`: per-subdomain retry behavior when the Cloudflare API or network fails temporarily.
|
||
|
||
## Usage
|
||
|
||
### Direct run
|
||
|
||
From the directory containing the binary and `config.yaml`:
|
||
|
||
```bash
|
||
./ddns-updater
|
||
```
|
||
|
||
The process will:
|
||
|
||
1. Load `config.yaml`.
|
||
2. Detect current public IPv4 using external services.
|
||
3. For each subdomain:
|
||
- Fetch its current A record from Cloudflare.
|
||
- If the IP differs, update the record.
|
||
4. Sleep for `check_interval` minutes and repeat.
|
||
5. Log events to `ddns-updater.log`.
|
||
|
||
### Run in background (simple)
|
||
|
||
```bash
|
||
nohup ./ddns-updater >/dev/null 2>&1 &
|
||
```
|
||
|
||
### Example systemd service (on Linux/LXC)
|
||
|
||
Create `/etc/systemd/system/ddns-updater.service`:
|
||
|
||
```ini
|
||
[Unit]
|
||
Description=Cloudflare DDNS Updater
|
||
After=network-online.target
|
||
Wants=network-online.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
WorkingDirectory=/opt/ddns-updater
|
||
ExecStart=/opt/ddns-updater/ddns-updater
|
||
Restart=on-failure
|
||
RestartSec=10
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
```
|
||
|
||
Then:
|
||
|
||
```bash
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable ddns-updater
|
||
sudo systemctl start ddns-updater
|
||
sudo systemctl status ddns-updater
|
||
```
|
||
|
||
Logs will go to `ddns-updater.log` in `/opt/ddns-updater` plus systemd’s journal.
|
||
|
||
## Updating
|
||
|
||
To update the binary:
|
||
|
||
```bash
|
||
git pull # if you put it in a repo
|
||
go build -o ddns-updater
|
||
sudo systemctl restart ddns-updater
|