cloudflare-zero-trust
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCloudflare Zero Trust
Cloudflare Zero Trust
Secure access to internal services without VPNs using Cloudflare's Zero Trust platform (Access, Tunnel, Gateway, and WARP).
借助Cloudflare的零信任平台(Access、Tunnel、Gateway和WARP),无需VPN即可安全访问内部服务。
When to Use
适用场景
- Replacing VPN access to internal web applications, SSH, or RDP.
- Enforcing identity-aware access policies on internal tools (dashboards, admin panels).
- Exposing on-premises or private-network services securely to remote teams.
- Filtering DNS traffic to block malware, phishing, and shadow IT.
- Enforcing device posture checks (managed devices, OS version, disk encryption).
- 替代VPN访问内部Web应用、SSH或RDP。
- 对内部工具(仪表板、管理面板)实施基于身份识别的访问策略。
- 安全地向远程团队暴露本地或私有网络服务。
- 过滤DNS流量以阻止恶意软件、钓鱼攻击和影子IT。
- 强制执行设备状态检查(受管理设备、操作系统版本、磁盘加密)。
Prerequisites
前置条件
- Cloudflare account with Zero Trust plan (free tier supports up to 50 users).
- A domain on Cloudflare (for Access application hostnames).
- Identity provider configured (Google Workspace, Okta, Azure AD/Entra ID, GitHub).
- CLI installed on the server hosting internal services.
cloudflared
bash
undefined- 拥有Zero Trust计划的Cloudflare账户(免费版支持最多50名用户)。
- 在Cloudflare上托管的域名(用于Access应用的主机名)。
- 已配置身份提供商(Google Workspace、Okta、Azure AD/Entra ID、GitHub)。
- 在托管内部服务的服务器上安装了CLI。
cloudflared
bash
undefinedInstall cloudflared
Install cloudflared
macOS
macOS
brew install cloudflared
brew install cloudflared
Debian/Ubuntu
Debian/Ubuntu
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt update && sudo apt install -y cloudflared
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt update && sudo apt install -y cloudflared
Docker
Docker
docker pull cloudflare/cloudflared:latest
undefineddocker pull cloudflare/cloudflared:latest
undefinedCloudflare Tunnel Setup
Cloudflare Tunnel 配置
Tunnels create encrypted outbound connections from your infrastructure to Cloudflare's edge, eliminating the need to open inbound ports.
Tunnel会从你的基础设施到Cloudflare边缘创建加密的出站连接,无需开放入站端口。
Create and Configure a Tunnel
创建并配置Tunnel
bash
undefinedbash
undefinedAuthenticate with Cloudflare
登录Cloudflare
cloudflared tunnel login
cloudflared tunnel login
Create a named tunnel
创建命名Tunnel
cloudflared tunnel create internal-apps
cloudflared tunnel create internal-apps
This creates credentials at ~/.cloudflared/<TUNNEL_ID>.json
此操作会在 ~/.cloudflared/<TUNNEL_ID>.json 生成凭证
List tunnels
列出Tunnel
cloudflared tunnel list
cloudflared tunnel list
Route DNS to the tunnel (creates a CNAME record)
将DNS路由到Tunnel(创建CNAME记录)
cloudflared tunnel route dns internal-apps grafana.example.com
cloudflared tunnel route dns internal-apps wiki.example.com
cloudflared tunnel route dns internal-apps ssh.example.com
undefinedcloudflared tunnel route dns internal-apps grafana.example.com
cloudflared tunnel route dns internal-apps wiki.example.com
cloudflared tunnel route dns internal-apps ssh.example.com
undefinedTunnel Configuration File
Tunnel配置文件
yaml
undefinedyaml
undefined~/.cloudflared/config.yml
~/.cloudflared/config.yml
tunnel: <TUNNEL_ID>
credentials-file: /home/deploy/.cloudflared/<TUNNEL_ID>.json
ingress:
Grafana dashboard
- hostname: grafana.example.com service: http://localhost:3000
Internal wiki
- hostname: wiki.example.com service: http://localhost:8080 originRequest: noTLSVerify: true
SSH access via browser
- hostname: ssh.example.com service: ssh://localhost:22
Private network access (CIDR routing)
- hostname: internal.example.com service: http://10.0.0.0/24
Catch-all — required as the last rule
- service: http_status:404
undefinedtunnel: <TUNNEL_ID>
credentials-file: /home/deploy/.cloudflared/<TUNNEL_ID>.json
ingress:
Grafana仪表板
- hostname: grafana.example.com service: http://localhost:3000
内部Wiki
- hostname: wiki.example.com service: http://localhost:8080 originRequest: noTLSVerify: true
通过浏览器访问SSH
- hostname: ssh.example.com service: ssh://localhost:22
私有网络访问(CIDR路由)
- hostname: internal.example.com service: http://10.0.0.0/24
兜底规则——必须作为最后一条规则
- service: http_status:404
undefinedRun the Tunnel
运行Tunnel
bash
undefinedbash
undefinedRun in foreground (for testing)
前台运行(用于测试)
cloudflared tunnel run internal-apps
cloudflared tunnel run internal-apps
Install as a systemd service
安装为systemd服务
sudo cloudflared service install
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
sudo cloudflared service install
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
Or run via Docker
或通过Docker运行
docker run -d --name cloudflared
--restart unless-stopped
-v /home/deploy/.cloudflared:/etc/cloudflared
cloudflare/cloudflared:latest
tunnel run internal-apps
--restart unless-stopped
-v /home/deploy/.cloudflared:/etc/cloudflared
cloudflare/cloudflared:latest
tunnel run internal-apps
undefineddocker run -d --name cloudflared
--restart unless-stopped
-v /home/deploy/.cloudflared:/etc/cloudflared
cloudflare/cloudflared:latest
tunnel run internal-apps
--restart unless-stopped
-v /home/deploy/.cloudflared:/etc/cloudflared
cloudflare/cloudflared:latest
tunnel run internal-apps
undefinedDocker Compose with Tunnel
结合Docker Compose运行Tunnel
yaml
undefinedyaml
undefineddocker-compose.yml
docker-compose.yml
version: "3.8"
services:
cloudflared:
image: cloudflare/cloudflared:latest
restart: unless-stopped
command: tunnel run
environment:
- TUNNEL_TOKEN=${TUNNEL_TOKEN}
networks:
- internal
grafana:
image: grafana/grafana:latest
networks:
- internal
wiki:
image: requarks/wiki:2
networks:
- internal
networks:
internal:
driver: bridge
undefinedversion: "3.8"
services:
cloudflared:
image: cloudflare/cloudflared:latest
restart: unless-stopped
command: tunnel run
environment:
- TUNNEL_TOKEN=${TUNNEL_TOKEN}
networks:
- internal
grafana:
image: grafana/grafana:latest
networks:
- internal
wiki:
image: requarks/wiki:2
networks:
- internal
networks:
internal:
driver: bridge
undefinedAccess Policies
访问策略
Access policies control who can reach applications behind Cloudflare.
访问策略控制谁可以访问Cloudflare后方的应用程序。
Create an Access Application
创建Access应用
bash
undefinedbash
undefinedVia API — create a self-hosted application
通过API创建自托管应用
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/apps"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "name": "Grafana", "domain": "grafana.example.com", "type": "self_hosted", "session_duration": "12h", "auto_redirect_to_identity": true, "allowed_idps": ["<IDP_UUID>"] }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "name": "Grafana", "domain": "grafana.example.com", "type": "self_hosted", "session_duration": "12h", "auto_redirect_to_identity": true, "allowed_idps": ["<IDP_UUID>"] }'
undefinedcurl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/apps"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "name": "Grafana", "domain": "grafana.example.com", "type": "self_hosted", "session_duration": "12h", "auto_redirect_to_identity": true, "allowed_idps": ["<IDP_UUID>"] }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "name": "Grafana", "domain": "grafana.example.com", "type": "self_hosted", "session_duration": "12h", "auto_redirect_to_identity": true, "allowed_idps": ["<IDP_UUID>"] }'
undefinedPolicy Types and Examples
策略类型及示例
bash
undefinedbash
undefinedAllow policy — members of the engineering group
允许策略——仅工程组成员访问
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/apps/<APP_ID>/policies"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "name": "Engineering Team", "decision": "allow", "include": [ { "group": { "id": "<GROUP_UUID>" } } ], "require": [ { "login_method": { "id": "<MFA_METHOD_UUID>" } } ] }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "name": "Engineering Team", "decision": "allow", "include": [ { "group": { "id": "<GROUP_UUID>" } } ], "require": [ { "login_method": { "id": "<MFA_METHOD_UUID>" } } ] }'
undefinedcurl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/apps/<APP_ID>/policies"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "name": "Engineering Team", "decision": "allow", "include": [ { "group": { "id": "<GROUP_UUID>" } } ], "require": [ { "login_method": { "id": "<MFA_METHOD_UUID>" } } ] }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "name": "Engineering Team", "decision": "allow", "include": [ { "group": { "id": "<GROUP_UUID>" } } ], "require": [ { "login_method": { "id": "<MFA_METHOD_UUID>" } } ] }'
undefinedCommon Policy Patterns
常见策略模式
| Pattern | Include Rule | Require Rule |
|---|---|---|
| All employees | Email domain | - |
| Engineering only | Access Group "Engineering" | MFA |
| Contractors (time-limited) | Email list | Device posture |
| CI/CD automation | Service token | - |
| External partners | Specific emails | Country check |
| 模式 | 包含规则 | 要求规则 |
|---|---|---|
| 所有员工 | 邮箱域名 | - |
| 仅工程部门 | 访问组“Engineering” | 多因素认证(MFA) |
| 承包商(限时) | 邮箱列表 | 设备状态检查 |
| CI/CD自动化 | 服务令牌 | - |
| 外部合作伙伴 | 指定邮箱 | 地域检查 |
Service Tokens for Automation
用于自动化的服务令牌
bash
undefinedbash
undefinedCreate a service token for CI/CD
为CI/CD创建服务令牌
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/service_tokens"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"name": "github-actions-deploy"}'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"name": "github-actions-deploy"}'
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/access/service_tokens"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"name": "github-actions-deploy"}'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{"name": "github-actions-deploy"}'
Response includes Client ID and Client Secret
响应包含Client ID和Client Secret
Use in CI with headers:
在CI中通过以下头部使用:
CF-Access-Client-Id: <CLIENT_ID>
CF-Access-Client-Id: <CLIENT_ID>
CF-Access-Client-Secret: <CLIENT_SECRET>
CF-Access-Client-Secret: <CLIENT_SECRET>
```bash
```bashUse service token in CI/CD
在CI/CD中使用服务令牌
curl -H "CF-Access-Client-Id: $CF_CLIENT_ID"
-H "CF-Access-Client-Secret: $CF_CLIENT_SECRET"
https://grafana.example.com/api/health
-H "CF-Access-Client-Secret: $CF_CLIENT_SECRET"
https://grafana.example.com/api/health
undefinedcurl -H "CF-Access-Client-Id: $CF_CLIENT_ID"
-H "CF-Access-Client-Secret: $CF_CLIENT_SECRET"
https://grafana.example.com/api/health
-H "CF-Access-Client-Secret: $CF_CLIENT_SECRET"
https://grafana.example.com/api/health
undefinedDevice Posture Checks
设备状态检查
Enforce endpoint requirements before granting access.
在授予访问权限前强制执行终端要求。
Configure Posture Checks (Dashboard)
配置状态检查(控制台)
- Go to Settings > WARP Client > Device posture.
- Add checks:
- Disk encryption: Require FileVault (macOS) or BitLocker (Windows).
- OS version: Minimum macOS 14.0 or Windows 11.
- Firewall: Ensure host firewall is enabled.
- Crowdstrike/SentinelOne: Verify EDR agent is running.
- Reference posture checks in Access policies under Require rules.
- 进入 Settings > WARP Client > Device posture。
- 添加检查项:
- 磁盘加密:要求启用FileVault(macOS)或BitLocker(Windows)。
- 操作系统版本:最低要求macOS 14.0或Windows 11。
- 防火墙:确保主机防火墙已启用。
- Crowdstrike/SentinelOne:验证EDR代理正在运行。
- 在访问策略的Require规则中引用状态检查项。
Gateway DNS Filtering
Gateway DNS过滤
Block malicious domains and enforce acceptable use policies at the DNS level.
在DNS层面阻止恶意域名并执行可接受使用策略。
DNS Locations
DNS位置配置
bash
undefinedbash
undefinedConfigure DNS endpoints for offices or networks
为办公室或网络配置DNS端点
Dashboard: Gateway > DNS Locations > Add a location
控制台路径:Gateway > DNS Locations > Add a location
Assign the Gateway DNS IPs to your network's DNS resolver:
将Gateway DNS IP设置为网络的DNS解析器:
IPv4: 172.64.36.1, 172.64.36.2
IPv4: 172.64.36.1, 172.64.36.2
IPv6: 2606:4700:4700::1111
IPv6: 2606:4700:4700::1111
DoH: https://<UNIQUE_ID>.cloudflare-gateway.com/dns-query
DoH: https://<UNIQUE_ID>.cloudflare-gateway.com/dns-query
undefinedundefinedDNS Policies
DNS策略
bash
undefinedbash
undefinedCreate a DNS policy to block malware and phishing
创建DNS策略以阻止恶意软件和钓鱼攻击
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/gateway/rules"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "name": "Block Security Threats", "enabled": true, "action": "block", "traffic": "any(dns.security_category[*] in {80 83 131 134 151 153})", "filters": ["dns"] }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "name": "Block Security Threats", "enabled": true, "action": "block", "traffic": "any(dns.security_category[*] in {80 83 131 134 151 153})", "filters": ["dns"] }'
undefinedcurl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/gateway/rules"
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "name": "Block Security Threats", "enabled": true, "action": "block", "traffic": "any(dns.security_category[*] in {80 83 131 134 151 153})", "filters": ["dns"] }'
-H "Authorization: Bearer $CF_API_TOKEN"
-H "Content-Type: application/json"
-d '{ "name": "Block Security Threats", "enabled": true, "action": "block", "traffic": "any(dns.security_category[*] in {80 83 131 134 151 153})", "filters": ["dns"] }'
undefinedCommon DNS Policy Rules
常见DNS规则
| Rule Name | Traffic Expression | Action |
|---|---|---|
| Block malware | | Block |
| Block phishing | | Block |
| Block social media | | Block |
| Allow exceptions | | Allow |
| 规则名称 | 流量表达式 | 操作 |
|---|---|---|
| 阻止恶意软件 | | 阻止 |
| 阻止钓鱼攻击 | | 阻止 |
| 阻止社交媒体 | | 阻止 |
| 允许例外 | | 允许 |
WARP Client Deployment
WARP客户端部署
Deploy the Cloudflare WARP client to route traffic through Gateway.
bash
undefined部署Cloudflare WARP客户端以通过Gateway路由流量。
bash
undefinedMDM deployment — macOS configuration profile
MDM部署——macOS配置文件
Use Cloudflare's managed deployment:
使用Cloudflare的托管部署:
Dashboard: Settings > WARP Client > Device enrollment
控制台路径:Settings > WARP Client > Device enrollment
Manual enrollment
手动注册
1. Install WARP client from https://1.1.1.1
2. Click gear icon > Account > Login with Cloudflare Zero Trust
2. 点击齿轮图标 > Account > Login with Cloudflare Zero Trust
3. Enter your team name (from Settings > General)
3. 输入团队名称(来自Settings > General)
Verify WARP is connected
验证WARP已连接
Look for: warp=on
查找:warp=on
undefinedundefinedWARP Split Tunnels
WARP拆分隧道
bash
undefinedbash
undefinedConfigure split tunnels to exclude certain traffic from WARP
配置拆分隧道以排除特定流量不通过WARP
Dashboard: Settings > WARP Client > Device settings > Split Tunnels
控制台路径:Settings > WARP Client > Device settings > Split Tunnels
Exclude mode (default): WARP handles everything except listed IPs
排除模式(默认):WARP处理除列出IP外的所有流量
Include mode: WARP only handles listed IPs/domains
包含模式:WARP仅处理列出的IP/域名
Common exclusions:
常见排除项:
- Local network: 192.168.0.0/16, 10.0.0.0/8
- 本地网络:192.168.0.0/16, 10.0.0.0/8
- Video conferencing: zoom.us, *.teams.microsoft.com
- 视频会议:zoom.us, *.teams.microsoft.com
- Printer subnets
- 打印机子网
undefinedundefinedSSH and Browser-Based Terminal
SSH与基于浏览器的终端
yaml
undefinedyaml
undefinedIn cloudflared config.yml — expose SSH via browser rendering
在cloudflared配置文件中——通过浏览器渲染暴露SSH
ingress:
- hostname: ssh.example.com service: ssh://localhost:22
```bashingress:
- hostname: ssh.example.com service: ssh://localhost:22
```bashUsers access ssh.example.com in their browser
用户在浏览器中访问ssh.example.com
Cloudflare renders an in-browser terminal after Access authentication
通过Access认证后,Cloudflare会渲染浏览器内终端
Or use cloudflared on the client side for native SSH
或在客户端使用cloudflared进行原生SSH访问
cloudflared access ssh --hostname ssh.example.com
cloudflared access ssh --hostname ssh.example.com
Add to SSH config for seamless access
添加到SSH配置以实现无缝访问
~/.ssh/config
~/.ssh/config
Host ssh.example.com
Host ssh.example.com
ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h
ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h
undefinedundefinedTroubleshooting
故障排查
| Symptom | Cause | Fix |
|---|---|---|
Tunnel shows | | Check |
| Access returns 403 despite correct identity | Policy order or missing require rule | Policies are evaluated top-to-bottom; ensure Allow is above Block |
| WARP shows "Unable to connect" | Team name wrong or enrollment disabled | Verify team name in Settings > General; check enrollment permissions |
| Service token auth fails | Token expired or wrong headers | Regenerate token; use both |
| DNS filtering not blocking | Client not using Gateway DNS resolvers | Verify DNS is set to 172.64.36.1; check WARP is connected |
| Tunnel latency spikes | Tunnel running on overloaded host | Monitor |
| "No healthy origins" error | Backend service is down | Check the service at the configured ingress port; review |
| 症状 | 原因 | 解决方法 |
|---|---|---|
控制台中Tunnel显示 | | 检查 |
| 身份正确但Access返回403 | 策略顺序错误或缺少要求规则 | 策略按从上到下顺序评估;确保允许策略在阻止策略之上 |
| WARP显示“无法连接” | 团队名称错误或注册已禁用 | 在Settings > General中验证团队名称;检查注册权限 |
| 服务令牌认证失败 | 令牌过期或头部错误 | 重新生成令牌;同时使用 |
| DNS过滤未生效 | 客户端未使用Gateway DNS解析器 | 验证DNS已设置为172.64.36.1;检查WARP已连接 |
| Tunnel延迟骤增 | Tunnel运行在过载主机上 | 监控 |
| “无健康源站”错误 | 后端服务已宕机 | 检查配置的入口端口对应的服务;查看 |
Related Skills
相关技能
- cloudflare-workers - Edge compute behind Access policies
- dns-management - DNS routing and record management
- reverse-proxy - Alternative gateway patterns
- service-mesh - Internal service-to-service security
- cloudflare-workers - Access策略后的边缘计算
- dns-management - DNS路由与记录管理
- reverse-proxy - 替代网关模式
- service-mesh - 内部服务间安全