DigitalPlat One免费二级域名 + Cloudflare Tunnel 内网穿透保姆级教程实战
适用人群:想把自己内网的服务(网站 / ERP / 接口 / 测试页)暴露到公网,但没有公网 IP、不想折腾路由器端口映射、也不想花钱买域名和服务器的人。
本文以 DigitalPlat 免费二级域名
qch.dpdns.org+ Cloudflare Tunnel(cloudflared) 为例,全程免费,Windows 实操,一步一步跟下来就能跑通。
这套方案能给你带来什么
- 免费:二级域名免费 + Cloudflare 免费版足够用。
- 不需要公网 IP:你家/公司内网照样能对外提供服务。
- 不需要在路由器上做端口映射:公司网络动不了路由器也不怕。
- 源站 IP 不暴露:流量走 Cloudflare 边缘节点,比直接暴露端口安全得多。
- 一个隧道挂多个服务:一条隧道按子域名分流到多个本地端口(单隧道多服务)。
一、准备清单
- Windows 10 / 11 电脑一台(建议长期开机;想开机自启见第十二节)。
- 能正常上外网(Cloudflare 要能连)。
- 一个 DigitalPlat 免费二级域名 (下文以
qch.dpdns.org为例,你换成自己的前缀)。
- 一个想对外暴露的本地服务(没有的话用本文第八节的 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,类似:
xxxx.ns.cloudflare.comyyyy.ns.cloudflare.com
把这两个 NS 填回 DigitalPlat 后台(见上文),覆盖默认 NS。
回到 Cloudflare 点 Check Nameservers / 等待生效(几分钟到几小时不等,看运气)。

✅ 验证标准:Cloudflare 的 DNS 页面能看到这个 zone,状态变 Active 即可。刚添加时 DNS 记录是空的,这是正常的。
三、下载安装 cloudflared
- 打开 GitHub Releases:https://github.com/cloudflare/cloudflared/releases
- 下载 Windows 64 位版本:
cloudflared-windows-amd64.exe。
- 新建目录,比如
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 干净利落。如果你网络通畅,去掉它也能跑。

验证外网,用浏览器
- 打开 https://demo.qch.dpdns.org → 应看到 demo 状态页(200)。


十、运维三件套:批处理脚本
每次开关隧道都敲一长串命令太麻烦,做三个 .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。
新增子域名的标准流程:
- 在
config.yml加一段- hostname / service;
- 跑一次
route dns建 CNAME;
- 重启隧道。
十二、进阶:注册成 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 服务后,基本可以忘了它的存在。
如果本文对你有帮助,欢迎点赞收藏;有疑问或踩到新坑,也欢迎评论区交流。