Skip to content

Architectuur

Geert van Zoest edited this page Mar 31, 2026 · 2 revisions

Architectuur

Overzicht

azure-ddns is een single-file bash script (267 regels) dat in één run:

  1. Configuratie valideert (7 env vars + jq)
  2. OAuth2 token ophaalt bij Azure Entra ID
  3. Publiek IP detecteert via externe service
  4. Huidig DNS A-record ophaalt via Azure REST API
  5. A-record update als het IP gewijzigd is

Flow diagram

┌─────────────┐
│  cron start │
└──────┬──────┘
       │
       ▼
┌──────────────┐    lock bezet
│ flock check  │───────────────► exit 0 (skip)
└──────┬───────┘
       │ lock vrij
       ▼
┌──────────────┐    vars ontbreken
│validate_config│──────────────► exit 1
└──────┬───────┘
       │ ok
       ▼
┌──────────────┐    HTTP != 200
│get_access_   │──────────────► exit 3
│token         │
└──────┬───────┘
       │ token
       ▼
┌──────────────┐    alle services falen
│get_public_ip │──────────────► exit 2
└──────┬───────┘
       │ IP
       ▼
┌──────────────┐    HTTP error
│get_dns_record│──────────────► exit 4
└──────┬───────┘
       │ huidig IP
       ▼
┌──────────────┐    IP gelijk + geen --force
│  vergelijk   │──────────────► exit 0 (skip)
└──────┬───────┘
       │ IP verschilt / --force
       ▼
┌──────────────┐    HTTP error
│  update_dns  │──────────────► exit 4
└──────┬───────┘
       │ 200/201
       ▼
    exit 0 (ok)

Functies

Functie Doel Input Output
log() Gestructureerd loggen level, message stdout of stderr
debug() Conditional logging message stdout (alleen als VERBOSE=1)
parse_args() CLI argument parsing $@ zet FORCE=1 bij --force
validate_config() Env vars + jq check 7 env vars exit 1 bij ontbrekend
get_access_token() OAuth2 token tenant, client, secret access token via echo
get_public_ip() Publiek IP detectie IP_SERVICES array IPv4 adres via echo
get_dns_record() Huidig A-record access token IP of lege string via echo
update_dns() DNS PUT access token, IP log succes of exit 4
main() Orchestratie $@ exit code 0-4

Externe services

IP-detectie (cascade)

Prioriteit Service Eigenaar URL
1 (primair) icanhazip.com Cloudflare https://icanhazip.com
2 (fallback) checkip.amazonaws.com Amazon AWS https://checkip.amazonaws.com

Als de primaire service faalt (timeout, HTTP error, ongeldig IP), probeert het script automatisch de volgende. Pas als alle services falen: exit 2.

Azure REST API

Operatie Endpoint API versie
Token login.microsoftonline.com/{tenant}/oauth2/v2.0/token
GET record management.azure.com/.../dnsZones/{zone}/A/{record} 2018-05-01
PUT record management.azure.com/.../dnsZones/{zone}/A/{record} 2018-05-01

Security

  • Geen secrets in het script — alle credentials via environment variables
  • AZURE_CLIENT_SECRET wordt expliciet uitgesloten van verbose debug output
  • OAuth2 scope is beperkt tot https://management.azure.com/.default
  • RBAC moet beperkt zijn tot DNS Zone Contributor op de specifieke zone (niet subscription-breed)
  • Lock file in /tmp/azure-ddns.lock — voorkomt gelijktijdige uitvoering

Bestanden

azure-ddns                          # Hoofdscript (267 regels)
test/
  test_helper.bash              # Gemeenschappelijke test setup
  test_ip_validation.bats       # 8 tests — IPv4 regex
  test_ip_fallback.bats         # 4 tests — service cascade
  test_force_flag.bats          # 4 tests — --force parsing
  test_verbose.bats             # 4 tests — VERBOSE=1
  test_ttl.bats                 # 4 tests — DNS_TTL config
  test_locking.bats             # 3 tests — flock locking
.github/workflows/test.yml     # CI pipeline
README.md                       # Gebruikersdocumentatie

Clone this wiki locally