LabHub
学习 学习路径 课程

Istio 服务网格

零信任网格 — 身份、加密,以及授权

在 LabHub 中继续学习

一句话总结

Messages安全有三个层。**是谁(SPIFFE身份)→强制加密(PeerAuthentication)→所以可以做什么(AuthorizationPolicy)。**跳过顺序一定会出问题。

概念图: 仅凭网络政策无法表达“谁”。 · 容器服务帐户 · 身份。 · PAD内

为什么需要这个?

容器群集内部通常被视为“可信赖的网络”,但实际上,即使只有一台服务器被盗,很多情况下也是一个可以平坦连接到整个群集所有服务的平坦网络。要阻止应用程序访问它,每个服务都必须包含TLS证书发行、更新、验证逻辑和权限检查逻辑。如果语言是网络,实现也是网络,网络的行为也存在微妙的差异。

而且还有更根本的问题。仅凭网络政策无法表达“谁”。基于IP的控制一旦帕德重启就会崩溃,也不能阻止冒充同一节点上的其他帕德。梅西将身份标准从IP转移到容器服务帐户,并将该身份刻在证书上进行密码学验证。

怎么行动

**身份。**格式遵循SPIFFE标准。

spiffe://cluster.local/ns/mesh-lab/sa/payments
         -------------    --------    --------
         트러스트 도메인    네임스페이스   서비스 어카운트

istiod兼顾CA。当PAD出现时,istio-agent在PAD内创建密钥对,只将CSR发送给istiod。个人密钥不会离开PAD。istiod验证服务帐户令牌,确认CSR的SPIFFE ID是否与令牌的命名空间/SA匹配后签名。证书的有效期为24小时,在有效期的一半左右自动更新。更新后的证书将通过SDS传递给Envoy,因此重新启动PAD也不需要连接清理。

强制加密。 PeerAuthentication 决定“是否要求 incoming connections 使用 mTLS”。

模式 动作 使用时
PERMISSIVE mTLS和普通文本都接受(默认值) 迁移期间
STRICT 仅接受mTLS 目标状态
DISABLE mTLS 关闭 外部 TLS 关闭设备后背等例外

范围是三层,狭窄的一边获胜 — 工作负载(指定selector)>命名空间(没有selector的相应命名空间)>消息全域(根命名空间istio-systemdefault这样的名字)。如果需要例外的话portLevelMtls只打开一个端口。

在这里不能弄混方向。**PeerAuthentication是接收方(服务器、入站)的设置,DestinationRule的trafficPolicy.tls是发送的一方(客户端,出站)设置。**服务器是STRICT的,但客户端的一方DestinationRule是DISABLE如果是的话,连接会全部失败(UF标志)。这次冲突是istioctl analyze去抓吧。客户端方面宣布要使用消息发出的证书。ISTIO_MUTUAL是。

最终用户认证。 RequestAuthentication 验证 JWT 的签名、发令者和有效期。这里存在最常见的误解。**仅此资源无法阻止任何东西。**规则是“如果存在令牌,则必须有效”,没有令牌的请求就会直接通过。要将令牌作为必需项,请使用 AuthorizationPolicy。requestPrincipals需要要求。

**许可。**每个请求都有确定的评价顺序。

1. CUSTOM  → 외부 인가기(OPA 등)가 거부하면 즉시 거부
2. DENY    → 하나라도 매칭되면 즉시 거부
3. ALLOW   → 대상 워크로드에 ALLOW 정책이 하나도 없으면 허용(기본 개방)
             ALLOW 정책이 하나라도 있으면 매칭돼야 허용(기본 거부로 전환)

最后一行是核心。**一旦产生一个ALLOW政策,该工作量就会进入白名单模式。**利用这种特性的是spec: {}这是一个惯例——虽然存在ALLOW政策,但没有任何匹配规则,所以没有人能通过。零信任的起点就在这一行。

principals写在上的值是SPIFFE ID,但在设置中spiffe://没有前缀cluster.local/ns/mesh-lab/sa/frontend记住写为。而且principal来自mTLS证书,所以在PERMISSIVE状态下以明文传入的请求,principal为空,绝对不匹配这个条件。这就是为什么STRICT转换是授权设计的先决条件。

在现场相遇的样子

**第一,跳过顺序的STRICT。**如果不整理平文出发地,打开消息全域STRICT,没有侧卡的Kron、Legacy VM、自定义探针都会同时中断。正石是观察(保持PERMISSIVE,确认平文比例)→删除平文出发地→从非核心命名空间开始STRICT→消息全域STRICT。完成标准也用数字来确定——例如“7天内平文请求为0件”。

**第二,在许可中403。**经常遇到的三个原因是(1)PERMISSIVE拉principal为空导致匹配失败,(2)命名空间·服务账户错误,(3)忘记在添加ALLOW政策的瞬间会变成默认拒绝的事实,没有留下现有路径。

第三,打开之前先看影子。AUDIT动作和dry-run注释不会阻止流量,只会记录“如果打开的话会拒绝什么”。在将基本拒绝纳入运营之前,必须先经过这一步骤。

**第四,每个工作负载都有专用服务账户。**多个工作负载default如果共享SA,SPIFFE ID就会相同,无法分享授权。身份设计就是授权设计。

下次实习要做的事情

两个实践会连续进行。在之前的实践中,从PERMISSIVE开始,铺设消息全局STRICT,创建工作负载·端口单位的例外,客户端方面ISTIO_MUTUAL设置后,在STRICT和DISABLE发生冲突时,确认静态分析是什么意思,并将逐步转换计划记录在文件中。在后面的实训中,从完全拒绝空规则开始,根据身份、方法、路径、命名空间、条件缩小权限,加上DENY安全网和AUDIT,然后制作每个调用允许/拒绝矩阵。

在这种环境中,实际不会发生mTLS握手。相反,通过宣言和静态分析来判断政策的范围、优先级、冲突。在实际工作中,我发现事故的大部分不是握手失败,而是政策范围把握不准。