2020 年 12 月,SolarWinds 供应链攻击事件震动整个安全行业。攻击者通过篡改 SolarWinds Orion 软件更新包,在超过 18000 家客户的内网中植入后门。拿到内网访问权限后,攻击者在多个政府机构和大型企业的网络中横向移动(Lateral Movement)长达数月,窃取大量敏感数据。这些组织无一例外都部署了 VPN 和防火墙,但一旦攻击者突破了边界,内网几乎是一马平川。
这不是偶然。2013 年 Target 数据泄露、2017 年 Equifax 事件、2021 年 Colonial Pipeline 勒索攻击——攻击路径高度一致:突破边界,横向移动,窃取数据。边界安全模型(Perimeter Security Model)的根本假设是”内网可信、外网不可信”,而现实反复证明这个假设是错的。
这篇文章要回答一个核心问题:VPN 为什么不够?BeyondCorp 模型的核心假设和实现路径是什么?
一、问题场景
1.1 一个典型的 VPN 访问流程
假设一家拥有 5000 名员工的企业,工程师要从家中访问内部的代码仓库和 CI/CD 系统。传统方案的流程是:
- 员工在笔记本上启动 VPN 客户端,输入用户名和密码(可能加上一次性验证码)
- VPN 网关验证身份后,在员工设备和企业内网之间建立加密隧道
- 员工的流量通过隧道进入内网,此后可以访问内网中的任意资源
- VPN 会话通常持续数小时,期间不再重新验证
这个模型的安全假设很清晰:身份验证发生在边界,通过边界后即获得内网信任。
1.2 这个模型在哪里崩塌
问题出在第 3 步和第 4 步。
横向移动不受约束。 员工连上 VPN 后,通常可以访问远超其工作所需的网络资源。一个前端工程师可以 ping 到数据库服务器,一个实习生可以 SSH 到生产环境的跳板机。如果攻击者窃取了任何一个员工的 VPN 凭据,他获得的就是同等范围的内网访问权限。
一次性认证无法应对持续威胁。 VPN 连接建立后,通常在数小时内不会重新验证设备状态。在这段时间内,如果员工的设备被恶意软件感染、磁盘加密被关闭、或者安全补丁过期,VPN 网关一无所知。
不适应现代工作环境。 远程办公、BYOD(Bring Your Own Device)、多云环境、SaaS 服务——企业的”内网”边界已经模糊到几乎不存在。一个微服务可能运行在 AWS 上,数据库在 GCP 上,CI/CD 在 GitHub Actions 上,员工在咖啡店的公共 WiFi 上。“内网”和”外网”的二分法已经失去意义。
1.3 攻击面的量化
根据 Verizon 2023 年数据泄露调查报告(DBIR),83% 的数据泄露涉及外部攻击者,其中 49% 利用了被盗凭据。IBM 的 2023 年数据泄露成本报告显示,数据泄露的平均检测时间为 204 天,平均遏制时间为 73 天。横向移动的时间窗口以月计算。
这些数字说明一个事实:边界防御是必要的,但远远不够。安全判定不能只发生在入口,必须发生在每一次资源访问。
二、传统边界安全模型的局限
2.1 城堡与护城河
传统安全架构常被比喻为”城堡与护城河”(Castle and Moat)模型:
- 护城河 = 防火墙 + VPN + DMZ(非军事区)
- 城堡 = 内部网络中的所有资源
- 吊桥 = VPN 网关或防火墙规则
只要跨过护城河,你就进入了城堡,可以在里面自由走动。这个模型在企业网络边界清晰、所有资源都在物理数据中心内的时代是合理的。
2.2 模型失效的四个维度
| 维度 | 边界模型的假设 | 现实情况 |
|---|---|---|
| 网络拓扑 | 内外网有清晰物理边界 | 多云、混合云、SaaS 模糊了边界 |
| 信任传递 | 通过边界后即可信 | 被盗凭据、内部威胁、供应链攻击 |
| 访问粒度 | 网络级别的访问控制 | 需要应用级别、API 级别的细粒度控制 |
| 时间维度 | 一次认证长期有效 | 设备状态、用户行为随时可能变化 |
2.3 东西向流量的盲区
传统安全投入集中在南北向流量(North-South Traffic)——即客户端与服务端之间穿越防火墙的流量。但在微服务架构中,服务间调用(东西向流量,East-West Traffic)的规模远大于南北向。一个用户请求可能触发数十个服务间调用,这些调用通常在内网中以明文 HTTP 传输,没有身份验证,没有加密,没有审计日志。
攻击者一旦攻破任何一个服务,就可以伪装成该服务向其他服务发起请求。在没有服务间认证的环境中,被调用的服务无法区分”来自合法服务的请求”和”来自已被攻破服务的请求”。
三、零信任核心原则
3.1 基本定义
零信任(Zero Trust)不是一个产品,不是一个协议,而是一种安全架构范式。其核心假设是:
网络位置不构成信任依据。每一次资源访问都必须经过身份验证、授权检查和加密保护,无论请求来自”内网”还是”外网”。
这个概念最早由 Forrester Research 的 John Kindervag 在 2010 年提出。
3.2 NIST SP 800-207 核心原则
美国国家标准与技术研究院(NIST)在 2020 年发布的 SP 800-207 文档是零信任架构的权威参考。其核心原则包括:
所有数据源和计算服务都被视为资源。 不仅仅是服务器,还包括个人设备、SaaS 应用、API 端点。
无论网络位置如何,所有通信都必须受到保护。 内网通信也必须加密和认证。
对单个企业资源的访问是按会话授予的。 每次请求都需要独立评估,不能依赖之前的认证状态。
对资源的访问由动态策略决定。 策略引擎综合考虑用户身份、设备状态、行为模式、环境上下文。
企业监控和测量所有资产的安全状态。 持续评估设备合规性、漏洞状态、补丁级别。
所有资源认证和授权都是动态的,在允许访问之前严格执行。 信任不是静态分配的,而是持续评估的。
企业收集尽可能多的关于资产、网络和通信状态的信息,用于改善安全态势。
3.3 零信任的三大支柱
将 NIST 的原则归纳为可操作的工程支柱:
零信任三大支柱
├── 身份验证(Identity)
│ ├── 用户身份:多因素认证(MFA)、SSO
│ ├── 服务身份:mTLS、SPIFFE/SPIRE
│ └── 设备身份:设备证书、TPM 认证
├── 持续验证(Continuous Verification)
│ ├── 设备信任评分
│ ├── 上下文感知策略
│ └── 会话级别的动态评估
└── 最小权限(Least Privilege)
├── 微分段(Micro-segmentation)
├── 基于角色的访问控制(RBAC)
└── 即时访问(Just-In-Time Access)
四、BeyondCorp 模型
4.1 Google 为什么要做 BeyondCorp
2009 年底,Google 遭受了代号为”极光行动”(Operation Aurora)的高级持续性威胁(APT)攻击。攻击者利用 IE 浏览器的零日漏洞,渗透了 Google 的内部网络。这次事件直接推动了 Google 对自身安全架构的根本性反思。
Google 的核心洞察是:与其不断加固边界,不如直接取消边界的特殊地位。 如果内网和外网一样不可信,那安全控制就必须下沉到每一个请求。
BeyondCorp 项目从 2011 年启动,历时数年完成全公司迁移,最终发表了一系列论文记录这个过程。
4.2 BeyondCorp 架构组件
BeyondCorp 的核心架构包括以下组件:
graph TB
subgraph 用户侧
U[用户设备]
DC[设备证书]
UA[用户认证凭据]
end
subgraph BeyondCorp 控制平面
DI[设备清单服务<br/>Device Inventory]
TP[信任评估引擎<br/>Trust Engine]
AP[访问代理<br/>Access Proxy]
PE[策略引擎<br/>Policy Engine]
SSO[单点登录<br/>SSO]
end
subgraph 企业资源
APP1[内部 Web 应用]
APP2[代码仓库]
APP3[CI/CD 系统]
DB[(数据库)]
end
U -->|携带设备证书| AP
U -->|用户认证| SSO
SSO -->|身份令牌| AP
DC -->|设备状态| DI
DI -->|设备信任等级| TP
TP -->|信任评分| PE
AP -->|请求 + 上下文| PE
PE -->|允许/拒绝| AP
AP -->|经过认证的请求| APP1
AP -->|经过认证的请求| APP2
AP -->|经过认证的请求| APP3
AP -->|经过认证的请求| DB
4.3 核心设计决策
(1)取消 VPN,所有访问通过访问代理。 员工无论在办公室还是在家,都通过同一个访问代理(Access Proxy)访问内部资源。访问代理部署在公网,所有请求都必须经过它。这意味着:
- 办公室网络不再享有特殊信任
- 所有请求都必须携带用户身份和设备信息
- 网络位置不再是访问决策的输入因素
(2)设备清单与信任评估。 Google 维护一个覆盖全公司的设备清单数据库,记录每台设备的硬件信息、操作系统版本、补丁级别、磁盘加密状态、安全软件运行状态等。信任评估引擎根据这些信息为每台设备计算一个信任等级(Trust Tier)。
(3)动态访问策略。 策略引擎根据以下输入做出访问决策:
- 用户身份(通过 SSO 验证)
- 设备信任等级(通过设备清单和信任引擎计算)
- 请求的资源敏感级别
- 时间、地点等上下文信息
例如:一个工程师可以在公司配发的、完全合规的笔记本上访问生产数据库,但在个人手机上只能查看公司 Wiki。同一个用户,不同设备,不同权限。
4.4 迁移路径
Google 的迁移不是一夜完成的,而是遵循了渐进式策略:
- 并行运行阶段。 VPN 和 BeyondCorp 访问代理同时运行,员工可以选择任一方式访问资源。
- 监控与对比阶段。 对比两种路径的访问日志,识别仅通过 VPN 可达的资源并迁移。
- 逐步收紧阶段。 将越来越多的资源设置为”仅通过访问代理可达”。
- 关闭 VPN 阶段。 当所有关键资源都通过访问代理可达后,关闭 VPN。
这个过程中最大的挑战不是技术,而是用户习惯迁移和遗留系统适配。
五、SPIFFE/SPIRE 与 mTLS
5.1 服务身份的困境
在零信任架构中,不仅用户需要身份,服务也需要身份。 当服务 A 调用服务 B 时,B 需要验证”这个请求确实来自 A,而不是来自一个伪装成 A 的攻击者”。
传统方案的问题:
- IP 地址不可靠。 在容器化和编排环境中,IP 地址是动态分配的,不能作为身份标识。
- 共享密钥不安全。 硬编码的 API Key 或 Token 容易泄露,且无法实现细粒度的身份区分。
- 手动证书管理不可扩展。 在数千个服务实例的环境中,手动签发和轮换 X.509 证书是不可行的。
5.2 SPIFFE 标准
SPIFFE(Secure Production Identity Framework for Everyone)是一个开放标准,定义了服务身份的格式和验证方式。
SPIFFE ID 格式:
spiffe://trust-domain/path
示例:
spiffe://production.example.com/payment-service
spiffe://staging.example.com/ns/default/sa/order-service
spiffe://example.com/region/us-east-1/service/auth
SPIFFE ID 是一个 URI,由三部分组成:
spiffe://:协议前缀trust-domain:信任域,通常对应一个组织或环境/path:标识具体的工作负载(Workload),路径格式由组织自定义
SVID(SPIFFE Verifiable Identity Document) 是 SPIFFE ID 的载体,有两种形式:
- X.509-SVID: 将 SPIFFE ID 编码在 X.509 证书的 SAN(Subject Alternative Name)扩展字段中,用于 mTLS 场景。
- JWT-SVID: 将 SPIFFE ID 编码在 JWT 的
sub声明中,用于 HTTP 头部传递场景。
5.3 SPIRE 架构
SPIRE(SPIFFE Runtime Environment)是 SPIFFE 标准的参考实现,负责 SVID 的签发、分发和轮换。
graph TB
subgraph SPIRE Server
CA[证书颁发机构<br/>CA]
REG[注册表<br/>Registration Entries]
DS[数据存储<br/>DataStore]
NA[节点认证器<br/>Node Attestor]
end
subgraph 工作节点 1
AG1[SPIRE Agent]
WA1[工作负载认证器<br/>Workload Attestor]
W1A[工作负载 A<br/>payment-service]
W1B[工作负载 B<br/>order-service]
end
subgraph 工作节点 2
AG2[SPIRE Agent]
WA2[工作负载认证器<br/>Workload Attestor]
W2A[工作负载 C<br/>user-service]
end
CA -->|签发节点证书| AG1
CA -->|签发节点证书| AG2
NA -->|验证节点身份| AG1
NA -->|验证节点身份| AG2
REG -->|注册信息| AG1
REG -->|注册信息| AG2
DS -->|持久化| REG
AG1 -->|签发 SVID| W1A
AG1 -->|签发 SVID| W1B
WA1 -->|验证工作负载身份| W1A
WA1 -->|验证工作负载身份| W1B
AG2 -->|签发 SVID| W2A
WA2 -->|验证工作负载身份| W2A
W1A <-->|mTLS| W2A
W1B <-->|mTLS| W2A
SPIRE Server 是控制平面,负责:
- 管理证书颁发机构(CA),签发和轮换根证书
- 维护注册表,记录哪些工作负载对应哪些 SPIFFE ID
- 通过节点认证器(Node Attestor)验证 Agent 所在节点的身份
SPIRE Agent 运行在每个工作节点上,负责:
- 向 Server 注册自身节点
- 通过工作负载认证器(Workload Attestor)识别本节点上的工作负载
- 向工作负载签发 SVID
- 自动轮换即将过期的证书
工作负载认证(Workload Attestation) 是 SPIRE 的核心机制。Agent 需要确认”请求 SVID 的进程确实是它声称的工作负载”。认证方式包括:
- Unix 认证器: 基于 PID、UID、GID
- Kubernetes 认证器: 基于 Pod 的 ServiceAccount、Namespace、Label
- Docker 认证器: 基于容器镜像哈希
- AWS 认证器: 基于 EC2 实例身份文档
5.4 SPIRE 配置示例
SPIRE Server 配置:
server {
bind_address = "0.0.0.0"
bind_port = "8081"
trust_domain = "production.example.com"
data_dir = "/opt/spire/data/server"
log_level = "INFO"
ca_ttl = "72h"
default_x509_svid_ttl = "1h"
default_jwt_svid_ttl = "5m"
}
plugins {
DataStore "sql" {
plugin_data {
database_type = "postgres"
connection_string = "dbname=spire host=db.internal sslmode=verify-full"
}
}
NodeAttestor "k8s_psat" {
plugin_data {
clusters = {
"production" = {
service_account_allow_list = ["spire:spire-agent"]
kube_config_file = ""
audience = ["spire-server"]
}
}
}
}
KeyManager "disk" {
plugin_data {
keys_path = "/opt/spire/data/server/keys.json"
}
}
}
注册工作负载条目:
# 注册 payment-service
spire-server entry create \
-spiffeID spiffe://production.example.com/payment-service \
-parentID spiffe://production.example.com/node/k8s-node-01 \
-selector k8s:ns:payment \
-selector k8s:sa:payment-service \
-ttl 3600
# 注册 order-service
spire-server entry create \
-spiffeID spiffe://production.example.com/order-service \
-parentID spiffe://production.example.com/node/k8s-node-01 \
-selector k8s:ns:order \
-selector k8s:sa:order-service \
-ttl 36005.5 mTLS 大规模部署
双向 TLS(mutual TLS,mTLS)是零信任服务间通信的基石。与普通 TLS 不同,mTLS 要求客户端和服务端都出示证书,双向验证身份。
Envoy 代理的 mTLS 配置:
# Envoy 作为 sidecar 代理的 mTLS 配置
static_resources:
listeners:
- name: mtls_listener
address:
socket_address:
address: 0.0.0.0
port_value: 8443
filter_chains:
- transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
require_client_certificate: true
common_tls_context:
tls_certificate_sds_secret_configs:
- name: "spiffe://production.example.com/payment-service"
sds_config:
api_config_source:
api_type: GRPC
grpc_services:
- envoy_grpc:
cluster_name: spire_agent
combined_validation_context:
default_validation_context:
match_typed_subject_alt_names:
- san_type: URI
matcher:
prefix: "spiffe://production.example.com/"
validation_context_sds_secret_config:
name: "spiffe://production.example.com"
sds_config:
api_config_source:
api_type: GRPC
grpc_services:
- envoy_grpc:
cluster_name: spire_agent
filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: local_service
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: spire_agent
connect_timeout: 0.25s
http2_protocol_options: {}
load_assignment:
cluster_name: spire_agent
endpoints:
- lb_endpoints:
- endpoint:
address:
pipe:
path: /run/spire/sockets/agent.sock
- name: local_service
connect_timeout: 0.25s
type: STATIC
load_assignment:
cluster_name: local_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8080证书轮换策略:
证书生命周期管理是 mTLS 大规模部署的关键挑战。SPIRE 的默认策略是:
- X.509 SVID 默认有效期 1 小时
- Agent 在证书剩余生命周期不足一半时自动轮换
- 轮换过程对工作负载透明——SPIRE Agent 通过 Workload API(一个 Unix Domain Socket)向工作负载推送新证书
证书生命周期
|←———— 1h ————→|
|——有效——|——轮换窗口——|——过期——|
↑
Agent 发起轮换
(剩余 < 50%)
这意味着在任何时刻,集群中所有证书的最大年龄不超过 1 小时。即使某个证书被泄露,攻击窗口也被限制在分钟级别。
六、持续身份验证
6.1 一次性认证的问题
传统认证模型是”认证一次,信任一段时间”:用户登录后获得一个有效期为数小时的会话令牌(Session Token),在此期间所有请求都被视为已认证。
这个模型的隐含假设是:用户在认证时刻的安全状态在整个会话期间保持不变。但这个假设在以下场景中不成立:
- 用户认证后,设备感染了恶意软件
- 用户的账号凭据在认证后被泄露到暗网
- 用户从安全的办公室网络切换到不安全的公共 WiFi
- 用户的行为模式突然发生异常(例如从未登录过的地理位置大量下载数据)
6.2 设备信任评分
零信任架构引入设备信任评分(Device Trust Score)机制,持续评估设备的安全状态:
设备信任评分模型
输入维度 权重 评分规则
─────────────────────────────────────────────────────
操作系统补丁级别 25% 最新 = 100,落后 1 个版本 = 70,落后 2+ = 30
磁盘加密状态 20% 启用 = 100,未启用 = 0
防病毒软件运行状态 15% 运行且更新 = 100,运行但过期 = 50,未运行 = 0
屏幕锁定策略 10% 启用(< 5min)= 100,启用(> 5min)= 60,未启用 = 0
设备是否企业管理 15% MDM 管理 = 100,BYOD 已注册 = 60,未知设备 = 0
最近安全事件 15% 无事件 = 100,低风险事件 = 50,高风险事件 = 0
─────────────────────────────────────────────────────
综合评分 = Σ(维度得分 × 权重)
信任等级映射:
90-100:完全信任 → 可访问所有资源
70-89 :基本信任 → 可访问非敏感资源
50-69 :有限信任 → 仅可访问公开资源
< 50 :不信任 → 拒绝访问,要求修复设备
6.3 上下文感知访问策略
上下文感知访问策略(Context-Aware Access Policy)将访问决策从简单的”用户+密码”扩展为多维度的实时评估。以下是一个策略引擎的伪代码示例:
class AccessDecision:
ALLOW = "allow"
DENY = "deny"
STEP_UP = "step_up" # 要求额外认证
def evaluate_access(request: AccessRequest) -> AccessDecision:
user = request.user
device = request.device
resource = request.resource
context = request.context
# 1. 基本身份验证
if not user.is_authenticated:
return AccessDecision.DENY
# 2. 设备信任检查
device_score = compute_device_trust_score(device)
if device_score < 50:
return AccessDecision.DENY
# 3. 资源敏感级别 vs 设备信任
if resource.sensitivity == "HIGH" and device_score < 90:
return AccessDecision.STEP_UP
# 4. 地理位置异常检测
if is_impossible_travel(user.last_location, context.location, context.timestamp):
return AccessDecision.DENY
# 5. 行为异常检测
if is_anomalous_behavior(user, request):
return AccessDecision.STEP_UP
# 6. 时间策略
if resource.requires_business_hours and not is_business_hours(context.timestamp):
if resource.sensitivity == "HIGH":
return AccessDecision.DENY
return AccessDecision.STEP_UP
# 7. 最小权限检查
if not user.has_permission(resource, request.action):
return AccessDecision.DENY
return AccessDecision.ALLOW
def is_impossible_travel(
last_loc: Location, current_loc: Location, timestamp: datetime
) -> bool:
"""检测不可能的旅行:两次登录的地理距离除以时间间隔超过合理速度"""
distance_km = haversine(last_loc, current_loc)
time_hours = (timestamp - last_loc.timestamp).total_seconds() / 3600
if time_hours == 0:
return distance_km > 0
speed_kmh = distance_km / time_hours
return speed_kmh > 1000 # 超过 1000 km/h 视为异常6.4 持续重新评估 vs 一次性认证
| 特性 | 一次性认证 | 持续重新评估 |
|---|---|---|
| 认证频率 | 登录时一次 | 每次请求或定期(如每 5 分钟) |
| 设备状态感知 | 仅登录时检查 | 持续监控 |
| 异常响应速度 | 等会话过期 | 实时降级或撤销 |
| 用户体验影响 | 低(认证后无感) | 可能触发二次认证 |
| 实现复杂度 | 低 | 高(需要策略引擎、设备代理等) |
| 安全窗口 | 数小时 | 分钟级 |
工程上的平衡点是:对低敏感度资源使用较长的评估间隔(如 15 分钟),对高敏感度资源使用较短的间隔(如每次请求),避免对用户体验造成过大影响。
七、微分段
7.1 什么是微分段
微分段(Micro-segmentation)是将网络划分为细粒度的安全区域,每个区域独立执行访问控制策略。与传统的
VLAN
分段不同,微分段可以精确到单个工作负载级别——例如,只允许
order-service 访问 payment-service
的 /charge 端点,拒绝所有其他服务的访问。
微分段的核心目标是限制爆炸半径(Blast Radius)。当攻击者攻破一个服务后,微分段阻止其横向移动到其他服务。
7.2 Kubernetes NetworkPolicy
Kubernetes 原生支持通过 NetworkPolicy 资源实现网络层面的微分段。以下是一个典型的配置:
# 默认拒绝所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
---
# 只允许 order-service 访问 payment-service
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-order-to-payment
namespace: production
spec:
podSelector:
matchLabels:
app: payment-service
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: order-service
ports:
- protocol: TCP
port: 8443
---
# 只允许 payment-service 访问数据库
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-payment-to-db
namespace: production
spec:
podSelector:
matchLabels:
app: payment-db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: payment-service
ports:
- protocol: TCP
port: 5432注意事项: Kubernetes NetworkPolicy 只在网络层(L3/L4)生效,无法控制 HTTP 方法、路径等应用层属性。要实现应用层微分段,需要服务网格(Service Mesh)。
7.3 服务网格中的微分段
以 Istio 为例,其 AuthorizationPolicy 可以实现 L7 级别的精细控制:
# 只允许 order-service 对 payment-service 的 POST /charge 端点发起请求
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: payment-service-policy
namespace: production
spec:
selector:
matchLabels:
app: payment-service
action: ALLOW
rules:
- from:
- source:
principals:
- "cluster.local/ns/production/sa/order-service"
to:
- operation:
methods: ["POST"]
paths: ["/charge", "/refund"]
- from:
- source:
principals:
- "cluster.local/ns/production/sa/admin-service"
to:
- operation:
methods: ["GET"]
paths: ["/transactions/*"]
---
# 默认拒绝所有未明确允许的请求
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: default-deny
namespace: production
spec:
{}这个配置实现了:
order-service只能向payment-service发送POST /charge和POST /refund请求admin-service只能向payment-service发送GET /transactions/*请求- 所有其他来源和路径的请求被拒绝
7.4 微分段的实施策略
从零开始实施微分段的渐进路径:
第一阶段:可观测性优先。 在不阻断任何流量的前提下,部署网络监控工具(如 Cilium Hubble 或 Calico Enterprise 的流量日志),记录所有服务间的通信模式。目标是画出一张完整的服务间调用关系图。
第二阶段:粗粒度分段。
按命名空间或业务域划分安全区域。例如,禁止 dev
命名空间的服务访问 production
命名空间的服务,禁止 frontend
命名空间的服务直接访问数据库命名空间。
第三阶段:细粒度策略。 在每个安全区域内部,按服务级别制定白名单策略。这一阶段的工作量最大,需要逐个服务梳理其合法的上下游依赖。
第四阶段:应用层策略。 在服务网格中配置 L7 级别的策略,控制到 HTTP 方法和路径级别。
每个阶段都应该在审计模式(Audit Mode)下运行足够长的时间,确认不会误杀合法流量后再切换到强制模式(Enforce Mode)。
八、工程案例
8.1 背景
某金融科技公司(以下称 FinCo)拥有约 800 名工程师,核心业务系统由 200 多个微服务构成,部署在 AWS 和自建数据中心的混合云环境中。2022 年之前,FinCo 的安全架构是典型的边界模型:
- 员工通过 Cisco AnyConnect VPN 接入企业内网
- 内网服务间通信使用明文 HTTP
- 访问控制主要依赖 AWS 安全组(Security Group)和网络 ACL
- 身份认证使用 LDAP + RADIUS
8.2 迁移动因
2022 年 Q1,FinCo 经历了一次安全事件:一名员工的 VPN 凭据被钓鱼攻击窃取,攻击者通过 VPN 进入内网后,横向移动到了一台开发环境的数据库服务器。虽然该数据库不包含生产数据,但事件暴露了多个架构缺陷:
- VPN 凭据泄露后,攻击者可以访问大量无关资源
- 内网服务间无认证,攻击者可以模拟任何服务发起请求
- 安全组规则过于宽松,多个服务的端口对整个 VPC 开放
- 缺乏东西向流量的审计日志
公司决定在 12 个月内完成向零信任架构的迁移。
8.3 实施过程
Phase 1(第 1-3 月):身份基础设施建设
- 部署 SPIRE 集群,为所有 Kubernetes 工作负载签发 SPIFFE ID
- 将用户认证从 LDAP 迁移到支持 MFA 的 IdP(Identity Provider)——选择了 Okta
- 在 AWS 上部署设备信任代理,采集员工设备的安全状态
SPIRE 部署的具体配置:
# SPIRE Server Helm Chart values
spireServer:
replicas: 3
trustDomain: "finco.internal"
ca:
ttl: "720h"
defaultSVIDTTL: "1h"
dataStore:
type: "postgres"
nodeAttestor:
type: "k8s_psat"
keyManager:
type: "aws_kms"
config:
region: "us-east-1"
keyId: "alias/spire-root-ca"
spireAgent:
workloadAttestors:
- type: "k8s"
config:
skipKubeletVerification: falsePhase 2(第 4-6 月):mTLS 部署
- 在 Kubernetes 集群中部署 Istio 服务网格
- 将 Istio 配置为
STRICTmTLS 模式,强制所有服务间通信加密 - 使用 SPIRE 作为 Istio 的外部 CA,统一证书管理
# Istio PeerAuthentication - 强制 mTLS
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mtls:
mode: STRICT逐步启用 mTLS 的过程:
- 先以
PERMISSIVE模式运行,允许明文和 mTLS 混合通信 - 监控流量日志,识别仍在使用明文的服务并逐个修复
- 确认所有服务都支持 mTLS 后,切换到
STRICT模式
Phase 3(第 7-9 月):微分段与持续验证
- 使用 Calico Enterprise 实施 Kubernetes NetworkPolicy
- 在 Istio 中配置 AuthorizationPolicy,实现 L7 微分段
- 部署上下文感知访问代理(选择了 Cloudflare Access),替代 VPN
Phase 4(第 10-12 月):VPN 退役与监控完善
- 将所有内部 Web 应用迁移到 Cloudflare Access 后面
- 对无法迁移的遗留系统,通过专用的零信任网关提供访问
- 关闭 VPN 服务
- 部署 SIEM(安全信息与事件管理)系统,聚合所有访问日志
8.4 量化结果
| 指标 | 迁移前 | 迁移后 |
|---|---|---|
| 平均攻击面(可达服务数) | 187(VPN 连接后可达) | 3-5(按角色授权) |
| 服务间通信加密率 | 12% | 100% |
| 身份认证覆盖率 | 仅南北向 | 南北向 + 东西向 |
| 安全事件平均检测时间 | 72 小时 | 4 小时 |
| VPN 相关工单数 | 约 120 件/月 | 0(VPN 已退役) |
| 证书管理人力投入 | 2 人全职 | 0(SPIRE 自动化) |
8.5 踩坑与教训
教训 1:遗留系统是最大的阻力。 FinCo 有 15 个遗留服务不支持 TLS,需要通过 sidecar 代理模式在应用无感知的情况下添加 mTLS 能力。其中 3 个使用了自定义 TCP 协议的服务需要编写专用的协议适配层。
教训 2:微分段策略不能一步到位。 初期团队试图一次性为所有 200 个服务编写精确的 NetworkPolicy,导致规则冲突、合法流量被误杀。后来改为按业务域分批实施,每批先观察两周再强制执行。
教训 3:设备信任评分需要校准。 初始评分模型过于严格,导致 30% 的工程师设备被标记为”不信任”。原因是评分模型没有考虑 macOS 和 Linux 在安全策略上的差异。经过三轮校准后,误判率降至 2% 以下。
教训 4:需要为开发者提供良好的调试体验。 微分段上线后,开发者在调试服务间调用问题时频繁遇到”请求被拒绝但不知道原因”的困境。团队后来为 Istio 的 AuthorizationPolicy 增加了拒绝原因日志,并开发了一个内部工具,让开发者可以查询”我的服务能否访问目标服务的某个端点”。
九、选型对比
9.1 VPN vs 零信任
| 对比维度 | VPN 边界模型 | 零信任架构 |
|---|---|---|
| 信任模型 | 通过边界后信任内网 | 永不信任,始终验证 |
| 认证粒度 | 网络级(IP/端口) | 应用级(用户+设备+上下文) |
| 横向移动防护 | 弱(通过后几乎不受限) | 强(微分段+最小权限) |
| 远程办公支持 | 依赖 VPN 隧道,性能瓶颈 | 原生支持,不依赖隧道 |
| 多云适应性 | 差(需要每个云单独建 VPN) | 好(基于身份而非网络) |
| 部署复杂度 | 低(成熟方案) | 高(需要身份基础设施、策略引擎等) |
| 用户体验 | VPN 连接延迟,断线重连 | 通常更流畅(无需手动连接 VPN) |
| 审计能力 | 有限(仅 VPN 网关日志) | 全面(每次请求级别) |
| 遗留系统兼容 | 好(透明隧道) | 需要适配(sidecar 代理等) |
| 实施成本 | 低 | 高(尤其是初始投入) |
| 运维成本 | 中(VPN 网关运维) | 中(自动化后降低) |
| 抗 APT 能力 | 弱 | 强 |
9.2 服务网格方案对比
在实现服务间零信任通信时,主流方案的对比:
| 特性 | Istio | Linkerd | Cilium |
|---|---|---|---|
| mTLS 支持 | 自动 mTLS | 自动 mTLS | 基于 WireGuard 的加密 |
| SPIFFE 兼容 | 是(内置或外部 CA) | 是(内置) | 否(使用自有身份模型) |
| L7 访问控制 | AuthorizationPolicy | Server/ServerAuthorization | CiliumNetworkPolicy |
| 性能开销 | 较高(Envoy sidecar) | 较低(Rust 微代理) | 最低(eBPF 内核级) |
| 资源消耗 | 约 50MB/sidecar | 约 10MB/sidecar | 无 sidecar |
| 学习曲线 | 陡峭 | 平缓 | 中等 |
| 社区生态 | 最大 | 中等 | 快速增长 |
| 适用场景 | 功能需求复杂 | 追求简洁和低开销 | 高性能、大规模集群 |
9.3 零信任方案的渐进路径
不同规模组织的推荐实施路径:
小型团队(< 50 人)
├── 第 1 步:SSO + MFA(如 Okta、Google Workspace)
├── 第 2 步:零信任访问代理(如 Cloudflare Access、Tailscale)
└── 第 3 步:Kubernetes NetworkPolicy
中型团队(50-500 人)
├── 第 1 步:SSO + MFA + 设备管理
├── 第 2 步:服务网格 mTLS(Linkerd 或 Istio)
├── 第 3 步:微分段(NetworkPolicy + AuthorizationPolicy)
└── 第 4 步:零信任访问代理替代 VPN
大型组织(500+ 人)
├── 第 1 步:身份基础设施统一(SPIFFE/SPIRE)
├── 第 2 步:服务网格全面部署
├── 第 3 步:设备信任评分 + 持续身份验证
├── 第 4 步:全面微分段
├── 第 5 步:VPN 退役
└── 第 6 步:SIEM 集成 + 自动化响应
十、总结
零信任不是一个可以”安装”的产品,而是一种需要持续投入的安全架构范式。它的核心思想可以归结为三句话:
- 身份是新的边界。 网络位置不再是信任的依据,用户身份、服务身份和设备身份才是。
- 验证必须持续。 一次性认证不够,必须在整个会话生命周期内持续评估安全状态。
- 权限必须最小。 微分段将攻击的爆炸半径限制在最小范围内。
工程上,零信任的实施不是一蹴而就的。从 SSO + MFA 开始,逐步引入 mTLS、SPIFFE/SPIRE、微分段和持续身份验证。每一步都要在安全收益和实施成本之间找到平衡。
最后一个提醒:零信任架构的最大敌人不是技术复杂性,而是组织惯性。技术组件可以逐步部署,但”内网可信”的心智模型需要从上到下的认知转变。在 SolarWinds 事件之后,美国政府发布了行政命令(EO 14028),要求联邦机构在规定时间内采用零信任架构——有时候推动变革需要一次足够大的事件。
上一篇:授权架构
下一篇:API 安全
参考资料
- Rose, S., Borchert, O., Mitchell, S., & Connelly, S. (2020). Zero Trust Architecture. NIST Special Publication 800-207.
- Ward, R., & Beyer, B. (2014). BeyondCorp: A New Approach to Enterprise Security. ;login:, 39(6), 6-11.
- Osborn, B., McWilliams, J., Beyer, B., & Saltonstall, M. (2016). BeyondCorp: Design to Deployment at Google. ;login:, 41(1), 28-34.
- Escobedo, V., Beyer, B., Saltonstall, M., & Peck, J. (2017). BeyondCorp: The Access Proxy. ;login:, 42(4), 28-33.
- SPIFFE Project. (2024). SPIFFE: Secure Production Identity Framework for Everyone. https://spiffe.io/
- CNCF. (2024). SPIRE Documentation. https://spiffe.io/docs/latest/spire-about/
- Kindervag, J. (2010). No More Chewy Centers: Introducing The Zero Trust Model Of Information Security. Forrester Research.
- Gilman, E., & Barth, D. (2017). Zero Trust Networks: Building Secure Systems in Untrusted Networks. O’Reilly Media.
- Verizon. (2023). Data Breach Investigations Report (DBIR).
- Executive Order 14028. (2021). Improving the Nation’s Cybersecurity. The White House.
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【Kubernetes 网络深度系列】Cilium 身份识别与零信任网络
从 IP-based 到 Identity-based 安全,Cilium 零信任网络架构的实现与落地
【系统架构设计百科】架构质量属性:不只是"高可用高性能"
需求评审时写下的'高可用、高性能、高并发',到了架构设计阶段几乎无法落地——因为它们不是可执行的需求。本文从 SEI/CMU 的质量属性理论出发,用 stimulus-response 场景模型把模糊需求变成可量化、可验证的架构约束,并拆解属性之间的冲突与联动关系。
【系统架构设计百科】告警策略:如何避免"狼来了"
大多数团队的告警系统都在制造噪声而不是传递信号。阈值告警看似直观,实则产生大量误报和漏报,值班工程师在凌晨三点被叫醒,却发现只是一次无害的毛刺。本文从告警疲劳的工业数据出发,拆解基于 SLO 的多窗口燃烧率告警算法,深入 Alertmanager 的路由、抑制与分组机制,结合 PagerDuty 的告警疲劳研究和真实工程案例,给出一套可落地的告警策略设计方法。
【系统架构设计百科】复杂性管理:架构的核心战场
系统复杂性是架构腐化的根源——本文从 Brooks 的本质复杂性与偶然复杂性划分出发,结合认知负荷理论与 Parnas 的信息隐藏原则,系统阐述复杂性的来源、度量与控制手段,并给出可操作的架构策略