diff --git a/scripts/prepare-zones.sh b/scripts/prepare-zones.sh index da09310..e2f088a 100755 --- a/scripts/prepare-zones.sh +++ b/scripts/prepare-zones.sh @@ -17,9 +17,37 @@ set -euo pipefail SRC_DIR="${SRC_DIR:-zones}" DST_DIR="${DST_DIR:-zones-prepared}" -SERIAL="${SERIAL:-$(date +%Y%m%d)01}" ADMIN_EMAIL="${ADMIN_EMAIL:-admin}" # becomes admin.. +# Serial number generation — YYYYMMDDNN format (RFC 1912 §2.2). +# +# Strategy: every `make prep` run produces a strictly-increasing serial +# so that HE slaves notice the change on their next poll. If today's +# previous serials exist in zones-prepared/, increment the 2-digit +# counter. Otherwise start at NN=01. +# +# Honors an explicit override: `SERIAL=2026051699 make prep` skips the +# auto-detection. +TODAY=$(date +%Y%m%d) +if [[ -z "${SERIAL:-}" ]]; then + # Pull the highest YYYYMMDDNN serial from currently-prepared zones + # that starts with today's date. If none, default to NN=01. + highest=$(grep -hE '^[[:space:]]+'"${TODAY}"'[0-9]{2}[[:space:]]+;' "$DST_DIR"/*.zone 2>/dev/null \ + | awk '{print $1}' | sort -un | tail -1) + if [[ -n "$highest" ]]; then + nn=$((10#${highest:8:2})) + next_nn=$((nn + 1)) + if (( next_nn > 99 )); then + echo "ERROR: serial counter exhausted for ${TODAY} (NN=99 reached)." >&2 + echo "Set SERIAL manually or wait until tomorrow." >&2 + exit 1 + fi + SERIAL=$(printf "%s%02d" "$TODAY" "$next_nn") + else + SERIAL="${TODAY}01" + fi +fi + # Public-facing nameservers (Hurricane Electric free secondary service). # These appear in NS records inside every zone so that recursive # resolvers fetching the zone learn the correct delegation.