土法炼钢兴趣小组的算法知识备份

【系统架构设计百科】零信任架构:不信任网络边界的安全模型

文章导航

分类入口
architecture
标签入口
#zero-trust#BeyondCorp#mTLS#SPIFFE#micro-segmentation

目录

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 系统。传统方案的流程是:

  1. 员工在笔记本上启动 VPN 客户端,输入用户名和密码(可能加上一次性验证码)
  2. VPN 网关验证身份后,在员工设备和企业内网之间建立加密隧道
  3. 员工的流量通过隧道进入内网,此后可以访问内网中的任意资源
  4. 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)模型:

只要跨过护城河,你就进入了城堡,可以在里面自由走动。这个模型在企业网络边界清晰、所有资源都在物理数据中心内的时代是合理的。

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 文档是零信任架构的权威参考。其核心原则包括:

  1. 所有数据源和计算服务都被视为资源。 不仅仅是服务器,还包括个人设备、SaaS 应用、API 端点。

  2. 无论网络位置如何,所有通信都必须受到保护。 内网通信也必须加密和认证。

  3. 对单个企业资源的访问是按会话授予的。 每次请求都需要独立评估,不能依赖之前的认证状态。

  4. 对资源的访问由动态策略决定。 策略引擎综合考虑用户身份、设备状态、行为模式、环境上下文。

  5. 企业监控和测量所有资产的安全状态。 持续评估设备合规性、漏洞状态、补丁级别。

  6. 所有资源认证和授权都是动态的,在允许访问之前严格执行。 信任不是静态分配的,而是持续评估的。

  7. 企业收集尽可能多的关于资产、网络和通信状态的信息,用于改善安全态势。

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)动态访问策略。 策略引擎根据以下输入做出访问决策:

例如:一个工程师可以在公司配发的、完全合规的笔记本上访问生产数据库,但在个人手机上只能查看公司 Wiki。同一个用户,不同设备,不同权限。

4.4 迁移路径

Google 的迁移不是一夜完成的,而是遵循了渐进式策略:

  1. 并行运行阶段。 VPN 和 BeyondCorp 访问代理同时运行,员工可以选择任一方式访问资源。
  2. 监控与对比阶段。 对比两种路径的访问日志,识别仅通过 VPN 可达的资源并迁移。
  3. 逐步收紧阶段。 将越来越多的资源设置为”仅通过访问代理可达”。
  4. 关闭 VPN 阶段。 当所有关键资源都通过访问代理可达后,关闭 VPN。

这个过程中最大的挑战不是技术,而是用户习惯迁移和遗留系统适配。


五、SPIFFE/SPIRE 与 mTLS

5.1 服务身份的困境

在零信任架构中,不仅用户需要身份,服务也需要身份。 当服务 A 调用服务 B 时,B 需要验证”这个请求确实来自 A,而不是来自一个伪装成 A 的攻击者”。

传统方案的问题:

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,由三部分组成:

SVID(SPIFFE Verifiable Identity Document) 是 SPIFFE ID 的载体,有两种形式:

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 是控制平面,负责:

SPIRE Agent 运行在每个工作节点上,负责:

工作负载认证(Workload Attestation) 是 SPIRE 的核心机制。Agent 需要确认”请求 SVID 的进程确实是它声称的工作负载”。认证方式包括:

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 3600

5.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 的默认策略是:

证书生命周期
|←———— 1h ————→|
|——有效——|——轮换窗口——|——过期——|
         ↑
     Agent 发起轮换
     (剩余 < 50%)

这意味着在任何时刻,集群中所有证书的最大年龄不超过 1 小时。即使某个证书被泄露,攻击窗口也被限制在分钟级别。


六、持续身份验证

6.1 一次性认证的问题

传统认证模型是”认证一次,信任一段时间”:用户登录后获得一个有效期为数小时的会话令牌(Session Token),在此期间所有请求都被视为已认证。

这个模型的隐含假设是:用户在认证时刻的安全状态在整个会话期间保持不变。但这个假设在以下场景中不成立:

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:
  {}

这个配置实现了:

7.4 微分段的实施策略

从零开始实施微分段的渐进路径:

第一阶段:可观测性优先。 在不阻断任何流量的前提下,部署网络监控工具(如 Cilium Hubble 或 Calico Enterprise 的流量日志),记录所有服务间的通信模式。目标是画出一张完整的服务间调用关系图。

第二阶段:粗粒度分段。 按命名空间或业务域划分安全区域。例如,禁止 dev 命名空间的服务访问 production 命名空间的服务,禁止 frontend 命名空间的服务直接访问数据库命名空间。

第三阶段:细粒度策略。 在每个安全区域内部,按服务级别制定白名单策略。这一阶段的工作量最大,需要逐个服务梳理其合法的上下游依赖。

第四阶段:应用层策略。 在服务网格中配置 L7 级别的策略,控制到 HTTP 方法和路径级别。

每个阶段都应该在审计模式(Audit Mode)下运行足够长的时间,确认不会误杀合法流量后再切换到强制模式(Enforce Mode)。


八、工程案例

8.1 背景

某金融科技公司(以下称 FinCo)拥有约 800 名工程师,核心业务系统由 200 多个微服务构成,部署在 AWS 和自建数据中心的混合云环境中。2022 年之前,FinCo 的安全架构是典型的边界模型:

8.2 迁移动因

2022 年 Q1,FinCo 经历了一次安全事件:一名员工的 VPN 凭据被钓鱼攻击窃取,攻击者通过 VPN 进入内网后,横向移动到了一台开发环境的数据库服务器。虽然该数据库不包含生产数据,但事件暴露了多个架构缺陷:

公司决定在 12 个月内完成向零信任架构的迁移。

8.3 实施过程

Phase 1(第 1-3 月):身份基础设施建设

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: false

Phase 2(第 4-6 月):mTLS 部署

# Istio PeerAuthentication - 强制 mTLS
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system
spec:
  mtls:
    mode: STRICT

逐步启用 mTLS 的过程:

  1. 先以 PERMISSIVE 模式运行,允许明文和 mTLS 混合通信
  2. 监控流量日志,识别仍在使用明文的服务并逐个修复
  3. 确认所有服务都支持 mTLS 后,切换到 STRICT 模式

Phase 3(第 7-9 月):微分段与持续验证

Phase 4(第 10-12 月):VPN 退役与监控完善

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 集成 + 自动化响应

十、总结

零信任不是一个可以”安装”的产品,而是一种需要持续投入的安全架构范式。它的核心思想可以归结为三句话:

  1. 身份是新的边界。 网络位置不再是信任的依据,用户身份、服务身份和设备身份才是。
  2. 验证必须持续。 一次性认证不够,必须在整个会话生命周期内持续评估安全状态。
  3. 权限必须最小。 微分段将攻击的爆炸半径限制在最小范围内。

工程上,零信任的实施不是一蹴而就的。从 SSO + MFA 开始,逐步引入 mTLS、SPIFFE/SPIRE、微分段和持续身份验证。每一步都要在安全收益和实施成本之间找到平衡。

最后一个提醒:零信任架构的最大敌人不是技术复杂性,而是组织惯性。技术组件可以逐步部署,但”内网可信”的心智模型需要从上到下的认知转变。在 SolarWinds 事件之后,美国政府发布了行政命令(EO 14028),要求联邦机构在规定时间内采用零信任架构——有时候推动变革需要一次足够大的事件。


上一篇:授权架构

下一篇:API 安全


参考资料

  1. Rose, S., Borchert, O., Mitchell, S., & Connelly, S. (2020). Zero Trust Architecture. NIST Special Publication 800-207.
  2. Ward, R., & Beyer, B. (2014). BeyondCorp: A New Approach to Enterprise Security. ;login:, 39(6), 6-11.
  3. Osborn, B., McWilliams, J., Beyer, B., & Saltonstall, M. (2016). BeyondCorp: Design to Deployment at Google. ;login:, 41(1), 28-34.
  4. Escobedo, V., Beyer, B., Saltonstall, M., & Peck, J. (2017). BeyondCorp: The Access Proxy. ;login:, 42(4), 28-33.
  5. SPIFFE Project. (2024). SPIFFE: Secure Production Identity Framework for Everyone. https://spiffe.io/
  6. CNCF. (2024). SPIRE Documentation. https://spiffe.io/docs/latest/spire-about/
  7. Kindervag, J. (2010). No More Chewy Centers: Introducing The Zero Trust Model Of Information Security. Forrester Research.
  8. Gilman, E., & Barth, D. (2017). Zero Trust Networks: Building Secure Systems in Untrusted Networks. O’Reilly Media.
  9. Verizon. (2023). Data Breach Investigations Report (DBIR).
  10. Executive Order 14028. (2021). Improving the Nation’s Cybersecurity. The White House.

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-13 · architecture

【系统架构设计百科】架构质量属性:不只是"高可用高性能"

需求评审时写下的'高可用、高性能、高并发',到了架构设计阶段几乎无法落地——因为它们不是可执行的需求。本文从 SEI/CMU 的质量属性理论出发,用 stimulus-response 场景模型把模糊需求变成可量化、可验证的架构约束,并拆解属性之间的冲突与联动关系。

2026-04-13 · architecture

【系统架构设计百科】告警策略:如何避免"狼来了"

大多数团队的告警系统都在制造噪声而不是传递信号。阈值告警看似直观,实则产生大量误报和漏报,值班工程师在凌晨三点被叫醒,却发现只是一次无害的毛刺。本文从告警疲劳的工业数据出发,拆解基于 SLO 的多窗口燃烧率告警算法,深入 Alertmanager 的路由、抑制与分组机制,结合 PagerDuty 的告警疲劳研究和真实工程案例,给出一套可落地的告警策略设计方法。

2026-04-13 · architecture

【系统架构设计百科】复杂性管理:架构的核心战场

系统复杂性是架构腐化的根源——本文从 Brooks 的本质复杂性与偶然复杂性划分出发,结合认知负荷理论与 Parnas 的信息隐藏原则,系统阐述复杂性的来源、度量与控制手段,并给出可操作的架构策略


By .