3、流量拓扑概念:服务间通信的源、目标、协议、端口、TLS状态、请求路径与网格拓扑图
流量拓扑是服务网格安全基线的核心观测维度。在 Istio/Envoy 架构中,每一次服务间调用都包含明确的源(Source)、目标(Destination)、协议(Protocol)、端口(Port)、TLS 状态(mTLS)以及请求路径(Path)。理解这六要素,才能精确编写 OPA 策略来允许或拒绝特定流量。
3.1 流量拓扑六要素定义
| 要素 | 字段示例(Envoy/OPA) | 说明 |
|---|---|---|
| 源(Source) | source.principal / source.namespace |
发起调用的工作负载身份(ServiceAccount)与命名空间 |
| 目标(Destination) | destination.service.host / destination.workload |
被调用的服务 FQDN 或工作负载标签 |
| 协议(Protocol) | attributes.destination.protocol |
HTTP、gRPC、TCP、MongoDB 等应用层协议 |
| 端口(Port) | destination.port |
目标服务监听端口,如 8080、443、3306 |
| TLS 状态 | connection.mtls / connection.tls_version |
是否启用双向 TLS、TLS 版本、加密套件 |
| 请求路径(Path) | request.http.path |
HTTP 请求的 URI 路径,如 /api/v1/orders |
安全基线要点:OPA 策略通常组合
source.namespace + destination.service.host + destination.port + connection.mtls 四个字段来定义一条允许规则。缺少任何一个字段都可能导致策略绕过或误拦截。
3.2 服务网格拓扑图:六要素可视化
下图展示了一个典型的微服务调用链,标注了从 frontend 到 orders 再到 payments 的完整流量拓扑六要素。
3.3 请求路径与网格拓扑的层级关系
在服务网格中,请求路径(Path)是六要素中最细粒度的控制维度。一个完整的网格拓扑图通常包含三个层级:
- 集群层(Cluster):Kubernetes 集群边界,决定服务发现范围。
- 命名空间层(Namespace):逻辑隔离单元,OPA 策略常以 namespace 作为源/目标分组。
- 工作负载层(Workload):具体的 Pod/Service,携带 ServiceAccount 身份。
实践建议:在编写 Helm Chart 时,将流量拓扑六要素作为 values.yaml 的显式配置项暴露出来,例如:
# values.yaml
trafficTopology:
- source:
namespace: "prod-front"
serviceAccount: "frontend-sa"
destination:
host: "orders.prod-biz.svc.cluster.local"
port: 8080
protocol: "HTTP"
tls:
mode: "STRICT"
paths:
- "/api/v1/orders"
- "/api/v1/orders/*"
这样 OPA 策略可以通过 data.trafficTopology 动态生成规则,避免硬编码。
3.4 网格拓扑图:命名空间与工作负载视角
下图从命名空间隔离和工作负载身份两个维度,展示更完整的网格拓扑结构,突出 OPA 策略的生效范围。
3.5 六要素在 OPA 策略中的映射
在 OPA 的 input 文档中,Envoy 过滤器会将流量六要素映射为以下字段:
input = {
"attributes": {
"source": {
"namespace": "prod-front",
"principal": "spiffe://cluster.local/ns/prod-front/sa/frontend-sa"
},
"destination": {
"service": {
"host": "orders.prod-biz.svc.cluster.local",
"name": "orders"
},
"port": 8080,
"workload": {
"labels": {"app": "orders", "version": "v2"}
}
},
"request": {
"http": {
"method": "POST",
"path": "/api/v1/orders",
"host": "orders.prod-biz.svc.cluster.local:8080"
}
},
"connection": {
"mtls": true,
"tls_version": "TLSv1.3"
}
}
}
常见陷阱:很多策略只检查
destination.service.host 和 destination.port,却忽略了 connection.mtls 状态。如果网格中某个服务意外降级为 PERMISSIVE 模式,未加密的明文流量可能绕过 mTLS 检查。务必在每条策略中显式断言 input.attributes.connection.mtls == true。
3.6 流量拓扑安全基线检查清单
| 检查项 | OPA 断言示例 | 违规后果 |
|---|---|---|
| 源身份验证 | source.principal == "spiffe://cluster.local/ns/prod-front/sa/frontend-sa" |
未授权服务可发起调用 |
| 目标服务白名单 | destination.service.host in ["orders.prod-biz.svc.cluster.local"] |
流量被路由到恶意服务 |
| 端口限制 | destination.port == 8080 |
绕过端口扫描防护 |
| mTLS 强制 | connection.mtls == true |
明文流量泄露敏感数据 |
| 路径精确匹配 | startswith(request.http.path, "/api/v1/orders") |
API 端点被未授权访问 |
| 协议一致性 | attributes.destination.protocol == "HTTP" |
协议混淆攻击 |