Cloudflare Tunnel 官方连接器参数详解:Token 模式与本地管理模式、四种跑法、config.yml 与 ingress 全解、Access 客户端(SSH/RDP)、Windows/Linux 服务安装与实战排障表。依据 2026.10.7 版 --help 实测整理。
本文档依据 cloudflared 2026.10.7 的实际
--help输出整理(参数与默认值均以该版本实测为准),覆盖隧道服务端与 Access 客户端两条线。示例中的域名、Token、UUID 均为占位,请替换为你自己的。
cloudflared 是 Cloudflare Tunnel 的官方连接器:它从你的机器主动向外连到 Cloudflare 边缘(出站连接,目标端口 7844),把外部请求经这条连接送回本机服务。因此不需要公网 IP、不需要在路由器上开任何入站端口。
它有三种身份,别混淆:
| 身份 | 命令族 | 干什么 |
|---|---|---|
| 隧道连接器(服务端) | cloudflared tunnel ... |
把本机/内网服务发布出去 |
| Access 客户端 | cloudflared access ... |
从另一台设备连受 Access 保护的 TCP/SSH/RDP 应用 |
| 系统服务 | cloudflared service ... |
把连接器装成开机自启的后台服务 |
隧道本身有两种管理模式,命令和参数通用,但凭证不同:
cloudflared tunnel run --token <TOKEN>。最省事,本文主要场景就是它。cloudflared tunnel login 拿到账户证书,再用命令行 create/route,路由写在本机 config.yml 的 ingress 规则里。适合一台机器发布多个服务、想把配置纳入版本管理的情况。不需要登录、不需要域名,Cloudflare 随机分配一个 *.trycloudflare.com 地址,关掉进程即失效:
cloudflared tunnel --url http://localhost:3000
终端会打印出分配的公网地址。注意:--url 是 tunnel 的参数,不带任何子命令。
可选:给临时隧道加一道邮箱验证(新版支持),只有名单里的邮箱过 Access 验证才能访问:
cloudflared tunnel --url http://localhost:3000 --allowed-mail you@example.com
cloudflared tunnel run --token <TOKEN>
Token 在后台的隧道详情里复制。它是一串 Base64,内含账户标识、隧道 UUID 和密钥——拿到 Token 就能以这条隧道的身份接入,等同凭证,禁止外泄、禁止写进公开仓库。
不想让 Token 出现在命令行(进程列表里可见)时,改用文件或环境变量:
cloudflared tunnel run --token-file C:\cloudflared\token.txt
$env:TUNNEL_TOKEN = "<TOKEN>"
cloudflared tunnel run
config.yml(位置见第六节)写好后,一条命令跑起来:
cloudflared tunnel --config /etc/cloudflared/config.yml run my-tunnel
不接任何真实服务,cloudflared 自己内置一个测试页,专用于验证「隧道链路本身通不通」,排障时先用它把问题和业务服务分开:
cloudflared tunnel --hello-world run --token <TOKEN>
或临时模式:cloudflared tunnel --hello-world。
| 命令 | 用途 |
|---|---|
tunnel login |
浏览器授权,下载账户证书 cert.pem(本地管理模式的前置) |
tunnel create |
创建隧道并生成凭证 JSON 文件 |
tunnel route dns |
给隧道绑域名(自动写 CNAME 记录) |
tunnel route ip |
给 WARP 客户端添加内网 IP 路由(add/show/delete/get) |
tunnel run |
运行隧道(核心命令,参数见第七节) |
tunnel list |
列出账户下全部隧道及连接状态 |
tunnel info |
查看某条隧道当前在线的连接器详情 |
tunnel token |
取回一条已有隧道的 Token |
tunnel cleanup |
清理隧道的僵尸连接记录 |
tunnel delete |
删除隧道 |
tunnel ready |
探测本机实例的 /ready 健康端点,用退出码表示是否就绪 |
tunnel diag |
生成诊断包(日志、指标、到边缘的 traceroute 等),报障时用 |
tunnel ingress validate |
校验 config.yml 的 ingress 规则语法 |
tunnel ingress rule <URL> |
测试某个 URL 会命中哪条 ingress 规则 |
tunnel vnet |
管理虚拟网络(多个内网 IP 段重叠时才用) |
access tcp/rdp/ssh |
客户端侧:把受保护应用转发到本地端口 |
access login / token / curl |
客户端侧:登录 Access 应用、取令牌、带令牌发请求 |
service install / uninstall |
安装/卸载系统服务 |
update |
自我更新(更新成功退出码为 11) |
tail |
流式查看某个远程 cloudflared 实例的日志 |
cloudflared tunnel login
打开浏览器选择域名授权,证书保存到 ~/.cloudflared/cert.pem(Windows 为 %USERPROFILE%\.cloudflared\cert.pem)。这张证书是账户级凭证:能创建/删除隧道,别随处拷贝。用 --origincert <路径> 可指定其他位置的证书。
cloudflared tunnel create my-tunnel
输出隧道 UUID,并在 ~/.cloudflared/ 下生成 <UUID>.json 凭证文件。关键参数:
| 参数 | 说明 | 示例 |
|---|---|---|
--credentials-file, --cred-file |
指定凭证 JSON 的写入路径(默认按 UUID 命名放在 .cloudflared 目录) | --cred-file ./my-tunnel.json |
--secret, -s |
手动指定隧道密钥(Base64,解码后至少 32 字节);不指定则随机生成。适合要把凭证纳入自己密钥管理流程的场景 | -s <base64> |
--output, -o |
输出格式,json 或 yaml,方便脚本解析 |
-o json |
Token 模式下不需要 login/create——隧道在后台建好后直接拿 Token。但要注意:
tunnel token命令只能取回 2022.3.0 之后创建的隧道的 Token。
cloudflared tunnel route dns my-tunnel app.example.com
在该域名所在 zone 里自动创建一条 CNAME,指向 <隧道UUID>.cfargotunnel.com。
| 参数 | 说明 |
|---|---|
--overwrite-dns, -f |
该主机名已有 DNS 记录时强制覆盖。不加这个参数、记录又已存在时命令会报错——面板建过的域名再用命令行绑,大概率要加 -f |
给 Zero Trust 组织的 WARP 客户端添加「某个内网网段走这条隧道」的路由,实现按 IP 直达内网(不是给公网用户用的):
cloudflared tunnel route ip add 192.168.10.0/24 my-tunnel
cloudflared tunnel route ip show
cloudflared tunnel route ip get 192.168.10.5
cloudflared tunnel route ip delete 192.168.10.0/24
多个物理内网用了相同 IP 段时,用 tunnel vnet add/list/update/delete 建虚拟网络把路由隔开,个人单机场景用不上。
默认搜索位置:Linux 为 /etc/cloudflared/config.yml、~/.cloudflared/config.yml;Windows 为 %USERPROFILE%\.cloudflared\config.yml。也可以用 --config <路径> 显式指定。
一份完整示例(一台机器发布三个服务):
tunnel: 5ef006c2-684b-4672-8ee2-02bcb7a052af
credentials-file: /etc/cloudflared/5ef006c2-684b-4672-8ee2-02bcb7a052af.json
protocol: http2
loglevel: info
metrics: localhost:20241
ingress:
# Web 应用
- hostname: app.example.com
service: http://localhost:3000
# 局域网另一台机器上的 HTTPS 服务(自签证书)
- hostname: nas.example.com
service: https://192.168.1.20:8443
originRequest:
noTLSVerify: true
# SSH(浏览器/客户端经 Access 访问)
- hostname: ssh.example.com
service: ssh://localhost:22
# 远程桌面
- hostname: rdp.example.com
service: rdp://localhost:3389
# 兜底规则:必须有且必须是最后一条,不匹配的一律 404
- service: http_status:404
顶层字段:
| 字段 | 说明 |
|---|---|
tunnel |
隧道名或 UUID |
credentials-file |
凭证 JSON 路径 |
protocol |
与边缘的传输协议:auto(默认,先 QUIC 后回落)/ quic / http2 |
loglevel |
日志级别 debug/info/warn/error/fatal |
metrics |
指标与健康端点监听地址 |
warp-routing: {enabled: true} |
启用 WARP 内网 IP 路由转发(配合 route ip 使用) |
ingress |
路由规则数组,自上而下匹配,命中即停 |
ingress 每条规则的字段:
| 字段 | 说明 |
|---|---|
hostname |
匹配的主机名,支持通配如 *.example.com;省略表示匹配全部主机名 |
path |
匹配路径的正则,如 /api/.*;省略表示全部路径 |
service |
目标服务,见下表 |
service 的合法形态:
| 写法 | 含义 |
|---|---|
http://localhost:3000 |
HTTP 源站 |
https://localhost:8443 |
HTTPS 源站(证书校验可用 originRequest 调整) |
tcp://localhost:3389 |
裸 TCP(配合 access 客户端或浏览器渲染使用) |
ssh://localhost:22 / rdp://localhost:3389 / smb://localhost:445 |
协议语义别名,本质都是 TCP,写明了便于 Access 侧识别 |
unix:/run/app.sock |
Unix 套接字源站 |
hello_world |
内置测试页 |
http_status:404 |
直接返回指定 HTTP 状态码(兜底规则常用) |
originRequest 常用项(写在某条规则下,只对该规则生效):
| 项 | 默认 | 说明 |
|---|---|---|
connectTimeout |
30s | 与源站建连超时 |
tlsTimeout |
10s | 与源站 TLS 握手超时 |
tcpKeepAlive |
30s | 源站连接 TCP keepalive |
keepAliveConnections |
100 | 到源站的长连接池上限 |
keepAliveTimeout |
1m30s | 源站长连接空闲关闭时间 |
noHappyEyeballs |
false | 禁用 IPv4/IPv6 双栈竞速(源站双栈有问题时开) |
httpHostHeader |
— | 改写发给源站的 Host 头 |
originServerName |
— | 校验源站证书时使用的名字(SNI/证书名与访问名不一致时用) |
caPool |
— | 源站证书的 CA 文件路径(私有 CA 时用) |
noTLSVerify |
false | 跳过源站证书校验(自签证书临时方案,长期应配 caPool) |
disableChunkedEncoding |
false | 禁用分块传输(老 WSGI 服务兼容) |
http2Origin |
false | 以 HTTP/2 回源 |
proxyType: socks |
— | 本规则经 SOCKS5 代理回源(配合 --socks5 场景) |
改完配置先校验再重启,两个官方工具:
cloudflared tunnel ingress validate
cloudflared tunnel ingress rule https://app.example.com/api/users
第二条会直接告诉你这条请求命中第几条规则、转发到哪个 service——多规则排障全靠它。
远程托管(Token)模式下 ingress 在云端配置,本机 config.yml 的 ingress 不生效,别在本地写了半天发现没动静。
语法位置先说清:cloudflared tunnel [通用参数] run [run 参数] [隧道名或UUID]。通用参数(第八节)必须写在 run 之前,run 自己的参数写在 run 之后,写串位置会报 flag provided but not defined 或被静默忽略。
| 参数 | 说明 | 示例 |
|---|---|---|
--token |
Token 模式的连接令牌 | --token eyJh... |
--token-file |
从文件读 Token,避免出现在进程列表和 shell 历史里 | --token-file C:\cloudflared\token.txt |
--credentials-file, --cred-file |
本地管理模式的凭证 JSON | --cred-file ~/.cloudflared/<UUID>.json |
--credentials-contents |
直接把凭证 JSON 的内容作为参数传入(容器编排注入用) | 一般人用不上 |
| 参数 | 说明 |
|---|---|
--url |
单一源站地址,默认 http://localhost:8080。cloudflared tunnel --url http://localhost:3000 即临时隧道;命名隧道 run 时加 --url 则忽略 ingress、只代理这一个服务 |
--hello-world |
用内置测试页当源站,纯链路自检 |
--unix-socket |
源站是 Unix 套接字时用它替代 --url |
--name, -n |
一步到位:创建+绑 DNS+运行一条新隧道(图省事用,生产环境建议分步执行) |
--hostname |
配合 --name 使用,指定要绑的主机名 |
| 参数 | 默认 | 说明 |
|---|---|---|
--protocol |
auto | 与边缘的传输协议:auto / quic / http2。新版已从 --help 中隐藏但仍有效(2026.10.7 实测:日志打印 Initial protocol http2)。QUIC 走 UDP 7844 被网络拦截时改 http2 走 TCP 7844;也可写进 config.yml 的 protocol: 字段 |
--edge-ip-version |
auto | 连边缘时用 IPv4、IPv6 还是自动:4 / 6 / auto。本机 IPv6 路由是坏的时强制 4 能少踩坑 |
--edge-bind-address |
— | 多网卡机器上指定出站绑定的本地 IP |
--dns-resolver-addrs |
— | 覆盖解析边缘域名用的 DNS 服务器(地址:端口,可多次)。本机 DNS 被劫持/污染导致解析不到 argotunnel 时用,如 --dns-resolver-addrs 1.1.1.1:53 |
--retries |
5 | 连接/协议错误的最大重试次数 |
--grace-period |
30s | 收到 Ctrl+C/终止信号后,等在途请求处理完再退出的宽限期 |
--no-prechecks |
false | 跳过启动时的连通性预检(DNS/UDP/TCP/API 四项)。明知某项会误报、只想强行启动时用;排障时不要加,要靠预检定位问题 |
--post-quantum, --pq |
false | 实验性后量子加密连接 |
--icmpv4-src / --icmpv6-src |
自动探测 | 指定 ICMP(ping 代理)用的源地址/网卡,WARP 内网路由场景才需要 |
--features, -F |
— | 启用实验特性(可多次),普通用户不用 |
| 参数 | 默认 | 说明 |
|---|---|---|
--metrics |
localhost:0(自动在 20241–20245 里挑) | 指标服务监听地址。启动后可访问 http://localhost:20241/metrics 看 Prometheus 指标、/ready 看就绪状态(返回 200 才算隧道可用) |
--pidfile |
— | 首次连接成功后把进程 PID 写到该文件,脚本管理用 |
ingress 模式请改写 originRequest,下表是 --url 模式的等价命令行版:--proxy-connect-timeout(30s)、--proxy-tls-timeout(10s)、--proxy-tcp-keepalive(30s)、--proxy-keepalive-connections(100)、--proxy-keepalive-timeout(1m30s)、--proxy-no-happy-eyeballs、--http-host-header、--origin-server-name、--origin-ca-pool、--no-tls-verify、--no-chunked-encoding、--http2-origin、--socks5(把本隧道当 SOCKS5 服务端)。含义与第五节 originRequest 表一一对应。
跳板机模式:--bastion 把本机作为 SSH 跳板(配合 Access 的 SSH 配置),另有 --proxy-address(默认 127.0.0.1)、--proxy-port(默认 0)指定其监听。
这一组对所有 tunnel 子命令生效,位置是 cloudflared tunnel <这里> <子命令>:
| 参数 | 默认 | 说明 |
|---|---|---|
--config |
见第五节 | 指定 YAML 配置文件路径 |
--origincert |
~/.cloudflared/cert.pem | login 证书路径(create/route/list 等管理命令要用) |
--loglevel |
info | 日志级别。排障第一动作就是调到 debug;注意 debug 会把请求头打进日志,可能含敏感信息,别长期开 |
--logfile |
— | 日志写入文件(服务模式排障必备,前台跑不用) |
--log-directory |
— | 日志按天滚动写入目录 |
--output |
default | 日志格式 default 或 json(喂日志系统用 json) |
--autoupdate-freq |
24h | 自动检查更新的间隔 |
--no-autoupdate |
false | 关闭自动更新。Windows 服务模式本来就不自动更新(启动日志会明说);Docker 部署建议关掉,改用换镜像升级 |
--metrics |
localhost:0 | 同 run 的指标地址(diag 命令靠它定位要诊断的实例) |
cloudflared tunnel list # 全部隧道:ID、名称、创建时间、连接数
cloudflared tunnel list -o json # JSON 输出给脚本
cloudflared tunnel list -d # 连已删除的也列出来
cloudflared tunnel list -n my-tunnel # 按名称过滤(另有 --name-prefix 等)
cloudflared tunnel info my-tunnel # 在线连接器:ID、来源 IP、版本、接入边缘位置
cloudflared tunnel token my-tunnel # 取回 Token(仅 2022.3.0 后建的隧道)
cloudflared tunnel token --cred-file ./t.json my-tunnel # 把 Token 写进凭证文件
cloudflared tunnel cleanup my-tunnel # 清掉已不存在的旧连接记录(info 里有僵尸连接器时用)
cloudflared tunnel cleanup -c <连接器ID> my-tunnel # 只清指定的一个连接器
cloudflared tunnel delete my-tunnel # 删除隧道(有活动连接会拒绝)
cloudflared tunnel delete -f my-tunnel # 强制删除(连同依赖的 IP 路由等)
cloudflared tunnel ready # 查本机实例 /ready,退出码 0=就绪
cloudflared tunnel diag # 生成诊断包 zip(日志+指标+系统信息+到边缘 traceroute)
diag 可用 --no-diag-logs / --no-diag-metrics / --no-diag-system / --no-diag-network / --no-diag-runtime 关掉某一类采集,--metrics <地址> 指定诊断哪个实例(同机多开时必须指定)。
发布是服务端的事;你在外面要连受 Access 保护的 TCP 类应用(SSH/RDP/SMB 等),连接端也要 cloudflared 做一次认证和本地转发。HTTP 应用不用这套,浏览器直接过 Access 登录即可。
access tcp、access rdp、access ssh 在当前版本是同一命令的三个名字,参数完全相同:
| 参数 | 说明 |
|---|---|
--hostname, -T |
目标应用的主机名(就是隧道里绑的那个域名) |
--url, --listener, -L |
在本机监听的地址:端口,流量从这里转发进隧道 |
--destination |
经虚拟网络/Target 访问时用的目标地址(高级用法) |
--header, -H |
附加请求头(可多次),一般配合服务令牌用 |
--service-token-id, --id + --service-token-secret, --secret |
用 Access 服务令牌免交互认证(脚本/自动化场景;人工使用走浏览器登录) |
--logfile / --log-directory / --log-level |
客户端日志三件套 |
远程桌面示例(在你要发起远控的电脑上):
cloudflared access rdp --hostname rdp.example.com --url localhost:33890
首次运行会弹浏览器做 Access 登录;保持这个窗口开着,再打开系统自带「远程桌面连接」,连 localhost:33890,输 Windows 账户密码即可。SSH 同理:
cloudflared access ssh --hostname ssh.example.com --url localhost:2222
ssh -p 2222 user@localhost
不想每次手敲,cloudflared access ssh-config 能生成一段 SSH 配置模板,写进 ~/.ssh/config 后 ssh ssh.example.com 一条命令直达(内部走 ProxyCommand 调用 cloudflared)。
其余客户端工具:access login <应用URL> 单独完成一次登录并缓存令牌;access token <应用URL> 把令牌打到标准输出给脚本用;access curl <URL> 带着 Access 令牌发 HTTP 请求,验证「应用是不是被 Access 正确保护」时很好用。
前台窗口跑隧道只是测试姿势,长期用一律装服务。
管理员 PowerShell,一次完成安装并启动(Token 直接跟在命令后面):
cloudflared service install <TOKEN>
cloudflared service uninstall
装完在 services.msc 里能看到名为 Cloudflared 的服务,启动类型为自动。日常启停用系统命令:
Start-Service Cloudflared
Stop-Service Cloudflared
Restart-Service Cloudflared
Get-Service Cloudflared
注意事项:Windows 上的服务不会自动更新 cloudflared 本体,升级要手动换 exe 后重启服务;服务的运行参数(Token)在安装时写死,换隧道/换 Token 后要先 uninstall 再重新 install。
sudo cloudflared service install <TOKEN>
sudo systemctl status cloudflared
sudo journalctl -u cloudflared -f
本地管理模式则是把 config.yml 和凭证放到 /etc/cloudflared/ 后 sudo cloudflared service install(不带 Token,读配置目录)。Docker 场景不用 service,直接把 cloudflared 容器设为 restart: unless-stopped 即可。
cloudflared update # 有新版就地升级并退出;退出码 11 表示「确实更新了」
cloudflared update --beta # 升到测试版
cloudflared update --version 2026.10.7 # 升/降到指定版本
cloudflared --version # 看当前版本
多数参数都有同名环境变量,容器和服务部署时更常用。优先级:命令行参数 > 环境变量 > 配置文件。
| 环境变量 | 对应参数 |
|---|---|
TUNNEL_TOKEN |
--token |
TUNNEL_TOKEN_FILE |
--token-file |
TUNNEL_URL |
--url |
TUNNEL_CRED_FILE |
--credentials-file |
TUNNEL_ORIGIN_CERT |
--origincert |
TUNNEL_LOGLEVEL |
--loglevel |
TUNNEL_LOGFILE |
--logfile |
TUNNEL_METRICS |
--metrics |
NO_AUTOUPDATE |
--no-autoupdate |
NO_TLS_VERIFY |
--no-tls-verify |
TUNNEL_EDGE_IP_VERSION |
--edge-ip-version |
TUNNEL_TRANSPORT_PROTOCOL |
(历史变量)协议改用 --protocol 或 config.yml 的 protocol: 字段 |
cloudflared 启动时会做四项连通性预检并打出表格,先看它再猜:
| 预检项 | 含义 | FAIL 的常见原因 |
|---|---|---|
| DNS Resolution | 能否解析 region1/region2.v2.argotunnel.com | 本机 DNS 故障/被污染 → --dns-resolver-addrs 1.1.1.1:53 |
| UDP Connectivity | QUIC(UDP 7844)能否连通边缘 | 运营商/路由器拦 UDP、本机代理软件 TUN 模式劫流 → 改 --protocol http2 或处理代理规则 |
| TCP Connectivity | HTTP/2(TCP 7844)能否连通边缘 | 出口防火墙只放行常用端口、本机安全软件拦截 |
| Cloudflare API | api.cloudflare.com:443 是否可达 | 一般网络问题 |
典型症状对号入座:
| 症状 | 结论与处理 |
|---|---|
日志 Failed to dial a quic connection ... no recent network activity,反复 Retrying |
QUIC 被拦。改 http2;若 TCP 预检也 FAIL,多半是本机 TUN 模式代理在劫流量——给 *.v2.argotunnel.com 加直连规则,或临时退出代理客户端验证(实测案例:关掉 TUN 立即恢复) |
| 域名打开报 1033 | 边缘找不到在线的连接器:cloudflared 没在跑、Token 不对、或进程被网络拦住根本没连上 |
| 域名打开报 502 | 隧道是通的,但 cloudflared 连不上源站:服务没启动、端口写错、或路由里的 service 地址与实际不符 |
Provided Tunnel token is not valid |
Token 复制不全/已失效。回后台重新复制;怀疑泄露就在后台轮换 |
| route dns 报记录已存在 | 该主机名已有 DNS 记录:确认无误后加 --overwrite-dns,或先删旧记录 |
| info 里挂着早已下线的连接器 | 旧进程没退干净或换机残留:tunnel cleanup 清理 |
| 服务装好但开机后隧道不在线 | 看服务日志(Windows 事件查看器/--logfile 指定的文件);先确认网络(尤其代理软件 TUN)没有把服务进程的出站劫走——服务与前台进程踩的是同一个坑 |
排障顺序建议:先 --hello-world 分清「隧道问题还是服务问题」→ 再看预检表定位网络层 → 最后 --loglevel debug 看细节。
noTLSVerify 只对内网自签临时用;长期服务给源站配正经证书或用 caPool。版本锚点:cloudflared 2026.10.7(2026-10-30 构建)。参数以 cloudflared <命令> --help 的实际输出为准;--protocol 为隐藏参数,经实测在该版本有效。官方文档:developers.cloudflare.com/cloudflare-one。