Files
unbound-docker/docker-compose.test.yml
T
Kyle Harding e31f1e27e2 Assert ECS config locally rather than via an authority
My previous change did not fix the flake, it moved it. Asserting on a
CLIENT-SUBNET option in the client's answer still depends on whether the
authority echoes ECS back, which is the same coin flip the original
`grep edns0-client-subnet` rode on. Two runs of that assertion, same
branch, minutes apart: amd64 saw `answer has edns subnet 203.0.113.0/24`
twice and passed, arm64 saw it zero times and failed.

Two mistakes. 203.0.113.0/24 is TEST-NET-3, so it is no more routable
than the RFC1918 address it replaced and authorities decline it just the
same -- the failing job still got "edns0-client-subnet was not used".
And unbound does not echo CLIENT-SUBNET to a client that sent one in
general: subnetmod.c gates that on the client having sent a /0 prefix, so
with a /24 the generate_lookup_without_subnet() fallback returns the
answer with no option at all.

There is no client-visible ECS signal that survives an authority
declining, so assert only local state: the build links subnetcache, the
mounted example config puts it in the module chain, and send-client-subnet
was parsed. The active unbound.conf sets no module-config, so
"init module 0: subnetcache" appears only when the example file loaded --
which is what this test existed to check.

Verified by matching each pattern against captured output from seven real
jobs, across four platforms and unbound 1.25.2 and 1.26.0, passing and
failing. Testing an actual round-trip would need an authoritative server
in the compose file; that is a larger change than this test has had.

Signed-off-by: Kyle Harding <kyle@balena.io>
2026-08-10 18:07:51 -04:00

69 lines
3.2 KiB
YAML

services:
server:
image: localhost:5000/sut
build:
context: .
dockerfile: Dockerfile
volumes:
# enable send-client-subnet example configuration file
- ./rootfs_overlay/etc/unbound/custom.conf.d/send-client-subnet.conf.example:/etc/unbound/custom.conf.d/send-client-subnet.conf:ro
# enable custom-port example configuration file
- ./rootfs_overlay/etc/unbound/custom.conf.d/custom-port.conf.example:/etc/unbound/custom.conf.d/custom-port.conf:ro
# enable remote-control example configuration file
- ./rootfs_overlay/etc/unbound/custom.conf.d/remote-control.conf.example:/etc/unbound/custom.conf.d/remote-control.conf:ro
command: -v -v
sut:
image: alpine:3.24@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b
depends_on:
- server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
working_dir: /test
entrypoint:
- /bin/sh
- -c
command:
- |
set -ex
apk add --no-cache bind-tools docker-cli
server_ip="$$(dig +short server | tail -n 1)"
while read id
do
if docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $${id} | grep -q "$${server_ip}"
then
server_id="$${id}"
break
fi
done < <(docker ps --format '{{.ID}}')
docker exec $${server_id} unbound -V
docker exec $${server_id} unbound-checkconf
docker exec $${server_id} unbound-anchor -v
docker exec $${server_id} drill -v
sleep 5
docker exec $${server_id} drill-hc -p 5353 dnssec.works @127.0.0.1 | tee /dev/stderr | grep NOERROR
! docker exec $${server_id} drill-hc -p 5353 foo.local @127.0.0.1 | tee /dev/stderr | grep NOERROR
! docker exec $${server_id} drill-hc -p 5353 bar.local @127.0.0.1 | tee /dev/stderr | grep NOERROR
dig @server -p 5353 dnssec.works +dnssec +multi | tee /dev/stderr | grep NOERROR
! dig @server -p 5353 fail01.dnssec.works +dnssec +multi | tee /dev/stderr | grep NOERROR
! dig @server -p 5353 fail02.dnssec.works +dnssec +multi | tee /dev/stderr | grep NOERROR
! dig @server -p 5353 fail03.dnssec.works +dnssec +multi | tee /dev/stderr | grep NOERROR
! dig @server -p 5353 fail04.dnssec.works +dnssec +multi | tee /dev/stderr | grep NOERROR
# Check the subnet module is built in and the send-client-subnet example
# config is active. A real ECS round-trip is deliberately not asserted
# here: authorities refuse non-routable prefixes, and whether they echo
# the option back varies between anycast instances. When they do not
# echo it, unbound re-resolves without the subnet and the answer reaches
# the client with no CLIENT-SUBNET option, so every client-visible ECS
# assertion is a coin flip. Testing the round-trip needs an
# authoritative server we control.
docker exec $${server_id} unbound -V | grep 'Linked modules:.*subnetcache'
docker logs $${server_id} 2>&1 | grep 'init module 0: subnetcache'
docker logs $${server_id} 2>&1 | grep 'send-client-subnet: 0\.0\.0\.0/0'