diff --git a/packaging/relay/Caddyfile b/packaging/relay/Caddyfile new file mode 100644 index 0000000..ea368c8 --- /dev/null +++ b/packaging/relay/Caddyfile @@ -0,0 +1,15 @@ +odoh-relay.example.com { + handle /relay { + reverse_proxy numa-relay:8443 + } + handle /health { + reverse_proxy numa-relay:8443 + } + respond 404 + + # Per-request access logs defeat the point of an oblivious relay. + # Aggregate counters are exposed at /health on the relay itself. + log { + output discard + } +} diff --git a/packaging/relay/README.md b/packaging/relay/README.md new file mode 100644 index 0000000..373b263 --- /dev/null +++ b/packaging/relay/README.md @@ -0,0 +1,48 @@ +# Numa ODoH Relay — Docker deploy + +Two-container deploy: Caddy terminates TLS (auto-provisioning a Let's Encrypt +cert via ACME) and reverse-proxies to a Numa relay running on an internal +Docker network. The relay never reads sealed payloads; Caddy never logs them. + +## Prerequisites + +- A host with public 80/443 reachable from the internet. +- A DNS record (`A` or `AAAA`) pointing your chosen hostname at the host. +- Docker + Docker Compose v2. + +## Configure + +Edit `Caddyfile` and replace `odoh-relay.example.com` with your hostname. +That hostname is what ACME validates against and what ODoH clients will +configure as their relay URL: `https:///relay`. + +## Deploy + +```sh +docker compose up -d +docker compose logs -f caddy # watch ACME provisioning +``` + +First boot takes a few seconds while Caddy obtains the cert. Subsequent +restarts reuse the cached cert from the `caddy_data` volume. + +## Verify + +```sh +curl https:///health +# ok +# total 0 +# forwarded_ok 0 +# forwarded_err 0 +# rejected_bad_request 0 +``` + +Then point any ODoH client at `https:///relay` and watch the +counters tick. + +## Listing on the public ecosystem + +DNSCrypt's [v3/odoh-relays.md](https://github.com/DNSCrypt/dnscrypt-resolvers/blob/master/v3/odoh-relays.md) +is the canonical list. The pruned 2025-09-16 commit shows one public ODoH +relay survived the cull — running this compose file doubles global supply. +Open a PR there once your relay has been up for ~24 hours. diff --git a/packaging/relay/docker-compose.yml b/packaging/relay/docker-compose.yml new file mode 100644 index 0000000..9561535 --- /dev/null +++ b/packaging/relay/docker-compose.yml @@ -0,0 +1,26 @@ +services: + numa-relay: + image: ghcr.io/razvandimescu/numa:latest + command: ["relay", "8443", "0.0.0.0"] + restart: unless-stopped + networks: [internal] + + caddy: + image: caddy:2 + ports: + - "80:80" + - "443:443" + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile:ro + - caddy_data:/data + - caddy_config:/config + restart: unless-stopped + depends_on: [numa-relay] + networks: [internal] + +networks: + internal: + +volumes: + caddy_data: + caddy_config: