Omdat ik zelf eerder niet veel vond van praktische voorbeelden rond het API gebruikt bij mijn.host :
Ik heb nu een pfsense script om via cron de API aan te spreken en een DDNS host van mijn.host up-to-date te houden.
Gebruik om een A record te updaten, hier cloud.example.nl van het domain example.nl
/root/mijnhost-ddns.sh -k 'API-key' -d example.nl -r cloud.example.nl -t A
Dit script update alleen een mijn.host record als de WAN IP gewijzigd is.
Je krijgt ook een lijntje in de logfiles van pfsense.
Je kan het script meerdere keren in cron zetten als je meer dan één record wil updaten,
alle andere bestaande records/hosts in mijn.host configuratie worden dus niet aangepast of gewist.
#!/bin/sh
set -eu
API_BASE="https://mijn.host/api/v2"
TTL=300 # 5 minutes
MAX_DELAY_SEC=20 # 0–20 sec random delay
log() {
logger -t mijnhost-ddns "$1"
}
usage() {
cat <<EOF
Usage:
$0 -k api_key -d domain.tld -r host.domain.tld [-t A|AAAA] [-l ttl]
Examples:
$0 -k 'APIKEY' -d example.nl -r cloud.example.nl -t A
$0 -k 'APIKEY' -d example.nl -r cloud.example.nl -t AAAA
EOF
exit 1
}
API_KEY=""
DOMAIN=""
FQDN=""
RECORD_TYPE="A"
MANUAL_TTL=""
while getopts "k:d:r:t:l:" opt; do
case "$opt" in
k) API_KEY="$OPTARG" ;;
d) DOMAIN="$OPTARG" ;;
r) FQDN="$OPTARG" ;;
t) RECORD_TYPE="$OPTARG" ;;
l) MANUAL_TTL="$OPTARG" ;;
*) usage ;;
esac
done
[ -n "$API_KEY" ] || usage
[ -n "$DOMAIN" ] || usage
[ -n "$FQDN" ] || usage
if [ -n "$MANUAL_TTL" ]; then
TTL="$MANUAL_TTL"
fi
detect_wan_if() {
route -n get default 2>/dev/null | awk '/interface:/{print $2; exit}'
}
get_ip_for_if() {
iface="$1"
case "$RECORD_TYPE" in
A)
ifconfig "$iface" 2>/dev/null | awk '/inet / {print $2; exit}'
;;
AAAA)
ifconfig "$iface" 2>/dev/null | awk '/inet6 / && $2 !~ /^fe80:/ {print $2; exit}'
;;
esac
}
WAN_IF="$(detect_wan_if || true)"
[ -n "$WAN_IF" ] || { log "Could not detect active WAN interface"; exit 1; }
WAN_IP="$(get_ip_for_if "$WAN_IF" || true)"
[ -n "$WAN_IP" ] || { log "Could not detect $RECORD_TYPE address on $WAN_IF"; exit 1; }
STATE_FILE="/var/db/mijnhost-${DOMAIN}-${FQDN}-${RECORD_TYPE}.state"
mkdir -p /var/db
if [ -f "$STATE_FILE" ] && [ "$(cat "$STATE_FILE" 2>/dev/null || true)" = "$WAN_IP" ]; then
log "No change for $FQDN ($WAN_IP)"
exit 0
fi
# Random delay 0–$MAX_DELAY_SEC seconds
RANDOM_DELAY_SEC=$(expr $(od -An -N2 -tu2 /dev/urandom) % $MAX_DELAY_SEC + 1)
sleep "$RANDOM_DELAY_SEC"
payload=$(cat <<EOF
{
"record": {
"type": "$RECORD_TYPE",
"name": "$FQDN",
"value": "$WAN_IP",
"ttl": $TTL
}
}
EOF
)
response="$(curl --silent --show-error \
--request PATCH "$API_BASE/domains/$DOMAIN/dns" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "API-Key: $API_KEY" \
--data "$payload" 2>&1)" || {
log "Update failed for $FQDN: $response"
exit 1
}
printf '%s' "$WAN_IP" > "$STATE_FILE"
log "Updated $FQDN ($WAN_IP, TTL $TTL, delay $RANDOM_DELAY_SEC s) via $WAN_IF"