diff --git a/README.md b/README.md index 4aef1dd..4fd1b5c 100644 --- a/README.md +++ b/README.md @@ -221,6 +221,21 @@ dig +https @dns1.slowb.ro . NS # compare against opennic.hints dig +https @dns1.slowb.ro . DNSKEY # compare the KSK (flags 257) against opennic.key ``` +## Cache TTL + +To reduce the load on authoritative servers and keep responses fast, answers +are cached for at least one hour, even when their TTL is shorter. The downside +is that changes to records with short TTLs can take an hour or more to be +visible to clients. + +The minimum can be changed with the `CACHE_MIN_TTL` environment variable, in +seconds, from `0` to `86400` (add `-e CACHE_MIN_TTL=60` to the `docker run` +command). `CACHE_MIN_TTL=0` honors the TTLs set by the zone owners. Without +the variable, the one-hour default is used. + +The value applies to both the Unbound cache and the encrypted-dns cache, and is +applied every time the container starts. + # Join the network If you want to help against DNS centralization and surveillance, diff --git a/entrypoint.sh b/entrypoint.sh index 763d593..d0dbb9c 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -167,8 +167,29 @@ ensure_initialized() { fi } +apply_cache_min_ttl() { + cache_min_ttl=$(printf '%s\n' "${CACHE_MIN_TTL:-3600}" | sed 's/^0*\([0-9]\)/\1/') + case "$cache_min_ttl" in + *[!0-9]* | ??????*) cache_min_ttl_valid=0 ;; + *) cache_min_ttl_valid=1 ;; + esac + if [ "$cache_min_ttl_valid" = 0 ] || [ "$cache_min_ttl" -gt 86400 ]; then + echo "CACHE_MIN_TTL must be a number of seconds between 0 and 86400, not [${CACHE_MIN_TTL}]" >&2 + exit 1 + fi + if grep -qE '^[[:space:]]*cache_ttl_min[[:space:]]*=' "$CONFIG_FILE"; then + if ! grep -qE "^cache_ttl_min = ${cache_min_ttl}\$" "$CONFIG_FILE"; then + sed -i -E "s/^[[:space:]]*cache_ttl_min[[:space:]]*=.*/cache_ttl_min = ${cache_min_ttl}/" "$CONFIG_FILE" + fi + elif [ -n "${CACHE_MIN_TTL:-}" ]; then + echo "No cache_ttl_min setting in [${CONFIG_FILE}], leaving the encrypted-dns cache unchanged" >&2 + fi + CACHE_MIN_TTL=$cache_min_ttl +} + start() { ensure_initialized + apply_cache_min_ttl fix_key_ownership if [ -f "${KEYS_DIR}/secret.key" ]; then echo "Importing the previous secret key [${KEYS_DIR}/secret.key]" @@ -187,8 +208,9 @@ start() { done # runit wipes the environment before running services, so persist - # settings that service scripts need to a file. + # settings that service scripts need to files. printf '%s\n' "${OPENNIC:-}" >/etc/opennic-env + printf '%s\n' "${CACHE_MIN_TTL:-}" >/etc/cache-min-ttl-env exec /etc/runit/2 /dev/null 2>/dev/null } diff --git a/unbound.sh b/unbound.sh index c986955..e444ccc 100755 --- a/unbound.sh +++ b/unbound.sh @@ -27,9 +27,18 @@ case "${OPENNIC:-}" in 1 | true | yes | on) opennic_enabled=1 ;; esac +if [ -z "${CACHE_MIN_TTL:-}" ] && [ -f /etc/cache-min-ttl-env ]; then + CACHE_MIN_TTL=$(cat /etc/cache-min-ttl-env) +fi +case "${CACHE_MIN_TTL:-}" in +"" | *[!0-9]*) cache_min_ttl=3600 ;; +*) cache_min_ttl=$CACHE_MIN_TTL ;; +esac + provider_name=$(cat "$KEYS_DIR/provider_name") sed \ + -e "s/@CACHE_MIN_TTL@/${cache_min_ttl}/" \ -e "s/@MSG_CACHE_SIZE@/${msg_cache_size}/" \ -e "s/@PROVIDER_NAME@/${provider_name}/" \ -e "s/@RR_CACHE_SIZE@/${rr_cache_size}/" \ @@ -43,7 +52,7 @@ server: so-reuseport: yes edns-buffer-size: 1232 delay-close: 10000 - cache-min-ttl: 3600 + cache-min-ttl: @CACHE_MIN_TTL@ cache-max-ttl: 86400 do-daemonize: no username: "_unbound"