87 lines
2.5 KiB
Markdown
87 lines
2.5 KiB
Markdown
## DNSMasq divergence testbed
|
|
|
|
This project spins up one `dnsmasq` in front of four backend DNS servers (CoreDNS). Each backend returns a different A record for the same name so you can observe how `dnsmasq` behaves when upstreams disagree.
|
|
|
|
### Topology
|
|
|
|
- **dnsmasq**: listens on host UDP/TCP `5353`, forwards to backends at `192.168.243.11-14`
|
|
- **backend1..backend4 (CoreDNS)**: each serves a different answer for `test.local`:
|
|
- backend1 → `10.0.0.1`
|
|
- backend2 → `10.0.0.2`
|
|
- backend3 → `10.0.0.3`
|
|
- backend4 → `10.0.0.4`
|
|
|
|
Custom bridge network: `192.168.243.0/24` with static IPs for reproducibility.
|
|
|
|
### Files
|
|
|
|
- `docker-compose.yaml`: services and fixed IP networking
|
|
- `dnsmasq/dnsmasq.conf`: forwards to all four backends, logging enabled, caching enabled
|
|
- `backends/backend*/Corefile`: CoreDNS configs returning distinct answers
|
|
|
|
### Run
|
|
|
|
```bash
|
|
docker compose -f /home/akos/docker/dnsmasq/docker-compose.yaml up -d
|
|
```
|
|
|
|
Wait a few seconds until all containers are healthy.
|
|
|
|
### Test from the host
|
|
|
|
Query via `dnsmasq` on port 5353:
|
|
|
|
```bash
|
|
dig @127.0.0.1 -p 5353 test.local A +short
|
|
```
|
|
|
|
Run several times to observe responses and `dnsmasq` caching behavior. You should see one of: `10.0.0.1`, `10.0.0.2`, `10.0.0.3`, `10.0.0.4`.
|
|
|
|
### Test from within the dnsmasq container (optional)
|
|
|
|
The `andyshinn/dnsmasq` image is Alpine-based; install `dig` temporarily:
|
|
|
|
```bash
|
|
docker exec -it dnsmasq sh -c "apk add --no-cache bind-tools >/dev/null && dig @127.0.0.1 test.local A +short"
|
|
```
|
|
|
|
### Inspect logs
|
|
|
|
`dnsmasq` query logging is enabled:
|
|
|
|
```bash
|
|
docker logs -f dnsmasq
|
|
```
|
|
|
|
### Adjusting behavior
|
|
|
|
To explore how `dnsmasq` handles disagreement:
|
|
|
|
- **Disable cache** (no stored answers): set `cache-size=0` in `dnsmasq/dnsmasq.conf`, then recreate the service.
|
|
- **Force first-server order**: add `strict-order` to `dnsmasq/dnsmasq.conf` so servers are queried in listed order.
|
|
- **Query all upstreams**: add `all-servers` so `dnsmasq` queries every upstream in parallel and picks the first reply.
|
|
|
|
Apply changes by recreating the service:
|
|
|
|
```bash
|
|
docker compose -f /home/akos/docker/dnsmasq/docker-compose.yaml up -d --force-recreate dnsmasq
|
|
```
|
|
|
|
### Resetting the cache
|
|
|
|
```bash
|
|
docker restart dnsmasq
|
|
```
|
|
|
|
### Clean up
|
|
|
|
```bash
|
|
docker compose -f /home/akos/docker/dnsmasq/docker-compose.yaml down -v
|
|
```
|
|
|
|
### Notes
|
|
|
|
- The backends are simple CoreDNS instances using the `hosts` plugin for `test.local`; unknown names forward to public resolvers.
|
|
- The compose file exposes `53/udp` and `53/tcp` on host port `5353` to avoid clashing with any local resolver.
|
|
|