设置Zero Trust-Access Controls只允许everyone访问特定路径--验证所有其他

以cloudflare-imgbed为例,只有 a.sample.com/file 和file/文件夹/是图床需要的路径,其他的都是登录或管理页面。此前的设置是这样

因为目标设置最多5个(web界面),这样做显然不够,那就需要设置多个application,也会遇到规则优先级问题,而且繁琐。
所以下面换个思路,先设置子域名a.sample.com/ 全部需要认证(邮箱接码或github),再排除/file路径,允许everyone访问。

**CF改版前,可以在policy规则的选择设置路径** 现在的 Access 规则只认“人/客户端属性”(身份、IP、国家等),不再把 URL 路径当作一个可以灵活组合的“Require 条件”。

用 Cloudflare 官方推荐的另一种标准解法:拆分成两个独立的 Application,利用最具体路由优先(Most Specific Route Wins)的原则


:hammer_and_wrench: 设置两个 Application

我们需要在 Zero Trust 中建立 两个不同的应用,让 Cloudflare 自动根据 URL 的精确度去分流。

第一步:创建保护整个站点的兜底应用

  1. 在 Access → Applications 中,点击 Add an Application → 选择 Self-hosted
  2. Application domain 配置:
  • Domain: a.sample.com
  • Path: 留空不填(匹配除了 /file 之外的所有请求)。
  1. Policy 配置:
  • Action: 选择 Allow
  • Rules (Include): 配置你的允许条件(比如特定邮箱、特定 IP 组等)。保存。

第二步:创建专门放行 /file 的精确应用(关键)

  1. 再次点击 Add an Application → 选择 Self-hosted
  2. Application domain 配置:
  • Domain: a.sample.com
  • Path: 填写 file(如果该路径下还有子目录,填写 file*)。
  1. Policy 配置:
  • Action: 选择 Bypass(直接放行)。
  • Rules (Include): 选择 Everyone
    保存应用。
  1. 顺便把另一个cloudflare-imgbed使用worker安装会有个xxx.pages.dev域名,也放进目标域名里,或者弃用–新建一个应用全部阻断掉(记得path用星号,不能留空)。

配置完成后,在Cloudflare 仪表板的 Caching 里点configuration–Purge Everything(清理缓存),然后用浏览器的无痕模式测试,目标应该完美实现。只有图片路径/file能打开,其他都需要输入邮箱收码/github账号通过验证。

:light_bulb:

Cloudflare 边缘节点的路由匹配规则是:哪个应用配置的域名更具体,谁就优先生效。

  • 当有人访问 a.sample.com/file 时,由于第二个应用明确指定了 Path 是 file,比第一个留空的应用更精确,因此请求会被直接分流到第二个应用,触发 Bypass(直接放行)。
  • 当有人访问根目录 a.sample.coma.sample.com/login 时,由于不满足 file 路径,请求会滑落到第一个兜底应用,触发 Allow(拦截并要求验证)。


附:
Web 界面手动添加的硬限制:5 个
在 Cloudflare Access (Zero Trust) 中,同一个 Application 内部允许添加的 Destinations(目标域名/路径,即 Application domain)数量,在不同配置方式和账户类型下是有所不同的:

  1. Web 界面手动添加的硬限制:5 个

如果你是在 Cloudflare Zero Trust 的网页控制台上,通过手动点击 + Add domain 按钮来添加独立的域名或路径,Dashboard 界面有一个硬性的 UI 限制:最多只能添加 5 个 Destination 行。

当你加满 5 个之后,继续悬停在添加按钮上,鼠标会变成红色的禁止图标。
  1. 企业版或通过 API/Wrangler/Terraform 配置的软限制

如果你使用的是 Enterprise 账户,或者不是通过网页 UI,而是通过 Cloudflare API、Terraform 等自动化工具去下发配置,这个数量可以放宽。但即使这样,Cloudflare 官方也不建议在单个应用里塞入几十个不同的不相关域名,这会严重降低边缘规则引擎的检索效率,且容易导致 JWT Cookie 跨域签发混乱。

多学习了其他方案:grinning_face_with_smiling_eyes:


在反向代理(如 Caddy)或隧道方案中,实现“仅放行特定路径,其余全部拦截并要求验证”的 Zero Trust(零信任)访问控制,核心思想是利用第七层(HTTP 层)的路由匹配机制

对于这种需求,Caddy 的 handle 指令是最佳工具,因为 handle 块是互斥的(类似于 if...else if...else),这非常适合用来分离公开路径和受保护路径。

以下是几种不同场景下的具体实现方式:

1. Caddy + Basic Auth(基础认证)

这是最轻量级的做法,不需要额外部署认证服务。我们将特定路径(例如 /public/*/webhook)暴露给所有人,而根路径及其他所有路径必须输入密码。

example.com {
    # 1. 允许 everyone 访问的特定路径 (白名单)
    handle /public/* {
        reverse_proxy app_container:8080
    }
    
    handle /webhook {
        reverse_proxy app_container:8080
    }

    # 2. 捕获所有其他路径,并强制要求验证 (Zero Trust 屏障)
    handle {
        # 使用 caddy hash-password 生成密码的哈希值
        basicauth {
            admin JDJhJDE0JFR0c.........................
        }
        reverse_proxy app_container:8080
    }
}

2. Caddy + Forward Auth (单点登录 SSO)

如果你在内网环境中已经部署了类似 Authelia 或 Authentik 这样的身份验证提供程序(IdP),可以通过 forward_auth 指令实现更强大的零信任访问控制。未登录的用户在访问受保护路径时,会被重定向到 SSO 登录页面;而访问白名单路径时则直接通行。

example.com {
    # 1. 公开的 API 或静态资源路径
    handle /api/guest/* {
        reverse_proxy app_container:8080
    }
    
    handle /assets/* {
        reverse_proxy app_container:8080
    }

    # 2. 其他所有路径交由 SSO 拦截验证
    handle {
        # 以 Authelia 为例,发送验证请求
        forward_auth authelia:9091 {
            uri /api/verify?rd=https://auth.example.com
            copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
        }
        reverse_proxy app_container:8080
    }
}

配置要点:

  • 必须将公开的 handle 块放在前面。
  • 最后一个没有匹配条件的 handle {} 充当了“Catch-all(默认兜底)”的角色,确保任何未明确放行的路径都会撞上认证墙。

3. Mesh VPN(如 Headscale / Netmaker)结合 Caddy

如果你是在 Mesh VPN 网络内提供服务,网络层(Layer 3/4)的 ACL 只能控制“谁能访问哪个 IP 的哪个端口”,无法精细控制 HTTP 路径

要实现路径级别的零信任,标准架构是在 VPN 节点上运行 Caddy,将 Caddy 绑定到 VPN 接口(例如 wg0 的 IP),由 Caddy 负责第七层的路径阻断:

# 仅监听 Mesh VPN 分配的 IP (例如 Headscale 分配的 100.64.0.5)
100.64.0.5:80, 100.64.0.5:443 {
    tls internal # 使用内部证书

    handle /status {
        # 允许 VPN 内的所有机器免密查看状态
        reverse_proxy localhost:9090
    }

    handle {
        # 其他高级管理路径,即使在 VPN 内也需要二次验证(防范内网横向移动)
        basicauth {
            sysadmin JDJhJDE0JFR0c.........................
        }
        reverse_proxy localhost:9090
    }
}

4. Cloudflare Tunnels (Zero Trust 控制台实现)

如果你提到的“隧道”是指 Cloudflare Tunnels (cloudflared),这种基于路径的旁路(Bypass)策略不需要写配置文件,而是直接在 Cloudflare Zero Trust 的 Dashboard 中配置:

  1. 进入 Zero Trust DashboardAccessApplications
  2. 为你的域名创建一个应用(例如 app.example.com)。
  3. Policies(策略) 选项卡中,按顺序创建两条策略:
  • 策略 1 (优先级 1 - 白名单): * Action: Bypass

  • Rule: Path 匹配 /public* 或者你的特定路径。

  • Include: Everyone。

  • 策略 2 (优先级 2 - 拦截):

  • Action: Allow

  • Rule: Include 你的邮箱、IdP 组、或者特定的国家/地区。

  • (这意味着除了被 Bypass 放行的路径外,其余所有访问都会跳出 Cloudflare 的 Access 验证页面)

通过以上这几种方式,无论是使用轻量级的反向代理还是成熟的 SSO 架构,都能实现核心的“默认拒绝,显式放行”的路径级零信任控制。