Files
doh-forwarder/docs/story.md

141 lines
5.1 KiB
Markdown

# The Story — Why This Project Exists
## The Problem
In countries with internet censorship (Iran, China, Russia, and others), DNS is
one of the first things controlled. ISPs intercept plain DNS queries (UDP/TCP
port 53) and:
- Return fake IP addresses for blocked domains
- Log every domain you look up
- Inject ads or redirect to government portals
DNS-over-HTTPS (DoH) and DNS-over-TLS (DoT) solve this by encrypting DNS
queries, making them invisible to the ISP's DNS layer.
## What Already Exists
This is not a new problem. Mature tools already solve local DNS → DoH forwarding:
| Tool | What it does | Maintained by |
|---|---|---|
| `cloudflared` | Local DNS → DoH proxy (`cloudflared proxy-dns`) | Cloudflare |
| `dnscrypt-proxy` | DoH + DoT + anonymized relays, blocklists | Frank Denis |
| `stubby` | Local DNS → DoT proxy | getdns team |
| `systemd-resolved` | Built into systemd, supports DoT | systemd team |
| `AdGuard Home` | DNS proxy + DoH/DoT + web UI + blocklists | AdGuard |
For simple "local DNS → DoH" forwarding, **`cloudflared proxy-dns` does exactly
what this project does in one command:**
```bash
cloudflared proxy-dns --port 5353 --upstream https://cloudflare-dns.com/dns-query
```
## The Real Obstacle
The harder problem — and the one most relevant to censored regions — is that
**upstream DoH/DoT endpoints themselves get blocked:**
| Technique | What gets blocked | How |
|---|---|---|
| SNI inspection | `cloudflare-dns.com`, `dns.google` | TLS ClientHello reveals the domain |
| IP blocklist | Known resolver IPs (1.1.1.1, 8.8.8.8) | Direct IP blocking |
| TLS fingerprinting | DoH/DoT traffic patterns | JA3/JA4 fingerprint analysis |
| Deep packet inspection | HTTPS traffic to known DNS resolvers | Pattern matching on domain + path |
A local forwarder that sends `POST https://cloudflare-dns.com/dns-query` will
work in most of the world, but **will likely fail in Iran** because the
connection to Cloudflare itself is blocked.
## What Actually Works in Censored Environments
Tools that solve the **upstream blocking** problem:
1. **Warp / WireGuard** — tunnel all traffic (including DNS) through an
encrypted VPN. The ISP sees WireGuard traffic but can't inspect it.
2. **GoodbyeDPI / zapret** — packet manipulation to evade DPI without a VPN.
Modifies TCP flags, splits packets, fakes SNI.
3. **dnscrypt-proxy with anonymized relays** — DNS queries go through
intermediate relays. The resolver never sees your IP, and the ISP never
sees the resolver's IP.
4. **Tor** — route DNS through Tor exit nodes. Slow but highly resistant.
5. **Encrypted Client Hello (ECH)** — hides the SNI field in TLS handshakes.
Still emerging; not widely supported.
## So Is This Project Necessary?
**Honestly: no, not for its current functionality.**
If the goal is "use encrypted DNS from Linux in a censored region," install
`cloudflared` or `dnscrypt-proxy` + a Warp/WireGuard tunnel. These are
battle-tested, maintained by teams, and packaged in every distro.
## Where This Project Becomes Useful
This project becomes **genuinely valuable** if it evolves beyond a basic
forwarder. Directions that matter:
### 1. Upstream obfuscation (the real differentiator)
Route upstream DoH traffic through a proxy (SOCKS5, HTTP CONNECT, or
WireGuard tunnel) instead of direct HTTPS. This bypasses SNI and IP
blocking:
```
Local DNS → this forwarder → SOCKS5 proxy → DoH resolver
```
No existing lightweight Rust tool does this well. `dnscrypt-proxy` has
anonymized relays but no SOCKS5 support for DoH.
### 2. Pluggable transport layer
Support multiple upstream transports:
- **Direct DoH** (current — works in free internet)
- **DoH over SOCKS5** (works behind blocks)
- **DoH over WireGuard tunnel** (works behind aggressive DPI)
- **DNS-over-TLS** (for resolvers that support it)
The user picks the transport based on their environment.
### 3. Smart upstream selection
Don't just round-robin — **probe** upstreams for latency and availability.
Auto-switch when a resolver becomes unreachable. This matters when resolvers
get blocked intermittently.
### 4. Built-in blocklist support
Ad-blocking and malware-blocking at the DNS level. `dnscrypt-proxy` and
`AdGuard Home` do this, but a lightweight Rust binary with this built-in
is appealing for embedded/resource-constrained systems.
### 5. Learning
Even if you never deploy it, building this teaches:
- DNS wire format (RFC 1035)
- DoH protocol (RFC 8484)
- Rust async (Tokio, Axum)
- Network programming
- Error handling patterns
That alone justifies the project.
## Summary
| Question | Answer |
|---|---|
| Does this solve local DNS → DoH? | Yes, but `cloudflared` already does this |
| Does this bypass censorship? | No — upstream DoH endpoints get blocked |
| Is the project pointless? | No — it's a foundation for something better |
| What makes it worth building? | SOCKS5/proxy upstream support, pluggable transports, learning |
The project is a **starting point**, not a finished solution. The first 80%
(local DNS → DoH forwarding) is solved by existing tools. The last 20%
(bypassing upstream blocking) is where this project can differentiate.