From f10ef5b6bd3e342826ea28aaee10a9654a6d67c8 Mon Sep 17 00:00:00 2001 From: Mohammadreza Khani Date: Mon, 6 Jul 2026 17:16:11 +0330 Subject: [PATCH] docs: add README with usage, config, and API reference --- README.md | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a46802 --- /dev/null +++ b/README.md @@ -0,0 +1,160 @@ +# doh-forwarder + +A lightweight DNS-over-HTTPS (DoH) forwarder written in Rust. + +Accepts DNS queries over HTTPS ([RFC 8484](https://www.rfc-editor.org/rfc/rfc8484)) and forwards them to upstream DoH resolvers (Cloudflare, Google, Quad9, or custom). + +## Features + +- **RFC 8484 compliant** — GET (`?dns=base64url`) and POST (`application/dns-message`) +- **Multiple upstreams** — configure several DoH resolvers +- **Selection strategies** — round-robin or failover +- **In-memory cache** — TTL-aware with LRU eviction (configurable) +- **Environment overrides** — override config via env vars +- **Graceful shutdown** — handles SIGINT and SIGTERM +- **Health endpoint** — `GET /health` + +## Quick Start + +```bash +# Build +cargo build --release + +# Run with default config +./target/release/doh-forwarder + +# Run with a custom config +./target/release/doh-forwarder --config /path/to/config.toml +``` + +## Configuration + +Create a TOML config file (see [config/default.toml](config/default.toml)): + +```toml +[server] +listen = "0.0.0.0:3000" + +[upstream] +resolvers = [ + { name = "cloudflare", url = "https://cloudflare-dns.com/dns-query" }, + { name = "google", url = "https://dns.google/dns-query" }, + { name = "quad9", url = "https://dns.quad9.net/dns-query" }, +] +strategy = "round-robin" # or "failover" + +[cache] +enabled = true +max_entries = 10000 +max_ttl_secs = 3600 +``` + +### Environment Variable Overrides + +| Variable | Description | Example | +|---|---|---| +| `DOH_LISTEN` | Override server listen address | `0.0.0.0:8080` | +| `DOH_UPSTREAM_STRATEGY` | Override upstream strategy | `failover` | +| `DOH_UPSTREAM_RESOLVERS` | Comma-separated `name=url` pairs | `google=https://dns.google/dns-query,cf=https://cloudflare-dns.com/dns-query` | +| `RUST_LOG` | Log level filter | `debug`, `doh_forwarder=trace` | + +## API + +### POST `/dns-query` + +Send a raw DNS wire-format query in the request body. + +```bash +# Using a pre-built DNS query (hex-encoded) +curl -X POST http://localhost:3000/dns-query \ + -H "Content-Type: application/dns-message" \ + -H "Accept: application/dns-message" \ + --data-binary @query.bin +``` + +### GET `/dns-query` + +Send a base64url-encoded DNS query as a query parameter. + +```bash +# Encode a DNS query and send via GET +QUERY=$(python3 -c " +import base64, struct +# Minimal A record query for example.com +q = b'\\x12\\x34' # ID +q += b'\\x01\\x00' # flags +q += b'\\x00\\x01' # 1 question +q += b'\\x00\\x00' # 0 answers +q += b'\\x00\\x00' # 0 authority +q += b'\\x00\\x00' # 0 additional +q += b'\\x07example\\x03com\\x00' # name +q += b'\\x00\\x01' # type A +q += b'\\x00\\x01' # class IN +print(base64.urlsafe_b64encode(q).rstrip(b'=').decode()) +") +curl "http://localhost:3000/dns-query?dns=$QUERY" +``` + +### GET `/health` + +Returns `ok` if the server is running. + +```bash +curl http://localhost:3000/health +# ok +``` + +## Upstream Strategies + +| Strategy | Behavior | +|---|---| +| `round-robin` | Distributes queries across resolvers in order | +| `failover` | Tries resolvers in order; moves to the next on failure | + +## Development + +```bash +# Prerequisites +rustup show # Rust 1.80+ + +# Run with auto-reload +cargo install cargo-watch +cargo watch -x run + +# Run tests +cargo test + +# Lint & format +cargo clippy -- -D warnings +cargo fmt --check +``` + +See [DEVELOP.md](DEVELOP.md) for full development rules and milestone tracking. + +## Project Structure + +``` +doh-forwarder/ +├── Cargo.toml +├── config/ +│ └── default.toml # Default configuration +├── src/ +│ ├── main.rs # Entrypoint, server setup +│ ├── lib.rs # Public API re-exports +│ ├── config.rs # TOML config + env overrides +│ ├── cache.rs # DNS response cache (TTL + LRU) +│ ├── dns/ +│ │ ├── mod.rs +│ │ ├── query.rs # DNS query parsing +│ │ └── response.rs # DNS response building +│ ├── upstream/ +│ │ ├── mod.rs +│ │ └── doh_client.rs # DoH forwarding client +│ └── routes.rs # HTTP route handlers +└── tests/ + └── integration.rs # Integration tests +``` + +## License + +MIT