DigitalPlat One免费二级域名 + Cloudflare Tunnel 内网穿透保姆级教程实战

DigitalPlat One免费二级域名 + Cloudflare Tunnel 内网穿透保姆级教程实战

适用人群:想把自己内网的服务(网站 / ERP / 接口 / 测试页)暴露到公网,但没有公网 IP、不想折腾路由器端口映射、也不想花钱买域名和服务器的人。

本文以 DigitalPlat 免费二级域名 qch.dpdns.org + Cloudflare Tunnel(cloudflared) 为例,全程免费,Windows 实操,一步一步跟下来就能跑通。


这套方案能给你带来什么

  • 免费:二级域名免费 + Cloudflare 免费版足够用。
  • 不需要公网 IP:你家/公司内网照样能对外提供服务。
  • 不需要在路由器上做端口映射:公司网络动不了路由器也不怕。
  • 源站 IP 不暴露:流量走 Cloudflare 边缘节点,比直接暴露端口安全得多。
  • 一个隧道挂多个服务:一条隧道按子域名分流到多个本地端口(单隧道多服务)。

一、准备清单

  1. Windows 10 / 11 电脑一台(建议长期开机;想开机自启见第十二节)。
  1. 能正常上外网(Cloudflare 要能连)。
  1. 一个 DigitalPlat 免费二级域名 (下文以 qch.dpdns.org 为例,你换成自己的前缀)。
  1. 一个想对外暴露的本地服务(没有的话用本文第八节的 demo 脚本顶上)。

二、注册 DigitalPlat 免费二级域名并托管到 Cloudflare

这是最关键、也最容易踩坑的一步。很多人卡在"Cloudflare 添加不了免费二级域名",根因是没搞明白托管的是哪一级 zone。

2.1 在 DigitalPlat 注册二级域名

   打开 DigitalPlat 官网注册 / 登录。https://dashboard.digitalplat.org/auth/login

  

   申请一个二级域名前缀,比如 qch,完整域名就是 qch.dpdns.org。

  

  重点 :在域名管理里,把该域名的 NS(Nameserver)记录 指到 Cloudflare 的 nameserver(先别急着填,下一步 Cloudflare 会告诉你该填哪两个)。

  

2.2 在 Cloudflare 添加这个域名

  注册 / 登录 Cloudflare,https://dash.cloudflare.com/login

  点 添加域名-连接域名 ,输入我们的域名 qch.dpdns.org。

  选 Free 计划。

  Cloudflare 会给你两个 nameserver,类似:

  1. xxxx.ns.cloudflare.com
  2. yyyy.ns.cloudflare.com

  把这两个 NS 填回 DigitalPlat 后台(见上文),覆盖默认 NS。

  回到 Cloudflare 点 Check Nameservers / 等待生效(几分钟到几小时不等,看运气)。

✅ 验证标准:Cloudflare 的 DNS 页面能看到这个 zone,状态变 Active 即可。刚添加时 DNS 记录是空的,这是正常的。

三、下载安装 cloudflared

  1. 打开 GitHub Releases:https://github.com/cloudflare/cloudflared/releases
  1. 下载 Windows 64 位版本:cloudflared-windows-amd64.exe。
  1. 新建目录,比如 D:\cloudflare,把 exe 放进去。

  打开 PowerShell / CMD,进到目录验证一下:

复制代码
cd D:\cloudflare
.\cloudflared-windows-amd64.exe --version

能输出版本号(如 2026.10.3)就说明没问题。

四、登录 Cloudflare(tunnel login)

在 D:\cloudflare 目录执行:

复制代码
.\cloudflared-windows-amd64.exe tunnel login

会自动弹出浏览器,让你勾选要授权的域名(选 qch.dpdns.org),点授权。

授权成功后,会在 C:\Users\你的用户名\.cloudflared\cert.pem 生成证书文件。

五、创建命名隧道

复制代码
.\cloudflared-windows-amd64.exe tunnel create test-tunnel

test-tunnel 是隧道名,随便起,记牢它。下文都拿这个名字举例,你换成自己的。

输出里会给出隧道 ID 和凭证文件路径(*.json),记一下 ID 备用。

六、编写 config.yml(单隧道多服务的核心)

在 D:\cloudflare 下新建 config.yml,内容如下(把 qch.dpdns.org 换成你自己的域名):

复制代码
ingress:
  # 演示服务: 本地 demo_server.py (端口 9000)
  - hostname: demo.qch.dpdns.org
    service: http://localhost:9000

  # 兜底: 没匹配到任何子域名的请求, 返回 404 (这一行必须有)
  - service: http_status:404

逐行解释:

  • hostname:你想对外用的子域名。
  • service:该子域名对应的本地服务地址(localhost:端口)。
  • 想再加服务?照着加一段 - hostname / service 两行即可。
  • 最后一行 http_status:404 是默认兜底项,ingress 必须有默认项,否则启动报错。

校验语法(注意参数顺序 ,--config 要写在 ingress 前面):

复制代码
.\cloudflared-windows-amd64.exe tunnel --config config.yml ingress validate

返回 OK 就说明配置没问题。

七、为每个子域名建 DNS(route dns)

Cloudflare Tunnel 不需要你手动填 A 记录,用命令自动建 CNAME:

复制代码
.\cloudflared-windows-amd64.exe tunnel route dns test-tunnel demo.qch.dpdns.org

每个子域名都要单独跑一次 。跑完去 Cloudflare 的 DNS 页面,能看到自动生成的 CNAME(指向 <隧道ID>.cfargotunnel.com)。

八、本地后端(可选 demo 验证)

如果你暂时没有现成服务,用下面这个 demo 先验证链路。在 D:\cloudflare 新建 demo_server.py:

复制代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import http.server
import socketserver
import datetime

PORT = 9000

class Handler(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        html = f"""<!doctype html>
<html lang="zh-CN"><head><meta charset="utf-8">
<title>Cloudflare Tunnel Demo</title>
<style>
 body{{font-family:-apple-system,Segoe UI,Roboto,'Microsoft YaHei',sans-serif;
   background:#0b1020;color:#e6e6e6;margin:0;padding:40px}}
 .card{{max-width:720px;margin:0 auto;background:#151b32;border:1px solid #2a3358;
   border-radius:14px;padding:28px 32px;box-shadow:0 8px 30px rgba(0,0,0,.4)}}
 h1{{margin:0 0 8px;font-size:22px;color:#7aa2ff}}
 .tag{{display:inline-block;background:#1f6feb22;color:#7aa2ff;border:1px solid #1f6feb55;
   padding:3px 10px;border-radius:999px;font-size:13px}}
 .row{{margin-top:18px;font-size:14px;line-height:1.9}}
 code{{background:#0b1020;padding:2px 7px;border-radius:6px;color:#9ae6b4}}
 .ok{{color:#3fb950}}
</style></head>
<body><div class="card">
  <span class="tag">Cloudflare Tunnel · 单隧道多服务 Demo</span>
  <h1>本地后端服务正常运行 ✅</h1>
  <div class="row">
    当前时间: <code>{now}</code><br>
    监听端口: <code>{PORT}</code><br>
    请求路径: <code>{self.path}</code><br>
    来源 IP: <code>{self.client_address[0]}</code>
  </div>
  <div class="row">
    这个页面就是 ingress 里 <code>service: http://localhost:{PORT}</code> 指向的后端。<br>
    当 cloudflared 隧道起来后,外网访问你的子域名就会落到这里 ------ <span class="ok">链路通了</span>。
  </div>
</div></body></html>"""
        body = html.encode("utf-8")
        self.send_response(200)
        self.send_header("Content-Type", "text/html; charset=utf-8")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def log_message(self, fmt, *args):
        print(f"[{datetime.datetime.now():%H:%M:%S}] {fmt % args}")

if __name__ == "__main__":
    with socketserver.TCPServer(("0.0.0.0", PORT), Handler) as httpd:
        print(f"Demo 服务已启动: http://127.0.0.1:{PORT}  (Ctrl+C 退出)")
        httpd.serve_forever()

View Code

运行:

复制代码
py demo_server.py

本地访问 http://127.0.0.1:9000 看到状态页就说明后端正常。

九、启动隧道

复制代码
.\cloudflared-windows-amd64.exe tunnel --config config.yml --protocol http2 run test-tunnel

为什么要加 --protocol http2? 部分内网环境挡了 QUIC / UDP(7844 端口),不加这个参数,cloudflared 会反复重试 QUIC 再降级到 http2,日志又吵又慢。直接指定 http2 干净利落。如果你网络通畅,去掉它也能跑。

验证外网,用浏览器

十、运维三件套:批处理脚本

每次开关隧道都敲一长串命令太麻烦,做三个 .bat(放在 D:\cloudflare)。

stop_tunnel.bat(停用隧道)

复制代码
@echo off
cd /d D:\cloudflare
echo Stopping cloudflared tunnel...
taskkill /F /IM cloudflared-windows-amd64.exe >nul 2>&1
if "%errorlevel%"=="0" (echo [OK] Tunnel stopped.) else (echo [!] No running cloudflared process found.)

start_tunnel.bat(启动隧道)

复制代码
@echo off
cd /d D:\cloudflare
echo Starting cloudflared tunnel (test-tunnel, http2)...
start "" /min cloudflared-windows-amd64.exe tunnel --config config.yml --protocol http2 run test-tunnel
echo [OK] Tunnel started. Visit https://demo.qch.dpdns.org

restart_tunnel.bat(重启隧道,改完 config 用)

复制代码
@echo off
cd /d D:\cloudflare
echo Stopping tunnel...
taskkill /F /IM cloudflared-windows-amd64.exe >nul 2>&1
echo Waiting 2 seconds...
ping -n 3 127.0.0.1 >nul
echo Restarting tunnel (http2)...
start "" /min cloudflared-windows-amd64.exe tunnel --config config.yml --protocol http2 run test-tunnel
echo [OK] Tunnel restarted.

用法 :双击 .bat 即可。start 会拉起一个独立后台窗口,关掉 .bat 窗口不影响隧道运行。

十一、改配置后怎么重启

cloudflared 只在启动时读 config.yml ,所以改完配置必须重启隧道。

  • 手动命令行启动的:先结束进程再启动,或直接双击 restart_tunnel.bat。
  • 已注册成服务的(见第十二节):Restart-Service cloudflared。

新增子域名的标准流程:

  1. 在 config.yml 加一段 - hostname / service;
  1. 跑一次 route dns 建 CNAME;
  1. 重启隧道。

十二、进阶:注册成 Windows 服务(开机自启、不掉线)

上面手动启动的隧道,关掉终端 / 重启电脑就没了。想一劳永逸:

  把 config.yml 复制到 C:\Users\你的用户名\.cloudflared\config.yml (Windows 服务默认读这个位置;隧道凭证 *.json 已经在这里了)。  

  以管理员身份打开 PowerShell,执行:

复制代码
cd D:\cloudflare
.\cloudflared-windows-amd64.exe service install

  服务会自动启动;之后开机自启、掉线自动重连,不用再手动管。

日常管理:

复制代码
# 以下均需管理员 PowerShell
Restart-Service cloudflared   # 改完配置后重启服务
Stop-Service cloudflared      # 停用
Start-Service cloudflared     # 启动

十三、常见问题 & 踩坑汇总

**  外网访问 502 / 找不到** :多半是忘了 route dns 建 CNAME,或本地后端没起来。

**  本机 curl localhost 返回 502** :你电脑设了 HTTP 代理,localhost 被代理拦截了。测外网直接用浏览器;命令行测加 --noproxy '*'。

**  日志一直重试 QUIC / 连接慢** :内网挡了 UDP,启动加 --protocol http2。

**  改了 config 不生效**:必须重启隧道(见第十一节)。

**  新增子域名不通** :记得 route dns 建 DNS(见第七节)。

  .bat 中文乱码报错:注释全部改成英文。

**  误建了多余 DNS 记录** :Cloudflare 后台 → 该域名 → DNS → 找到多余那条 CNAME → 删除即可(cloudflared 本身没有删 DNS 的命令)。

结语

到这一步,你已经拥有了一条免费、稳定、安全的内网穿透隧道:一个 DigitalPlat 免费二级域名,配一条 Cloudflare Tunnel,按子域名把内网多个服务暴露到公网。把它注册成 Windows 服务后,基本可以忘了它的存在。

如果本文对你有帮助,欢迎点赞收藏;有疑问或踩到新坑,也欢迎评论区交流。