背景
在 Windows 上把本地服务通过 Cloudflare Tunnel 暴露到公网,cloudflared 本身并不复杂,但一旦从“手动 run”切换到“Windows 系统服务”,就会遇到几个比较隐蔽的坑。
本文记录一次完整流程:安装、纯命令行创建隧道、写 config.yml、安装为 Windows 服务,以及服务模式下配置路径、ImagePath 和重启卡死的问题。
安装 cloudflared
可以通过 Scoop 或 Winget 安装:
scoop install cloudflared
或 powershell:
winget install -e --id Cloudflare.cloudflared
安装后确认命令可用:
where cloudflared
cloudflared --version
纯命令行创建本地管理隧道
这里使用“本地管理隧道”模式:隧道配置保存在本地 config.yml,通过命令行创建和管理。
1. 登录授权
cloudflared tunnel login
浏览器会打开 Cloudflare 授权页面。授权成功后,本地会生成 cert.pem,它是后续命令行操作的身份凭证。
2. 创建隧道
隧道名称只能包含小写字母、数字和连字符,长度 1 到 63,且在同一账户下唯一。例如:
cloudflared tunnel create xu-newhome
执行后会生成一个凭证 JSON 文件,文件名通常包含隧道 UUID。
3. 编写 config.yml
在默认配置目录 %USERPROFILE%\.cloudflared 下创建 config.yml,例如:
tunnel: xu-newhome
credentials-file: C:\Users\Administrator\.cloudflared\c7d942f8-65b4-4c57-800b-5e08af87556b.json
ingress:
- hostname: app.example.com
service: http://localhost:8000
- service: http_status:404
注意:
credentials-file建议使用绝对路径。ingress最后一条必须是回退规则,例如http_status:404。- 如果
config.yml放在自定义位置,运行时要加s--config指定完整路径。
4. 添加 DNS 路由
cloudflared tunnel route dns xu-newhome app.example.com
这一步会在 Cloudflare 上创建 CNAME,把域名指向隧道。
5. 手动运行测试
cloudflared tunnel --config .\.cloudflared\config.yml run xu-newhome
日志中出现 Registered tunnel connection,说明隧道已经连上 Cloudflare。
安装为 Windows 系统服务
手动 run 的进程关掉终端就断了,因此可以安装为 Windows 服务:
cloudflared service install
如果提示服务已存在,说明这台机器上已经有 cloudflared 服务。Cloudflare 的限制是:同一台机器只能运行一个 cloudflared 服务实例。不同机器、不同 NAS 各自运行不冲突。
服务模式的三个大坑
坑一:服务读取的 config.yml 不是用户目录下的那个
手动运行时,你用的是:
C:\Users\Administrator\.cloudflared\config.yml
但 Windows 服务以 SYSTEM 账户运行,默认读取的是:
C:\Windows\System32\config\systemprofile\.cloudflared\config.yml
如果只把配置写在用户目录,服务虽然“启动了”,但并没有加载你期望的隧道配置。
解决方式:把 config.yml 和凭证 JSON 复制到系统配置目录:
mkdir C:\Windows\System32\config\systemprofile\.cloudflared -Force
copy C:\Users\Administrator\.cloudflared\config.yml `
C:\Windows\System32\config\systemprofile\.cloudflared\config.yml
copy C:\Users\Administrator\.cloudflared\c7d942f8-65b4-4c57-800b-5e08af87556b.json `
C:\Windows\System32\config\systemprofile\.cloudflared\
并把系统配置目录里的 config.yml 中 credentials-file 改成绝对路径:
credentials-file: C:\Windows\System32\config\systemprofile\.cloudflared\c7d942f8-65b4-4c57-800b-5e08af87556b.json
坑二:服务的 ImagePath 只指向 exe,缺少运行参数
查看服务注册表:
Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Cloudflared' -Name ImagePath
如果输出只是:
C:\Users\Administrator\scoop\apps\cloudflared\current\cloudflared.exe
说明它只启动了程序本身,没有告诉 cloudflared 要运行哪个隧道、用哪个配置文件,服务会启动失败。
需要手动修正 ImagePath,补上 tunnel --config ... run 参数。以管理员身份执行:
$cloudflaredExe = "C:\Users\Administrator\scoop\apps\cloudflared\current\cloudflared.exe"
$configFile = "C:\Windows\System32\config\systemprofile\.cloudflared\config.yml"
$newImagePath = "`"$cloudflaredExe`" tunnel --config `"$configFile`" run"
reg add "HKLM\SYSTEM\CurrentControlSet\Services\Cloudflared" `
/v ImagePath /t REG_EXPAND_SZ /d "$newImagePath" /f
验证:
(Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Cloudflared' -Name ImagePath).ImagePath
输出应类似:
"C:\Users\Administrator\scoop\apps\cloudflared\current\cloudflared.exe" tunnel --config "C:\Windows\System32\config\systemprofile\.cloudflared\config.yml" run
坑三:Restart-Service 卡在“Waiting for service to stop”
cloudflared 在 Windows 服务模式下有一个已知问题:有时无法正常响应停止信号,Restart-Service cloudflared 会一直卡住。管理员权限也解决不了,需要强制结束进程。
先查服务 PID:
sc queryex cloudflared
然后强制结束:
taskkill /f /pid <PID>
或者直接结束所有 cloudflared 进程:
Get-Process -Name cloudflared -ErrorAction SilentlyContinue | Stop-Process -Force
确认进程消失后,再启动服务:
Start-Service cloudflared
以后修改配置后的推荐重启流程是:
Get-Process cloudflared -ErrorAction SilentlyContinue | Stop-Process -Force
Start-Sleep -Seconds 2
Start-Service cloudflared
不要依赖 Restart-Service 自动完成两步。
验证隧道是否真的生效
服务启动成功不等于网站可访问。建议按顺序检查:
- 查看 cloudflared 日志,确认出现 Registered tunnel connection。
- 登录 Cloudflare Dashboard,进入 Networking → Tunnels,确认隧道状态为 Healthy,Connector 数量正常。
- 浏览器访问 config.yml 中配置的 hostname。
- 检查 Cloudflare DNS 中该域名的 CNAME 是否指向:
<隧道UUID>.cfargotunnel.com
如果 Dashboard 正常、日志也显示连接成功,但网站打不开,优先检查 DNS 记录是否被旧记录占用,以及本地服务地址和端口是否正确。
多台 NAS 使用 cloudflared 会冲突吗
不会。不同设备各自运行 cloudflared 互不影响。
需要注意:
- 同一台机器只能运行一个
cloudflared服务实例。 - 不同设备建议分别创建独立隧道,或用不同路由规则区分。
- 不要把同一个隧道的凭证复制到两台设备上同时运行,否则 Cloudflare 会把流量随机分发到两台设备,相当于负载均衡,而不是主备。
安全提醒
cert.pem 权限很高,持有它可以管理账户下的所有隧道。不要随意复制到不信任的设备。如果必须在新设备上操作,更安全的做法是在那台设备上重新执行:
cloudflared tunnel login
生成新的凭证。
常用命令速查
# 查看隧道列表
cloudflared tunnel list
# 查看隧道详情
cloudflared tunnel info xu-newhome
# 删除隧道
cloudflared tunnel delete xu-newhome
# 清理失效连接
cloudflared tunnel cleanup xu-newhome
# 安装服务
cloudflared service install
# 卸载服务
cloudflared service uninstall
# 强制停止进程后启动服务
Get-Process cloudflared -ErrorAction SilentlyContinue | Stop-Process -Force
Start-Service cloudflared
小结
Windows 上使用 cloudflared 的关键,是区分“手动运行”和“系统服务”两种模式:
- 手动运行读用户目录配置;
- 系统服务读
SYSTEM账户配置目录; - 服务
ImagePath必须带tunnel --config ... run参数; - 重启卡住时直接强制结束进程,再单独启动服务。
- 把这几个点处理好,
cloudflared作为 Windows 服务长期运行还是比较稳定的。