第一章:为什么需要零信任?
1.1 传统安全模型的崩溃
| 模型 | 假设 | 现实漏洞 |
|---|---|---|
| 城堡护城河 | 内网可信,外网危险 | 远程办公普及,内网设备不可控 |
| VPN + 防火墙 | 登录即信任 | 凭据泄露导致全系统沦陷 |
| 静态 RBAC | 角色 = 权限 | 无法应对“合法用户异常行为” |
典型案例:
- SolarWinds 供应链攻击:攻击者通过合法更新进入内网
- 某公司 HR 电脑中毒,窃取高管薪资数据
1.2 零信任核心原则(NIST SP 800-207)
- 所有数据源和计算服务都被视为资源
- 无论网络位置,所有通信都需安全
- 对资源的访问授权是动态策略驱动的
- 企业监控并测量资产完整性和安全性
- 所有资源认证和授权是强制的、动态的
关键转变:从“网络位置信任”→“身份+设备+上下文信任”
第二章:架构设计 —— BeyondCorp 模型拆解
Google 的 BeyondCorp 是零信任工业标准,其核心组件:
2.1 我们的简化实现
- 设备信任引擎:自研轻量设备注册服务
- 访问代理:Nginx + Lua(或 Envoy)
- 策略引擎:Open Policy Agent(OPA)
- 身份提供者:保留现有 JWT(兼容 OAuth2)
第三章:设备可信评估
3.1 设备标识与注册
每台设备需预先注册,获取唯一证书:
# 设备首次注册(由 IT 管理员触发) curl -X POST https://device-trust.example.com/register \ -H "Authorization: Bearer admin_token" \ -d '{ "device_id": "macos-abc123", "hardware_fingerprint": "sha256:...", "os_version": "macOS 14.2", "compliance_status": "patched" }'硬件指纹生成(前端 Electron / 后端脚本):
- macOS:
ioreg -rd1 -c IOPlatformExpertDevice | grep UUID- Windows:
wmic csproduct get uuid
3.2 设备证书颁发
注册成功后,签发短期 TLS 客户端证书:
# device_trust/cert_issuer.py from cryptography import x509 from cryptography.hazmat.primitives import hashes, serialization def issue_device_cert(device_id, public_key): subject = issuer = x509.Name([ x509.NameAttribute(x509.NameOID.COMMON_NAME, f"device:{device_id}") ]) cert = x509.CertificateBuilder().subject_name(subject) .issuer_name(issuer) .public_key(public_key) .serial_number(x509.random_serial_number()) .not_valid_before(datetime.utcnow()) .not_valid_after(datetime.utcnow() + timedelta(days=7)) # 7天有效期 .add_extension( x509.ExtendedKeyUsage([x509.OID_CLIENT_AUTH]), critical=True ) .sign(private_key, hashes.SHA256()) return cert3.3 前端(Vue)携带设备证书
Electron 应用可直接使用系统证书库。Web 应用需降级方案:
- 方案 A(推荐):仅支持企业托管设备(MDM),通过 SSO 传递设备 ID
- 方案 B:使用 Web Crypto API 生成设备密钥,存储于 IndexedDB(安全性较低)
本篇假设:前端为Electron 桌面应用或企业浏览器插件,可管理证书。
第四章:访问代理(Access Proxy)
4.1 Nginx + Lua 实现双向认证
# nginx.conf server { listen 443 ssl; ssl_certificate /path/to/server.crt; ssl_certificate_key /path/to/server.key; # 要求客户端提供证书 ssl_verify_client on; ssl_client_certificate /path/to/device_ca.pem; location /api/ { access_by_lua_block { local device_cn = ngx.var.ssl_client_s_dn:match("CN=device:(.+)") if not device_cn then ngx.exit(403) end -- 将设备 ID 注入请求头 ngx.req.set_header("X-Device-ID", device_cn) -- 调用 OPA 策略引擎 local opa_res = ngx.location.capture("/opa/allow", { method = ngx.HTTP_POST, body = json.encode({ input = { user = ngx.var.jwt_claim_sub, -- 从 JWT 提取 device = device_cn, path = ngx.var.uri, method = ngx.var.request_method, ip = ngx.var.remote_addr, time = os.time() } }) }) if opa_res.status ~= 200 or not cjson.decode(opa_res.body).result then ngx.exit(403) end } proxy_pass http://flask-api; proxy_set_header Host $host; } }4.2 代理职责
- 强制 mTLS(验证设备证书)
- 提取用户身份(从 JWT)
- 调用 OPA 决策
- 转发请求(附加
X-Device-ID供后端审计)
第五章:动态策略引擎 —— Open Policy Agent (OPA)
5.1 策略定义(Rego 语言)
# policies/access.rego package authz import input default allow = false # 规则1:设备必须合规 device_compliant { device_info := data.devices[input.device] device_info.compliance_status == "patched" } # 规则2:用户角色匹配 user_authorized { user_role := data.users[input.user].role required_role := role_for_path[input.path] user_role == required_role } # 规则3:工作时间访问(9AM-6PM) within_business_hours { hour := time.clock_hour(input.time) hour >= 9 and hour <= 18 } # 规则4:敏感操作需 MFA(如删除用户) needs_mfa { startswith(input.path, "/api/users/") and input.method == "DELETE" } # 主策略 allow { device_compliant user_authorized within_business_hours not needs_mfa # 若需要 MFA,则此处失败,触发二次认证 }5.2 策略数据(JSON)
// data/devices.json { "macos-abc123": { "compliance_status": "patched", "os": "macOS" }, "win-def456": { "compliance_status": "vulnerable", "os": "Windows" } } // data/users.json { "alice": { "role": "admin" }, "bob": { "role": "user" } } // role_for_path 映射 { "/api/users": "admin", "/api/profile": "user" }OPA 启动:
opa run --server --bundle policies/ --set=services.default.url=http://localhost:8181
第六章:持续会话验证与 MFA
6.1 敏感操作拦截
当 OPA 返回needs_mfa = true,访问代理返回 403 + 特殊头:
if needs_mfa { ngx.header["X-MFA-Required"] = "true"; ngx.exit(403); }6.2 前端处理 MFA 流程
// api/client.ts async function request(url: string, options: any) { try { return await fetch(url, options); } catch (err) { if (err.response?.headers.get('X-MFA-Required')) { // 触发 MFA 弹窗 const token = await showMfaPrompt(); // 重试请求,附带 MFA 令牌 return fetch(url, { ...options, headers: { ...options.headers, 'X-MFA-Token': token } }); } } }6.3 后端验证 MFA 令牌
# decorators/mfa_required.py def verify_mfa_token(f): @wraps(f) def decorated(*args, **kwargs): mfa_token = request.headers.get('X-MFA-Token') if not mfa_token or not redis.get(f"mfa:{mfa_token}"): abort(403, "MFA required") return f(*args, **kwargs) return decorated @app.route('/api/users/<int:id>', methods=['DELETE']) @verify_mfa_token @jwt_required() def delete_user(id): # 执行删除MFA 令牌生成:Totp / Push Notification / WebAuthn
第七章:服务间微隔离
7.1 服务网格集成(Istio / Linkerd)
在 Kubernetes 中,启用 mTLS:
# PeerAuthentication (Istio) apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default spec: mtls: mode: STRICT7.2 非 K8s 环境:自签名证书 + JWT Scope
Flask 服务间调用携带 Scope 限制的 JWT:
# service_a calls service_b token = create_jwt( sub="service_a", scope=["read:orders"] # 仅允许读订单 ) response = requests.get( "https://service-b/api/orders", headers={"Authorization": f"Bearer {token}"} )Service B 验证 Scope:
# service_b/utils/auth.py def require_scope(required_scope): def decorator(f): @wraps(f) def wrapper(*args, **kwargs): token = get_jwt() if required_scope not in token.get('scope', []): abort(403, "Insufficient scope") return f(*args, **kwargs) return wrapper return decorator @app.route('/api/orders') @require_scope('read:orders') def get_orders(): ...第八章:平滑迁移策略
8.1 渐进式启用
| 阶段 | 范围 | 策略 |
|---|---|---|
| 1 | 新功能(如支付) | 强制零信任 |
| 2 | 管理员后台 | 启用设备认证 + MFA |
| 3 | 全量用户 | 逐步替换 IP 白名单 |
8.2 兼容旧 RBAC
OPA 策略可桥接旧角色系统:
# 保留旧 role 字段,同时引入新属性 user_authorized { old_role := data.users[input.user].role new_policy := data.new_policies[input.path] new_policy.allowed_roles[_] == old_role }第九章:可观测性与审计
9.1 关键日志字段
每次访问记录:
user_iddevice_iddecision(allow/deny)policy_reason(如 "device non-compliant")mfa_used(true/false)
9.2 实时告警
- 异常设备登录:从未见过的
device_id - 策略拒绝激增:可能配置错误或攻击尝试
- MFA 绕过尝试:频繁 403 with
X-MFA-Required
第十章:挑战与最佳实践
10.1 用户体验平衡
- 设备注册流程:IT 自助门户 + 自动化(Intune/Jamf)
- MFA 频率:信任评分高则减少提示(如公司 WiFi + 合规设备)
10.2 性能考量
- OPA 缓存:对相同输入缓存决策结果(TTL 10s)
- 证书吊销:OCSP Stapling 或短有效期(<24h)
10.3 不是万能药
- 内部威胁:合法用户恶意操作仍需 DLP
- 供应链攻击:零信任不防依赖库后门
总结:安全不是功能,而是架构
零信任不是产品,而是一套持续验证的信任机制。