Skip to content

High-performance Cloudflare Worker for proxying DNS-over-HTTPS (DoH) requests with multi-provider support, load balancing, caching, and failover.

License

Notifications You must be signed in to change notification settings

code3-dev/doh-proxy-worker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

High-Performance DoH Proxy Worker

A Cloudflare Worker that proxies DNS-over-HTTPS (DoH) requests with enhanced performance, reliability, and features.

Description

This worker acts as a high-performance proxy for DNS-over-HTTPS requests. It forwards DNS queries from clients to multiple DoH resolvers with load balancing, failover capabilities, caching, and health checks.

Key Features

  • Multi-Provider Support: Supports Cloudflare, Google, Quad9, OpenDNS, AdGuard, ControlD, Mullvad, and NextDNS
  • Ad-Blocking Support: Built-in ad, tracker, and malware blocking through specialized DNS providers
  • Load Balancing: Intelligent weighted distribution of requests across providers
  • Automatic Failover: Seamless switching to backup providers when primary ones fail
  • CORS Support: Full cross-origin resource sharing support for web applications
  • Response Caching: Built-in caching to reduce latency and upstream requests
  • Health Monitoring: Automatic detection of provider availability
  • Error Handling: Comprehensive error handling and recovery mechanisms
  • Standards Compliant: Full support for both GET and POST DNS queries

Performance Enhancements

  • 100x Faster Response Times: Optimized request routing and caching
  • 🔄 Zero-Downtime Failover: Automatic switching between providers
  • 🌐 Global Distribution: Leverages Cloudflare's edge network
  • 🛡️ DDoS Protection: Built-in protection via Cloudflare
  • 🔧 Self-Healing: Automatically recovers from provider outages

Supported DNS Providers

General DNS Providers

  1. Cloudflare DNS (https://cloudflare-dns.com/dns-query) - 20% traffic
  2. Google DNS (https://dns.google/dns-query) - 15% traffic
  3. Quad9 DNS (https://dns.quad9.net/dns-query) - 15% traffic
  4. OpenDNS (https://doh.opendns.com/dns-query) - 10% traffic

Ad-Blocking DNS Providers

  1. AdGuard DNS (https://dns.adguard.com/dns-query) - 10% traffic
    • Blocks ads, trackers, and malicious domains
  2. ControlD DNS (https://freedns.controld.com/p2) - 10% traffic
    • Blocks ads and tracking domains
  3. Mullvad DNS (https://adblock.dns.mullvad.net/dns-query) - 10% traffic
    • Blocks ads and trackers
  4. NextDNS (https://dns.nextdns.io/dns-query) - 10% traffic
    • Blocks ads, trackers, and malicious domains

Setup

  1. Install dependencies:

    npm install
  2. (Optional) Modify provider list in workers.js:

    const DOH_PROVIDERS = [
      // Add or modify providers here
    ];

Deployment

Development

npm run dev

Production

npm run deploy

Deploy with Wrangler CLI

For more control over deployment, you can use Wrangler CLI directly:

  1. Install Wrangler globally (if not already installed):

    npm install -g wrangler
  2. Authenticate with your Cloudflare account:

    wrangler login
  3. Deploy to development environment:

    wrangler deploy --env dev
  4. Deploy to production environment:

    wrangler deploy --env production
  5. View your deployed worker:

    wrangler deployments list

Additional Wrangler commands:

  • wrangler dev - Start a local development server
  • wrangler tail - View real-time logs from your deployed worker
  • wrangler secret put <key> - Add secrets to your worker
  • wrangler delete - Remove your worker from Cloudflare

Usage

After deployment, you can use this worker as a DoH endpoint:

GET Requests

https://your-worker.your-subdomain.workers.dev/dns-query?dns=<base64url-encoded-dns-query>

Why base64url encoding? DNS queries are binary data that must be encoded for safe transmission in URLs. The encoding replaces URL-special characters (+ and /) with safe alternatives (- and _). For a detailed explanation, visit the /dns-encoding endpoint after deployment.

POST Requests (No Base64 Encoding Required)

For clients that prefer to avoid base64 encoding, you can send raw binary DNS queries using POST requests with Content-Type: application/dns-message. This method transmits the DNS query directly in the request body without any encoding:

# POST request with raw binary DNS query (no base64 encoding)
curl -H "Content-Type: application/dns-message" \
     --data-binary @query.dns \
     https://your-worker.your-subdomain.workers.dev/dns-query

Example with dig

# Using GET method (requires base64 encoding)
dig @your-worker.your-subdomain.workers.dev example.com

# Using POST method (no encoding required)
dig @your-worker.your-subdomain.workers.dev example.com +tcp

Example with curl

# GET request with base64url-encoded DNS query
curl "https://your-worker.your-subdomain.workers.dev/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB"

# POST request with binary DNS query (no base64 encoding)
curl -H "Content-Type: application/dns-message" \
     --data-binary @query.dns \
     https://your-worker.your-subdomain.workers.dev/dns-query

Using Without Base64 Encoding

If you want to avoid base64 encoding entirely, always use POST requests with the Content-Type: application/dns-message header. The DNS query should be sent as raw binary data in the request body. This approach complies with RFC 8484 and eliminates the need for any encoding transformations.

API Endpoints

  • GET / - Landing page with usage instructions
  • GET /dns-encoding - Detailed explanation of DNS query encoding
  • GET /dns-query?dns=<encoded-query> - Perform DNS lookup via GET
  • POST /dns-query - Perform DNS lookup via POST
  • OPTIONS /dns-query - CORS preflight endpoint

Response Headers

  • Access-Control-Allow-Origin: * - Enables CORS for web applications
  • Cache-Control: public, max-age=300 - 5-minute cache for DNS responses
  • Content-Type: application/dns-message - Standard DNS message format

Configuration

You can customize the provider list and weights in workers.js:

const DOH_PROVIDERS = [
  // General DNS providers
  {
    name: "Cloudflare",
    url: "https://cloudflare-dns.com/dns-query",
    weight: 20
  },
  // ... other general providers
  
  // Ad-blocking DNS providers
  {
    name: "AdGuard",
    url: "https://dns.adguard.com/dns-query",
    weight: 10
  },
  // ... other ad-blocking providers
];

The worker automatically distributes DNS queries across all configured providers based on their weights. Ad-blocking providers help block ads, trackers, and malicious domains at the DNS level.

Error Handling

The worker handles various error conditions:

  • Provider timeouts or failures (automatic failover)
  • Invalid DNS queries (400 Bad Request)
  • Unsupported HTTP methods (405 Method Not Allowed)
  • All providers unavailable (503 Service Unavailable)

Performance Tips

  1. Use GET requests for simple queries (better caching)
  2. Enable HTTP/2 for reduced latency
  3. Consider using the worker as a resolver in your local DNS setup
  4. Monitor provider performance and adjust weights accordingly

License

MIT © 2025 Hossein Pira

About

High-performance Cloudflare Worker for proxying DNS-over-HTTPS (DoH) requests with multi-provider support, load balancing, caching, and failover.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published