Obex DNS is a lightweight, scalable, and privacy-focused DNS resolution system. It runs entirely on Cloudflare's edge network, leveraging the ultra-fast response of Workers and the efficient storage of D1 database to provide users with a granular DNS (over HTTPS) control experience.
DoH (RFC 8484) is a protocol for performing DNS queries via encrypted HTTPS connections. Compared to traditional plaintext DNS, DoH can:
- Prevent Hijacking: Prevents ISPs or third parties from tampering with DNS responses.
- Enhance Privacy: Hides your browsing history through an encrypted tunnel.
- Bypass Censorship: Provides more stable resolution in restricted network environments.
- 🚀 Ultra-fast Resolution: Fully based on edge computing with extremely low global latency.
- 🗒️ Multi-profile Management: Supports creating multiple independent configurations, each with a unique endpoint.
- 🛡️ Granular Filtering:
- Allow/Block Lists: Supports exact domain and subdomain wildcard matching.
- Third-party Rule Sets: Supports subscribing to external blocklists in formats like AdGuard.
- Custom Redirection: Supports custom overrides for A, AAAA, TXT, and CNAME records.
- 📊 Real-time Stats & Logs: Visual dashboard recording every request's hit reason, geo-location, and upstream latency.
- 🔐 Privacy Enhancement: Flexible ECS (EDNS Client Subnet) configuration (Forward, Custom, or Hidden).
- 🌗 Modern UI: Dark mode support, high-density management panel built with React + BlueprintJS.
| User Login |
|---|
![]() |
| Setup Guide | Endpoints |
|---|---|
![]() |
![]() |
| Real-time Analytics | Request Destinations |
|---|---|
![]() |
![]() |
| Rule Management | External Filters |
|---|---|
![]() |
![]() |
| Resolution Logs | Log Detail |
|---|---|
![]() |
![]() |
| Profile Settings | Profile Select |
|---|---|
![]() |
![]() |
| Mobile Logs | Mobile Stats |
|---|---|
![]() |
![]() |
├── src/
│ ├── index.ts # Entry point, handles HTTP routing & middleware
│ ├── types.ts # Type definitions
│ ├── api/ # API Controllers (Auth, Account, Profiles)
│ ├── lib/ # Core logic (RBAC, Rule filtering)
│ ├── models/ # D1 Database models
│ ├── pipeline/ # DNS Resolution Pipeline (Core business logic)
│ └── utils/ # Utilities (Cache, GeoIP, DNS Codec, Bloom Filter)
├── web/ # React/BlueprintJS UI frontend project
│ ├── public/ # Public static files
│ ├── src/ # Frontend source code
│ │ ├── assets/ # Static assets (images, icons, etc.)
│ │ ├── components/ # Reusable UI components
│ │ ├── i18n/ # Internationalization (i18n) configuration
│ │ ├── layouts/ # Layout components (dashboard layout, etc.)
│ │ ├── routes/ # Frontend routing configuration
│ │ ├── views/ # Main pages / views (dashboard, logs, settings, setup, etc.)
│ │ └── utils/ # Utility helpers and functions
│ └── package.json # Frontend dependencies configuration
├── static/ # Compiled static resources
├── migrations/ # D1 Database migration scripts
└── wrangler.toml # Cloudflare deployment configuration
When a DNS request arrives, it goes through the following processing stages:
- Memory Cache Check: Checks if a valid response for the query exists in the edge node's memory.
- Config Loading: Layers profile settings loading from Memory -> Cache API -> D1 Database.
- Local Rule Matching:
- Whitelist: If hit, forwards directly to upstream and returns.
- Redirection: If hit, returns custom records.
- Blacklist: If hit, returns NXDOMAIN, 0.0.0.0, or a custom result.
- External List Filtering:
- Use a Bloom filter for fast filtering.
- Upstream Resolution: If none of the above hit, requests the upstream DoH server based on configuration, with optional ECS support.
- Async Logging & Caching: Asynchronously records resolution logs, fetches target GeoIP, and writes results to various cache levels.
- Node.js: v18.x or later
- Package Manager: npm
- Cloudflare Account: Workers and D1 permissions required
- Clone the repository and install dependencies:
npm install- Initialize D1 Database:
npm run db:setup
npm run db:migrate:dev- Start the development server:
npm run dev- Deploy online
npm run deploy- Fork this repo: Click the
Forkbutton at the top right to clone the repository to your own GitHub account. - Create D1 Database: Log in to the Cloudflare dashboard, go to
Workers & Pages>D1, and create a new database (e.g., namedobex_db), and copy the created database ID. - Configure Database ID: In your forked repository, edit the
wrangler.tomlfile and replacedatabase_idwith the ID of the database you just created. - Create Worker: Go to Cloudflare dashboard
Workers & Pages>Create application>Create Worker. - Import from GitHub: On the deployment page, select
Deploy from GitHub, connect your forked project, and complete the authorized deployment.
If you wish to deploy the project using Cloudflare Pages (Advanced Mode):
Warning
Not Recommended: This project is primarily a DNS resolution service, which is highly sensitive to response latency. Workers, as lightweight edge functions, are much better suited for low-latency DoH resolution tasks compared to Pages Functions. Standard Worker deployment also offers simpler routing and binding management. We strongly suggest deploying via Workers instead.
- Create a D1 Database, copy its ID, and paste it into the
database_idfield inwrangler.toml. - In the Cloudflare Dashboard, go to
Workers & Pages>Create application>Pages>Connect to Git. - Select your forked repository, and configure the build settings:
- Framework preset:
None - Build command:
npm run build:pages - Build output directory:
static
- Framework preset:
- After the initial deployment, go to the Pages project's Settings > Functions > D1 database bindings, and add a binding:
- Variable name:
DB - D1 database: Select your
obex_dbdatabase.
- Variable name:
- Redeploy the Pages project for the bindings to take effect.
- Cloudflare Workers
- Blueprint (at Palantir)
- Tailwind CSS
- React
This project is licensed under the AGPLv3 License.













