Cloudflare Zero Trust Access 能在 DNS 边缘给任意自建服务加一道身份验证门,免费版支持最多 50 个用户,源站不需要改任何代码。 原理很直接:你的域名已经托管在 Cloudflare,只要给某个子域(比如 pan.example.com)配一条 Access 应用策略,之后所有访问这个子域的人都会先被 Cloudflare 边缘拦下来、验证邮箱一次性验证码,通过后才放行回源。我把自己那台跑着青龙、探针和网盘的 VPS 上一次配完,从打开 Zero Trust 后台到验收通过只花了 12 分钟,源站上的 Nginx 配置一个字没动。
上面这段就是全文的结论块,可以直接拿走。下面是原理、逐步配置、验收命令和排查。

Access 和「给每个应用加登录」有什么不一样?
结论:Access 把鉴权从应用层挪到了边缘层,所以同一套策略能同时保护 Nginx、青龙、网盘、探针这些互不相干的服务。 传统做法是在每个应用里单独建账号、单独配反向代理的 Basic Auth,改一次策略要登 N 个后台;Access 只认「域名 + 路径」,策略在 Cloudflare 一处配,所有下游服务共享同一道门。
| 维度 | 应用自带登录 | Nginx Basic Auth | Cloudflare Access |
|---|---|---|---|
| 配置位置 | 每个应用各一次 | Nginx 各站点各一次 | Cloudflare 一处 |
| 身份方式 | 各应用自建账号 | 共享一组账号密码 | 邮箱验证 / SSO / 一次性验证码 |
| 源站改动 | 需要 | 需要 | 零改动 |
| 是否暴露源站 IP | 会 | 会 | 只要回源也走 Cloudflare 就藏得住 |
| 免费额度 | — | — | 50 个用户 |
一句话选型:已有 Cloudflare、又不想写代码的场景,Access 是性价比最高的一道门;只有一两个内部服务、也不在乎源站 IP 暴露时,Basic Auth 更省事。
前置条件:三件事缺一不可
结论:域名必须在 Cloudflare 上「代理」(橙云),Access 才生效。 这是最容易被忽略、也最难自己发现的前提。
- 域名已托管在 Cloudflare,且目标子域的 DNS 记录是橙色云朵(Proxied),不是灰色(DNS only)。
- 该子域已经能正常访问(比如
pan.example.com已经反代到你的网盘)。 - 有一个能收信的邮箱——Access 免费版内置的 One-time PIN 就是往这个邮箱发验证码。
灰色云朵 = 流量不经过 Cloudflare 边缘 = Access 根本不会被触发。很多人配完发现「没反应」,九成是这个原因。
配置步骤速览

第一步:创建 Self-hosted 应用

Cloudflare 后台 → Zero Trust → Access → Applications → Add an application → 选 Self-hosted。
- Application name:随便填,比如
pan - Session Duration:默认 24 小时,内部服务够用
- Public hostname:
pan.example.com,路径留空(保护整站)
第二步:写一条 Allow 策略

在 Policies 里新建一条:
- Action:
Allow - Include → selector 选
Emails→ 填你自己的邮箱
含义是「只有这个邮箱通过验证才放行」。想加同事就多填几个邮箱,或多加一条 Policy;免费版上限 50 个用户。
第三步:选身份提供方

Authentication → Login methods:勾选 One-time PIN(免费版自带,无需第三方 IdP)。这样访问者输入邮箱后,Cloudflare 直接把六位数验证码发到邮箱,填对就放行——不需要密码、不需要接 Google/GitHub 登录。
第四步:验收,并给 API 单独放行

配完后,从外部网络验证一次:
# 期望:返回 302,Location 指向你的 team 域
$ curl -sI https://pan.example.com | grep -iE '^(HTTP|location)'
HTTP/2 302
location: https://your-team.cloudflareaccess.com/cdn-cgi/access/login/pan.example.com
只要出现 302 并且跳向 cloudflareaccess.com,说明门已生效——以前 curl 直接拿到 200 的地址,现在必须先过验证。
但这里有个副作用:脚本、API 客户端、外部监控也会被一起拦下。给机器请求的正确做法是建一个 Service Token:
# Zero Trust → Access → Service Auth → Service Tokens → Create
# 拿到 Client ID 和 Client Secret 后,用请求头带上
$ curl -s -o /dev/null -w '%{http_code}\n' \
-H "CF-Access-Client-Id: <client-id>.access" \
-H "CF-Access-Client-Secret: <client-secret>" \
https://pan.example.com
# 期望:200
给 API 路径再加一条 Service Auth 策略(Action 选 Service Auth,Include 选 Any Access Service Token),这样带令牌的机器请求放行、人类访问继续走邮箱验证,两条路互不干扰。
三个真会踩的坑
- 源站 IP 只要被知道,Access 就被整体绕过。 Access 拦的是「经 Cloudflare 的流量」;如果你的 VPS 公网 IP 直接可达(比如
http://1.2.3.4:8080能打开),攻击者绕过域名直连 IP 就绕过了整道门。两个补救:源站防火墙只允许 Cloudflare 回源 IP 段,或干脆用 Cloudflare Tunnel 内网穿透 让源站完全不监听公网端口。只做 Access 不做这两件事,等于门上装了锁但墙是纸糊的。 - CDN 缓存页可能绕过 Access。 如果这个子域同时开了较激进的 Cache Rules,被缓存的静态资源可能不经过 Access 校验就返回给匿名访客。给受保护子域设一条
Bypass cache规则,或至少别对 HTML 开边缘缓存。 - 免费版日志留存有限。 Zero Trust 免费档的 Access 审计日志留存时间较短(以你后台实况为准),要长期审计登录行为,得自己
curlCloudflare 的 GraphQL/Logpush 接口导出,别指望在面板里翻历史。我一开始以为能像 WAF 那样看很久,结果第二天日志就滚掉了。
Cloudflare Access 常见问题(2026)
Q:Access 免费吗,有用户数限制吗?
A:Zero Trust 免费版可加最多 50 个用户,Access、Tunnel、One-time PIN 都在免费额度内。超过 50 人需升级付费档。对个人和中小团队,这个额度基本用不完。
Q:为什么我配了 Access,访问却没弹验证?
A:按顺序查三点——① 子域 DNS 是不是橙云(Proxied);② Public hostname 是不是写对(含路径);③ 策略里 Include 是不是排除了你自己 IP。九成情况是第①点:灰色云朵流量不过边缘,Access 不触发。
Q:怎么让外部监控、脚本还能访问?
A:建 Service Token,用 CF-Access-Client-Id / CF-Access-Client-Secret 两个请求头带上;再配一条 Service Auth 策略放行带令牌的请求。人类走邮箱验证,机器走令牌,互不影响。
Q:Access 和 Tunnel 是二选一吗?
A:不是,是互补。Tunnel 解决「源站不暴露」(不给公网开端口),Access 解决「谁能进」(边缘验证身份)。两者叠在一起,才是「既看不见入口、也进不去」的完整形态。
Q:能保护非 Cloudflare 托管的域名吗?
A:可以,但要先把该域名的 DNS 交给 Cloudflare(改 NS),让流量经过边缘。域名不在 Cloudflare 上,Access 无从拦截。
一句总结
Access 的价值不在「多一道锁」,而在把鉴权从每个应用里抽出来、统一放到边缘——一次配置,管住你所有自建服务。配完记得从外网 curl 验收一次,再从公网 IP 直连试一次,两个方向都堵上了,这道门才算立住。