# 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
