名称:mTLS与服务网格安全 描述:在实现服务间安全、mTLS或服务网格模式时使用。涵盖相互TLS、Istio、Linkerd、证书管理和服务网格安全配置。 允许工具:读取、全局搜索、Grep
mTLS和服务网格安全
通过相互TLS和服务网格模式保护服务间通信的综合指南。
何时使用此技能
- 在服务之间实施mTLS
- 部署服务网格(Istio、Linkerd)
- 服务证书管理
- 集群内的零信任网络
- 服务身份和认证
- 加密东西向流量
相互TLS(mTLS)基础
TLS与mTLS
标准TLS(单向):
客户端 ──────────────────► 服务器
客户端验证
服务器身份
相互TLS(双向):
客户端 ◄────────────────► 服务器
双方相互验证
彼此
标准TLS:
- 服务器提供证书
- 客户端验证服务器
- 客户端对服务器保持匿名
相互TLS:
- 服务器提供证书
- 客户端验证服务器
- 客户端提供证书
- 服务器验证客户端
- 双方身份验证通过
mTLS握手流程
mTLS握手流程:
1. 客户端Hello
└── 客户端 → 服务器:“你好,我支持这些加密套件”
2. 服务器Hello + 证书
└── 服务器 → 客户端:“让我们使用这个加密套件”
└── 服务器 → 客户端:“这是我的证书”
└── 服务器 → 客户端:“请提供你的证书”
3. 客户端证书
└── 客户端 → 服务器:“这是我的证书”
4. 证书验证
└── 双方验证:
- 证书链有效
- 未过期
- 未撤销
- 身份匹配预期
5. 密钥交换
└── 派生共享会话密钥
6. 加密通信
└── 所有流量用会话密钥加密
证书组件
服务证书字段:
主题:
CN = 我的服务
O = 我的组织
主题替代名称(SANs):
- DNS:我的服务.default.svc.cluster.local
- DNS:我的服务.default
- DNS:我的服务
- URI:spiffe://cluster.local/ns/default/sa/我的服务
颁发者:(签署证书的CA)
CN = 集群-CA
有效期:
起始时间:2025-01-01
结束时间:2025-01-08 (短期有效,自动轮换)
密钥用途:
- 数字签名
- 密钥加密
扩展密钥用途:
- TLS Web 服务器认证
- TLS Web 客户端认证
服务网格架构
组件
服务网格架构:
┌─────────────────────────────────────────────────────┐
│ 控制平面 │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Pilot │ │ Citadel │ │ Galley │ │
│ │ (配置) │ │ (CA) │ │ (验证) │ │
│ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ │
└────────┼───────────────┼───────────────┼───────────┘
│ │ │
└───────────────┼───────────────┘
│
┌───────────────▼───────────────┐
│ 数据平面 │
┌────────┼────────────────────────────────┼────────┐
│ │ │ │
│ ┌─────▼─────┐ ┌──────▼─────┐ │
│ │ Sidecar │◄─────mTLS───────►│ Sidecar │ │
│ │ (Envoy) │ │ (Envoy) │ │
│ └─────┬─────┘ └─────┬──────┘ │
│ │ │ │
│ ┌─────▼─────┐ ┌─────▼─────┐ │
│ │ 服务A │ │ 服务B │ │
│ └───────────┘ └───────────┘ │
└──────────────────────────────────────────────────┘
控制平面功能:
- 证书颁发机构(签发/轮换证书)
- 配置分发
- 策略管理
- 服务发现
数据平面功能:
- mTLS终止
- 流量加密
- 策略强制执行
- 遥测收集
Sidecar代理模式
Sidecar注入:
无Sidecar:
┌───────────────────┐
│ Pod │
│ ┌─────────────┐ │
│ │ 应用 │──────► 网络
│ └─────────────┘ │
└───────────────────┘
有Sidecar:
┌────────────────────────────────────┐
│ Pod │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 应用 │ │ Sidecar │ │
│ │ │──►│ (Envoy) │──────► mTLS ──►
│ │ localhost │ │ 处理安全 │ │
│ │ :8080 │ │ │ │
│ └─────────────┘ └─────────────┘ │
└────────────────────────────────────┘
流量流程:
1. 应用发送请求到localhost
2. Sidecar拦截(iptables规则)
3. Sidecar建立mTLS连接
4. 流量加密到目标Sidecar
5. 目标Sidecar解密
6. 目标Sidecar转发到应用
Istio安全
Istio mTLS模式
PeerAuthentication 模式:
1. PERMISSIVE(默认初始)
- 接受明文和mTLS
- 适合迁移
2. STRICT
- 所有流量需要mTLS
- 拒绝明文连接
3. DISABLE
- 禁用mTLS(不推荐)
示例策略:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICT
Istio授权策略
授权策略结构:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: orders-policy
namespace: production
spec:
selector:
matchLabels:
app: orders-service
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/production/sa/frontend"]
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/orders/*"]
when:
- key: request.headers[x-custom-header]
values: ["valid-value"]
策略逻辑:
- selector: 此策略适用于哪些工作负载
- from: 谁可以发起请求(源身份)
- to: 允许什么操作
- when: 附加条件
Istio证书管理
Istio证书流程:
1. 工作负载启动Sidecar
2. Sidecar向Istiod(CA)请求证书
3. Istiod验证服务账户身份
4. Istiod签发短期证书(默认24小时)
5. Sidecar将证书存储在内存中
6. 证书在过期前自动轮换
SPIFFE身份格式:
spiffe://cluster.local/ns/namespace/sa/service-account
证书属性:
- 短期有效(小时,非年)
- 自动轮换(无需手动干预)
- 绑定到Kubernetes服务账户
- 私钥不离开工作负载
Linkerd安全
Linkerd mTLS
Linkerd自动mTLS:
功能:
- mTLS默认启用
- 零配置设置
- 自动证书轮换
- 基础mTLS无需YAML
身份系统:
- 使用Kubernetes服务账户
- 证书由Linkerd身份服务签发
- 24小时证书有效期(默认)
- 自动轮换
验证:
$ linkerd viz tap deploy/my-service
显示连接的mTLS状态
$ linkerd check --proxy
验证mTLS配置
Linkerd服务器授权
Linkerd授权:
apiVersion: policy.linkerd.io/v1beta1
kind: Server
metadata:
name: orders-api
namespace: production
spec:
podSelector:
matchLabels:
app: orders-service
port: 8080
proxyProtocol: HTTP/2
---
apiVersion: policy.linkerd.io/v1beta1
kind: ServerAuthorization
metadata:
name: orders-authz
namespace: production
spec:
server:
name: orders-api
client:
meshTLS:
serviceAccounts:
- name: frontend
namespace: production
证书管理
证书轮换策略
轮换方法:
1. 短期证书(推荐)
- 1-24小时有效期
- 由网格自动轮换
- 无需撤销(只需过期)
- 服务网格自动处理
2. 长期证书与撤销
- 数天至数月有效期
- 需要撤销基础设施
- 使用CRL或OCSP检查
- 管理更复杂
3. 混合方法
- 服务网格用短期证书
- 外部连接用长期证书
- 不同场景不同方法
轮换时间线:
┌─────────────────────────────────────────────────┐
│ 证书有效期(例如,24小时) │
│ │
│ ├──────────────────┼────────────────┼────────┤
│ 签发 轮换 过期 │
│ t=0 t=12h t=24h │
│ (50%生命周期) │
└─────────────────────────────────────────────────┘
根CA管理
根CA层次结构:
选项1:单一根CA(简单)
根CA
└── 工作负载证书
选项2:中间CA(推荐)
根CA(离线,长期有效)
├── 集群CA 1(中间CA,中等有效期)
│ └── 工作负载证书(短期)
├── 集群CA 2
│ └── 工作负载证书
└── 集群CA 3
└── 工作负载证书
根CA轮换:
1. 生成新根CA
2. 更新信任包(包含新旧根CA)
3. 从新根CA签发新中间CA
4. 工作负载接受新旧根CA的证书
5. 所有证书轮换后移除旧根CA
迁移到mTLS
迁移策略
阶段1:观察(第1-2周)
- 启用网格在permissive模式
- 监控哪些连接是明文
- 识别所有服务间流量
- 文档化依赖关系
阶段2:测试(第3-4周)
- 在测试环境启用strict模式
- 验证所有服务可通信
- 测试故障场景
- 修复任何问题
阶段3:部署(第5-8周)
- 逐个命名空间启用strict模式
- 从最不关键的命名空间开始
- 监控连接失败
- 准备回滚计划
阶段4:强制执行(第9周后)
- 集群范围启用strict模式
- 移除permissive策略
- 文档化例外
- 持续监控
常见迁移问题
问题:外部服务无法连接
修复:使用网关处理外部→内部流量
问题:遗留服务不支持mTLS
修复:对特定服务使用permissive模式
问题:性能下降
修复:调整Sidecar资源、连接池
问题:证书错误
修复:检查信任包、证书链
问题:非网格服务无法通信
修复:添加到网格或使用permissive模式
最佳实践
安全最佳实践:
1. 证书管理
□ 使用短期证书(小时,非年)
□ 完全自动化轮换
□ 保护根CA(尽可能离线)
□ 监控证书过期
2. 策略管理
□ 默认拒绝,明确允许
□ 使用命名空间隔离
□ 定期审计策略
□ 先在预演环境测试策略
3. 可观测性
□ 监控mTLS成功/失败率
□ 警报明文连接(在strict模式)
□ 记录授权决策
□ 跨服务追踪请求
4. 运维
□ 文档化所有例外
□ 定期安全审查
□ 事件响应程序
□ 轮换操作手册
5. 性能
□ 合理配置Sidecar资源
□ 连接池
□ 监控延迟开销
□ 基准测试有无网格
故障排除
常见问题:
1. “连接重置”错误
- 检查双方是否有有效证书
- 验证信任包同步
- 检查证书过期
2. “503服务不可用”
- 目标可能没有Sidecar
- 授权策略阻止请求
- 服务不在网格中
3. 高延迟
- Sidecar资源约束
- 证书验证开销
- 网络策略冲突
4. 间歇性故障
- 证书轮换竞争条件
- 信任包传播延迟
- Sidecar重启期间轮换
调试命令(Istio):
$ istioctl analyze
$ istioctl proxy-status
$ istioctl proxy-config secret <pod>
调试命令(Linkerd):
$ linkerd check
$ linkerd viz tap <resource>
$ linkerd viz stat <resource>
相关技能
zero-trust-architecture- 整体安全架构api-security- 应用级安全container-orchestration- Kubernetes和服务网格distributed-tracing- 服务网格中的可观测性