docs/ is gitignored; references to docs/implementation/*.md from public
source, configs, and packaging were dead links outside the maintainer
machine. Adds four recipes (README, dnsdist-front, doh-on-lan,
odoh-upstream) under top-level recipes/ and repoints existing pointers.
- numa.toml, packaging/client/{README.md,numa.toml}: point to
recipes/odoh-upstream.md.
- src/{bootstrap_resolver,forward,serve}.rs: reference issue #122
directly (module scope is broader than the ODoH-specific recipe).
- src/health.rs: drop the §-ref; iOS HealthInfo remains named as the
canonical consumer.
73 lines
2.4 KiB
Markdown
73 lines
2.4 KiB
Markdown
# Numa ODoH Client — Docker deploy
|
|
|
|
Single-container deploy that runs Numa as an ODoH (RFC 9230) client: every
|
|
DNS query routes through an independent relay + target so neither operator
|
|
sees both your IP and your question. See the [ODoH upstream recipe][odoh]
|
|
for the protocol details and the bootstrap-pinning trade-offs.
|
|
|
|
[odoh]: ../../recipes/odoh-upstream.md
|
|
|
|
## Prerequisites
|
|
|
|
- Docker + Docker Compose v2.
|
|
- Port 53 (UDP+TCP) free on the host — Numa listens there for DNS
|
|
clients on your LAN.
|
|
|
|
## Configure
|
|
|
|
The shipped `numa.toml` points at Numa's own public relay
|
|
(`odoh-relay.numa.rs`) paired with Cloudflare's ODoH target
|
|
(`odoh.cloudflare-dns.com`). That's two independent operators with
|
|
distinct eTLD+1s — the default configuration passes Numa's same-operator
|
|
check and works out of the box.
|
|
|
|
To use a different relay or target, edit `numa.toml` and adjust the URLs.
|
|
The `relay` and `target` must resolve to distinct operators or Numa
|
|
refuses to start.
|
|
|
|
## Deploy
|
|
|
|
```sh
|
|
docker compose up -d
|
|
docker compose logs -f numa # watch startup
|
|
```
|
|
|
|
The first query fires the bootstrap resolver + ODoH config fetch;
|
|
subsequent queries reuse the warm HTTP/2 connection.
|
|
|
|
## Point your devices at it
|
|
|
|
Set each device's DNS server to the IP of the Docker host. For a LAN-wide
|
|
rollout, set the DNS server in your router's DHCP config so every device
|
|
picks it up automatically.
|
|
|
|
Verify a query landed on the ODoH path:
|
|
|
|
```sh
|
|
dig @<host-ip> example.com
|
|
curl http://<host-ip>:5380/stats | jq '.upstream_transport.odoh'
|
|
```
|
|
|
|
`upstream_transport.odoh` should increment on each query.
|
|
|
|
## What this does NOT buy you
|
|
|
|
ODoH protects the *path*, not the content:
|
|
|
|
- **The target (Cloudflare here) still sees the question.** It just
|
|
doesn't know it's you asking. If Cloudflare logs every ODoH query, the
|
|
query is still visible — it's simply unattributed.
|
|
- **The relay is a trusted party for availability.** A malicious relay
|
|
can drop or delay queries; it just can't read them.
|
|
- **Traffic analysis defeats small relays.** If you're the only client
|
|
talking to a relay, timing alone re-identifies you. Shared, busy relays
|
|
give better anonymity sets.
|
|
|
|
See the [ODoH integration doc][odoh] for more.
|
|
|
|
## Relay operator?
|
|
|
|
If you'd rather run your own relay (same binary, different mode), see
|
|
[`../relay/`](../relay/) — that package spins up a public-facing relay
|
|
with Caddy + ACME in front of it.
|