WEBKT

实战进阶:Istio Ingress Gateway 落地 RequestAuthentication 实现南北向 JWT 精细化控制

4 0 0 0

在云原生架构中,将身份认证(Authentication)下沉到基础设施层是实现零信任架构的关键一步。对于 Istio 而言,针对南北向(外部到集群内部)流量,在 Ingress Gateway 处统一校验 JWT(JSON Web Token)不仅能减轻业务微服务的负担,还能显著提升整体安全性。

本文将深入探讨如何利用 Istio 的 RequestAuthenticationAuthorizationPolicy 协同工作,实现对南北向流量的精细化访问控制。

一、 核心概念:验证与授权的解耦

在开始配置前,必须明确 Istio 安全架构中的两个核心资源:

  1. RequestAuthentication: 它的职责是验证。它检查请求中携带的 JWT 是否合法(签名是否正确、是否过期、Issuer 是否匹配)。如果 Token 合法,它会将解析出的 Claim 附加到请求上下文中;如果 Token 非法,它会拒绝请求;但如果请求不带 Token,它默认是放行的
  2. AuthorizationPolicy: 它的职责是授权。它根据 RequestAuthentication 提取出的身份信息(如 requestPrincipalclaims),决定是否允许该请求访问特定的路径或服务。

二、 基础配置:在 Gateway 开启 JWT 校验

假设我们有一个运行在 istio-system 命名空间的 Ingress Gateway,我们希望对访问 api.example.com 的流量进行校验。

1. 定义 RequestAuthentication

apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: ingress-jwt-auth
  namespace: istio-system # 作用于网关所在命名空间
spec:
  selector:
    matchLabels:
      istio: ingressgateway # 匹配网关的 Label
  jwtRules:
  - issuer: "https://auth.example.com"
    jwksUri: "https://auth.example.com/.well-known/jwks.json"
    forwardPayloadHeader: "x-jwt-payload" # 可选:将解密后的 Payload 转发给后端

关键点:

  • Selector: 必须精准匹配 Ingress Gateway 的 Pod 标签。
  • jwksUri: Istio 控制面(istiod)会负责获取这些公钥。如果你的认证服务器在集群内,确保 istiod 能够解析其域名。

2. 强制要求 Token 存在

由于 RequestAuthentication 允许空 Token 经过,我们需要一个 AuthorizationPolicy 来“关门”。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: require-jwt
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  action: ALLOW
  rules:
  - from:
    - source:
        requestPrincipals: ["https://auth.example.com/*"]

此策略规定:只有当 requestPrincipal 符合特定发行者格式(即 JWT 验证通过)时,才允许流量通过网关。

三、 精细化控制:基于 Claims 的路由权限

在实际业务场景中,我们往往需要根据 JWT 中的 scoperole 来限制访问。

场景:只有具备 admin 角色的用户才能访问 /admin 路径

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: admin-only-access
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  action: ALLOW
  rules:
  - to:
    - operation:
        paths: ["/admin/*"]
    when:
    - key: request.auth.claims[role]
      values: ["admin"]

四、 处理多个 Issuer 与多版本平滑切换

在系统迁移或多租户场景下,网关可能需要同时支持多个 JWT 发行者。

  jwtRules:
  - issuer: "https://old-auth.example.com"
    jwksUri: "https://old-auth.example.com/keys"
  - issuer: "https://new-auth.example.com"
    jwksUri: "https://new-auth.example.com/keys"

Istio 会逐一尝试匹配。只要其中一个验证通过,请求就会被标记为已认证。

五、 实战踩坑与排查经验

在落地过程中,你可能会遇到以下典型问题:

  1. 401 Unauthorized:
    • 检查 issuer 字符串是否与 JWT Payload 中的 iss 字段完全一致(包括末尾的斜杠)。
    • 检查 Ingress Gateway 是否能够通过网络访问到 jwksUri。如果网关无法下载公钥,校验将始终失败。
  2. 403 Forbidden:
    • 这通常意味着 RequestAuthentication 校验通过了,但 AuthorizationPolicy 的规则没匹配上。
    • 利用 istioctl proxy-config log 调高 Envoy 的 RBAC 日志级别,观察具体的匹配决策。
  3. CORS 预检请求(OPTIONS)失败:
    • 浏览器发起的 OPTIONS 请求通常不带 Authorization Header。
    • 对策:在 AuthorizationPolicy 中放行 OPTIONS 方法,或者在 EnvoyFilter 中配置 CORS 优先于认证执行。

六、 总结

通过在 Ingress Gateway 部署 RequestAuthentication,我们构建了第一道防线。这种方式的优势在于:

  • 集中化管理:证书轮换和策略更新无需修改后端服务。
  • 高性能:基于 Envoy 的 C++ 实现,校验延迟极低。
  • 解耦:开发人员可以专注于业务逻辑,而安全团队则通过 YAML 定义安全边界。

在生产环境中,建议始终遵循“默认拒绝”原则,先建立基础的 JWT 强制校验,再根据业务路径逐步细化 AuthorizationPolicy

云原生老兵 Istio网络安全

评论点评