自建无污染DNS服务器

Aria Bennett 发布于 2025-08-30 853 次阅读


AI 摘要

**引言**:想拥有一个无污染、纯净的DNS服务吗?通过Cloudflare Workers,你可以轻松自建DNS服务器,无需额外服务器,成本低廉!本文将手把手教你如何快速部署,享受纯净网络体验。快来探索吧!

方案

使用cloud flare workers部署

优点:无需服务器,成本低

缺点:无法屏蔽广告,自定义程度低

使用cloudflareworkers搭建纯净dns服务

登陆cloudflare  选择workers计算---workers和pages 单击创建

 

选择从hello world开始--单击部数 单机编辑代码 删除原有内容然后粘贴下方代码

 


var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });

// API 服务配置
const API_ENDPOINTS = {
  primary: "https://1.1.1.1/dns-query",
  backup: "https://dns.google/dns-query", 
  secure: "https://dns.quad9.net/dns-query",
  filter: "https://dns.adguard.com/dns-query"
};

// 服务配置
const DEFAULT_ENDPOINT = API_ENDPOINTS.primary;
const JSON_ENDPOINT = "https://1.1.1.1/dns-query";
const BINARY_TYPE = "application/dns-message";
const JSON_TYPE = "application/dns-json";
const BASE_PATH = "";

// 缓存设置
const CACHE_DURATION = 300;

const repo_default = {
  async fetch(request, env, ctx) {
    return handleApiRequest(request, env, ctx);
  }
};

async function handleApiRequest(request, env, ctx) {
  try {
    const { method, headers, url } = request;
    const urlObj = new URL(url);
    const { searchParams, pathname } = urlObj;

    // 路径验证
    if (!pathname.startsWith(BASE_PATH)) {
      return createNotFoundResponse();
    }

    // 获取服务端点
    const service = searchParams.get("service") || "primary";
    const endpoint = API_ENDPOINTS[service] || DEFAULT_ENDPOINT;

    let response;

    if (method === "GET" && searchParams.has("query")) {
      // 处理查询请求
      response = await handleQueryRequest(endpoint, searchParams);
    } else if (method === "POST" && headers.get("content-type") === BINARY_TYPE) {
      // 处理二进制数据请求
      response = await handleBinaryRequest(endpoint, request);
    } else if (method === "GET" && headers.get("Accept") === JSON_TYPE) {
      // 处理 JSON 数据请求
      response = await handleJsonRequest(JSON_ENDPOINT, urlObj.search);
    } else if (method === "GET" && (pathname === "/" || pathname === "/api")) {
      // API 文档
      response = createApiDocResponse();
    } else if (method === "OPTIONS") {
      // 预检请求
      response = createOptionsResponse();
    } else {
      return createNotFoundResponse();
    }

    // 添加通用响应头
    return addResponseHeaders(response);
    
  } catch (error) {
    console.error("API request error:", error);
    return createErrorResponse();
  }
}

async function handleQueryRequest(endpoint, searchParams) {
  const queryData = searchParams.get("query");
  if (!queryData) {
    return createBadRequestResponse("Missing query parameter");
  }

  return fetch(`${endpoint}?dns=${encodeURIComponent(queryData)}`, {
    method: "GET",
    headers: {
      "Accept": BINARY_TYPE,
      "User-Agent": "NetworkTool/2.0 (API Client)"
    },
    cf: {
      cacheTtl: CACHE_DURATION,
      cacheEverything: true
    }
  });
}

async function handleBinaryRequest(endpoint, request) {
  const payload = await request.arrayBuffer();
  
  return fetch(endpoint, {
    method: "POST",
    headers: {
      "Accept": BINARY_TYPE,
      "Content-Type": BINARY_TYPE,
      "User-Agent": "NetworkTool/2.0 (API Client)"
    },
    body: payload,
    cf: {
      cacheTtl: CACHE_DURATION,
      cacheEverything: true
    }
  });
}

async function handleJsonRequest(endpoint, search) {
  return fetch(`${endpoint}${search}`, {
    method: "GET",
    headers: {
      "Accept": JSON_TYPE,
      "User-Agent": "NetworkTool/2.0 (API Client)"
    },
    cf: {
      cacheTtl: CACHE_DURATION,
      cacheEverything: true
    }
  });
}

function createApiDocResponse() {
  const docs = `Network Query API v2.0

API Endpoints:
• GET  /api?query=           - Execute network query
• POST /api (binary payload)       - Submit binary data
• GET  /api (Accept: JSON)         - Get JSON response

Query Services:
• service=primary  - Primary service (default)
• service=backup   - Backup service  
• service=secure   - Secure service
• service=filter   - Filtered service

Usage Examples:
• /api?query=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
• /api?service=backup&query=

Response Formats:
- Binary: application/dns-message
- JSON: application/dns-json

Rate Limiting: 1000 requests/hour
Cache TTL: 5 minutes`;

  return new Response(docs, {
    headers: {
      "Content-Type": "text/plain; charset=utf-8",
      "X-API-Version": "2.0"
    }
  });
}

function createOptionsResponse() {
  return new Response(null, {
    status: 204,
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
      "Access-Control-Allow-Headers": "Content-Type, Accept, Authorization",
      "Access-Control-Max-Age": "86400"
    }
  });
}

function createNotFoundResponse() {
  return new Response("API endpoint not found", { 
    status: 404,
    headers: { 
      "Content-Type": "text/plain",
      "X-Error": "ENDPOINT_NOT_FOUND"
    }
  });
}

function createBadRequestResponse(message) {
  return new Response(`Bad Request: ${message}`, { 
    status: 400,
    headers: { 
      "Content-Type": "text/plain",
      "X-Error": "INVALID_PARAMETER"
    }
  });
}

function createErrorResponse() {
  return new Response("Service temporarily unavailable", { 
    status: 503,
    headers: { 
      "Content-Type": "text/plain",
      "X-Error": "SERVICE_ERROR",
      "Retry-After": "60"
    }
  });
}

function addResponseHeaders(response) {
  const newResponse = new Response(response.body, response);
  
  // API 通用头
  newResponse.headers.set("Access-Control-Allow-Origin", "*");
  newResponse.headers.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
  newResponse.headers.set("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization");
  
  // 伪装头
  newResponse.headers.set("X-Powered-By", "NetworkAPI/2.0");
  newResponse.headers.set("Server", "CloudEdge");
  
  // 缓存控制
  if (!newResponse.headers.has("Cache-Control")) {
    newResponse.headers.set("Cache-Control", "public, max-age=300");
  }
  
  return newResponse;
}

__name(handleApiRequest, "handleApiRequest");
__name(handleQueryRequest, "handleQueryRequest"); 
__name(handleBinaryRequest, "handleBinaryRequest");
__name(handleJsonRequest, "handleJsonRequest");
__name(createApiDocResponse, "createApiDocResponse");
__name(createOptionsResponse, "createOptionsResponse");
__name(createNotFoundResponse, "createNotFoundResponse");
__name(createBadRequestResponse, "createBadRequestResponse");
__name(createErrorResponse, "createErrorResponse");
__name(addResponseHeaders, "addResponseHeaders");

export {
  repo_default as default
};

点击部署,由于workers域名被大陆封锁所以需要用自定义域中转。回到workers和page页面在设置里找到域和路由,添加自定义域。

效果

使用

1. GET 请求 - 执行网络查询

curl "https://api.example.com/api?query="
curl "https://api.example.com/api?service=backup&query"
curl "https://api.example.com/api?service=secure&query"

api?query默认dns服务器查询

api?service=backup&query备份dns服务器查询

为什么不用标准查询路径?

防止GFW进行关键词过滤,伪装成API服务避免可能的QOS降速

此作者没有提供个人介绍。
最后更新于 2025-09-05