Linkerd 服务网格控制面打点与Viz、Tap、Admin接口利用技术

Linkerd 服务网格控制面打点与Viz、Tap、Admin接口利用技术

LinkerdIstio/Kuma 的管理面风格不太一样。它的危险点通常不在“大而全的控制台写接口”,而在于它把:

  • 服务发现
  • 实时流量观测
  • 控制面指标
  • 调试 profiling
  • Dashboard

这些能力拆散在多个控制面与扩展组件里。官方文档明确说明:

  • 控制面组件会对外提供 admin-http 端口
  • 控制面组件可通过 /metrics 输出控制面指标
  • 控制面调试端点通过 /debug/pprof 暴露 Go profiling 数据
  • linkerd-viz 扩展会安装 webtapmetrics-apiPrometheus
  • tap 可以实时观察流量
  • diagnostics endpoints 可以查询 destination 服务发现状态

这意味着,一旦 Linkerd 控制面、viz 扩展或调试端点进入低信任网络,攻击者通常能迅速回收:

  • 服务与 authority 到 endpoint 的映射
  • 实时 HTTP/gRPC 请求元数据
  • 代理和控制面指标
  • 控制面组件的命令行、goroutine、heap、trace
  • dashboard 中的依赖关系、成功率、延迟和路由健康状态

对攻击者来说,这些信息的价值在于:

  1. 恢复服务拓扑
  2. 恢复控制面与数据面依赖
  3. 通过 tap 直接获取流量样本
  4. 通过 pprof 获取运行时画像
  5. 从 metrics 中恢复 authority、route、身份、TLS 与失败模式

本文重点围绕:

  1. 如何识别 Linkerd 控制面和 linkerd-viz 暴露
  2. 如何围绕 admin-http/metrics/debug/pprofviz dashboardtap 建立可利用画像
  3. 如何利用 destination / diagnostics 接口恢复服务发现状态
  4. 哪些接口只是只读观测,哪些已经足够用于高价值流量侦察
  5. 蓝队如何从 metrics、dashboard、tap 与调试访问中定位这类打点

下文请求/响应样例为脱敏后的实战常见结构,重点保留识别点、对象结构和利用判断依据。


0. 攻击面概览

0.1 需要区分三层面

Linkerd 实战里至少要区分:

控制面组件

  • destination
  • identity
  • proxy-injector
  • policy

viz 扩展

  • web
  • tap
  • metrics-api
  • prometheus

调试与观测面

  • admin-http
  • /metrics
  • /debug/pprof
  • dashboard 公开入口

0.2 常见端口与路径

首轮建议优先关注:

  • 4191:proxy metrics 默认端口
  • 8084
  • 8085
  • 9990
  • /metrics
  • /ready
  • /live
  • /debug/pprof/
  • /tap
  • /api

由于 Linkerd 常通过 kubectl port-forward 暴露给本地运维,所以很多环境不会直接把这些端口放公网。但一旦出现:

  • Ingress 暴露 web
  • 对外暴露 prometheus
  • SSRF / 端口转发 / 调试 sidecar
  • Pod 到控制面 Service 的邻近访问

这些接口就会从纯内部排障面,变成高价值打点面。

0.3 官方边界的实战含义

官方文档中几个点非常重要:

  • web 默认会做 Host header 限制,防 DNS rebinding
  • 如果要公开 dashboard,必须显式配置 -enforced-host
  • viz 包含 tapwebmetrics-apiprometheus
  • controller-metricsproxy-metricsdiagnostics endpoints 都是官方提供的直接观察通道
  • pprof 可通过 enablePprof=true 启用

这在渗透里转化成:

  1. 即使默认没完全裸露,管理员为了公开 dashboard 常会主动开洞
  2. 只要 dashboard / viz 暴露,往往意味着 metrics-api / tap 也在旁边
  3. pprof 一旦打开,就是高价值运行时泄露面

1. 第一轮打点:识别 Linkerd 控制面与 Dashboard 暴露

1.1 GET /

如果直接打到 web 组件或其 Ingress,通常会得到 Linkerd Dashboard。

请求示例

GET / HTTP/1.1
Host: dashboard.target.example
Accept: text/html
Connection: close

典型响应示例

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Connection: close
<!doctype html>
<html>
  <head>
    <title>Linkerd</title>
  </head>
  <body>
    <div id="main"></div>
  </body>
</html>

如果命中 Host 限制,则还可能看到类似错误:

HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close

invalid Host header

这同样很有价值,因为它说明:

  • 对方确实跑着 linkerd-viz web
  • 只是 enforced-host 还在生效

1.2 GET /metrics

无论是控制面组件还是 viz 扩展,/metrics 都是高价值识别点。

请求示例

GET /metrics HTTP/1.1
Host: linkerd-destination.target.example:9996
Accept: text/plain
Connection: close

典型响应示例

# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 21.72
# HELP destination_service_query_total Number of destination queries
# TYPE destination_service_query_total counter
destination_service_query_total 84921

这一步可以帮助判断:

  • 当前组件是 destinationidentitytap 还是 metrics-api
  • 控制面是否真实在服务生产流量
  • 哪个组件最值得继续深挖

1.3 GET /readyGET /live

控制面与扩展组件通常会暴露 liveness / readiness。

请求示例

GET /ready HTTP/1.1
Host: linkerd-identity.target.example:9990
Connection: close

典型响应示例

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Connection: close

ready

请求示例

GET /live HTTP/1.1
Host: linkerd-identity.target.example:9990
Connection: close

典型响应示例

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Connection: close

live

这些探针虽然不直接泄露业务对象,但能帮助判断:

  • 控制面组件是否活跃
  • 哪些 Pod/Service 当前真的可用

2. 第二轮打点:恢复服务发现、流量观测与控制面依赖

2.1 destination 视角的 endpoint 恢复

官方 linkerd diagnostics endpoints 文档明确说明:

  • 该命令查询的就是 destination 服务内部状态
  • 会返回 authority 对应的地址

这意味着只要能命中 destination 相关接口或相同后端逻辑,攻击者就能把某个 service authority 解析成真实 endpoint 列表。

目标 authority 示例

web.linkerd-viz.svc.cluster.local:8084

典型返回结构示意

{
  "authority": "web.linkerd-viz.svc.cluster.local:8084",
  "endpoints": [
    {
      "namespace": "linkerd-viz",
      "ip": "10.42.7.16",
      "port": 8084,
      "pod": "web-cbb846484-d987n"
    }
  ]
}

这一步的价值非常高,因为它把:

  • service FQDN
  • Pod IP
  • 端口
  • 命名空间

直接联系起来。

2.2 linkerd-viz dashboard 的关系图价值

官方 dashboard 文档说明,viz 仪表板可展示:

  • success rate
  • requests per second
  • latency
  • service dependencies
  • route health

如果攻击者拿到 dashboard 或其背后的 API,价值并不只是“看看数值”,而是能得到:

  • 哪些服务彼此依赖
  • 哪些服务最繁忙
  • 哪些路径最容易出错
  • 哪些目标更适合做横向或流量级侦察

2.3 tap 的流量观察价值

官方文档将 tap 描述为可以“listen to a traffic stream”。从渗透角度,它的价值非常直接:

  • 看实时请求
  • 看 authority / path / method
  • 看响应码
  • 看延迟

如果 tap 组件或其 API 被错误公开,攻击者通常不需要自己发大量探测流量,就能:

  • 被动观察业务流量
  • 确认内部 API 路径
  • 恢复调用关系
  • 收集请求头与协议元数据

典型观察事件示例

{
  "source": "10.42.1.19:41454",
  "destination": "10.42.3.28:8080",
  "authority": "payments.default.svc.cluster.local:8080",
  "method": "POST",
  "path": "/api/v1/refund",
  "scheme": "http",
  "tls": true,
  "status": 200,
  "latency_ms": 37
}

这类数据一旦被低信任主体获取,其价值通常高于普通 metrics。

2.4 metrics-apiprometheus

官方 dashboard/metrics 文档说明:

  • viz 扩展会带一个 on-cluster Prometheus
  • metrics-api 负责给 dashboard/CLI 提供聚合视图
  • 历史版本还会自带 Grafana

对攻击者来说,这意味着如果 linkerd-viz 组件被对外暴露,可能顺带泄露:

  • 聚合指标
  • 服务 Top N
  • 历史 6 小时流量
  • 控制面指标

这比单个 proxy 的 /metrics 更像全局视角。


3. 调试端点:admin-http/debug/pprof

3.1 GET /debug/pprof/

官方任务文档明确说明:

  • 所有控制面组件都可以通过 /debug/pprof 暴露 Go profiling 数据
  • 该数据由 admin-http 端口提供
  • 可通过 go tool pprof 直接分析

请求示例

GET /debug/pprof/ HTTP/1.1
Host: linkerd-identity.target.example:9990
Accept: text/html
Connection: close

典型响应示例

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Connection: close
<html>
  <head><title>/debug/pprof/</title></head>
  <body>
    <a href="allocs">allocs</a>
    <a href="goroutine">goroutine</a>
    <a href="heap">heap</a>
    <a href="profile?seconds=30">profile</a>
    <a href="trace?seconds=5">trace</a>
  </body>
</html>

这类端点的高风险点在于:

  • 暴露命令行参数
  • 暴露 goroutine 栈
  • 暴露 heap 采样
  • 暴露 trace 与 profile

3.2 GET /debug/pprof/cmdline

请求示例

GET /debug/pprof/cmdline HTTP/1.1
Host: linkerd-identity.target.example:9990
Connection: close

典型响应示例

/usr/local/bin/linkerd-identity
-log-level=info
-addr=:8080
-admin-listen-addr=:9990
-issuer-scheme=kubernetes.io/tls

这里往往能直接暴露:

  • 组件二进制名
  • 监听地址
  • 证书签发模式
  • 调试开关

3.3 GET /debug/pprof/profile?seconds=10

请求示例

GET /debug/pprof/profile?seconds=10 HTTP/1.1
Host: linkerd-destination.target.example:9996
Connection: close

典型响应示例

HTTP/1.1 200 OK
Content-Type: application/octet-stream
Connection: close

这类接口本身不直接给文本结果,但会返回 profile 数据,可用于:

  • 反推出当前高负载路径
  • 分析控制面是否被压垮
  • 放大对 Go runtime / goroutine 的运行时认知

3.4 enablePprof=true 的现实风险

较新的官方文档还特别指出:

  • pprof 需要通过 enablePprof=true 显式启用

这说明现实环境里有两类高价值目标:

  1. 运维为排障临时打开 pprof 后忘记关闭
  2. 某些 Helm values/升级流程把该选项长期保留在生产

4. 数据面与控制面指标的利用价值

4.1 proxy /metrics 默认端口 4191

官方文档明确写出:

  • Linkerd proxy 的指标默认在 :4191/metrics

请求示例

GET /metrics HTTP/1.1
Host: pod-proxy.target.example:4191
Accept: text/plain
Connection: close

典型响应示例

# TYPE request_total counter
request_total{direction="outbound",dst="payments.default.svc.cluster.local:8080",tls="true"} 12842
# TYPE response_total counter
response_total{direction="outbound",dst="payments.default.svc.cluster.local:8080",classification="success",status_code="200"} 12831
# TYPE response_latency_ms histogram
response_latency_ms_bucket{direction="outbound",dst="payments.default.svc.cluster.local:8080",le="10"} 12000

即使只拿到 proxy metrics,也能恢复:

  • 调用目标 authority
  • inbound/outbound 方向
  • 是否启用 TLS
  • 请求量、状态码、延迟

4.2 control_* 指标

官方 proxy metrics 文档说明,还存在专门衡量控制面请求的指标:

  • control_request_total
  • control_response_total
  • control_response_latency_ms

典型指标片段

control_request_total{addr="linkerd-destination.linkerd.svc.cluster.local:8086"} 24190
control_response_total{addr="linkerd-identity.linkerd.svc.cluster.local:8080",classification="success"} 24188

这能帮助攻击者判断:

  • proxy 正在依赖哪些控制面地址
  • destination / identity 的实际通信地址
  • 控制面是否稳定

4.3 authority / route / authz 标签

官方 metrics 文档指出,Linkerd 暴露的指标会带出:

  • authority
  • route
  • authz_name
  • grpc_status_code
  • tls

这些标签组合的价值非常大,因为它们基本能让攻击者从 metrics 恢复:

  • 哪些 authority 正在被调用
  • 哪些 route 名称已经定义
  • 哪些授权策略在放行或拒绝

5. 历史与现实高风险场景

5.1 Dashboard 暴露不是单纯“看板问题”

官方专门提供了公开 dashboard 的 Ingress 配置示例,还专门说明了 Host header 保护。这本身就说明:

  • 真实环境里确实常有人把 dashboard 暴露出去
  • 一旦暴露,不只 UI 在外面,背后的 metrics-apitapprometheus 也可能被顺带带出

典型公开配置方向

  • Nginx Basic Auth
  • oauth2-proxy
  • Traefik
  • Ambassador

这意味着在渗透中,看到 dashboard.example.com 一类入口时,不应只停留在 UI,而要继续问:

  • metrics-api 是否可侧击
  • tap 是否在同 namespace/同服务后面
  • Prometheus 是否也被公开

5.2 tap 暴露的被动监听价值

与许多控制面不同,tap 的危险在于:

  • 攻击者不必主动制造请求
  • 只要订阅成功,就能观察他人真实流量

这在管理面打点里属于非常高价值的“被动观测型接口”。

5.3 pprof 打开后的运行时泄露

pprof 不一定直接给你业务对象,但它会显著提升:

  • 运行时画像还原
  • 命令行与参数泄露
  • goroutine / trace 暴露
  • 控制面异常热点分析

对高流量控制面来说,这类数据在红队和蓝队手里都很有价值。

5.4 多组件组合暴露

Linkerd 最现实的高风险场景,通常不是某个孤立路径,而是组合暴露:

  1. web 被 Ingress 暴露
  2. metrics-api / prometheus 一起可达
  3. 某个控制面组件的 admin-http 也能打到
  4. pprof 被开启

这时攻击者就能同时拿到:

  • 拓扑视图
  • 流量视图
  • 指标视图
  • 运行时视图

6. 蓝队日志、检测与处置

6.1 应优先收集哪些日志

对 Linkerd 控制面与 viz 组件事件,优先级最高的是:

  • web / metrics-api / tap 访问日志
  • control plane component 日志
  • proxy /metrics 被异常抓取的记录
  • kubectl port-forward、临时暴露、Ingress 变更记录
  • Kubernetes Audit Log

6.2 重点检索的路径

应优先关注:

  • /metrics
  • /ready
  • /live
  • /debug/pprof/
  • /debug/pprof/cmdline
  • /debug/pprof/heap
  • /debug/pprof/profile
  • dashboard 根路径
  • tap API 相关路径或连接

6.3 典型日志示例

2026-06-16T13:21:14Z INFO http request method=GET path=/metrics component=destination client=198.51.100.51
2026-06-16T13:21:19Z INFO http request method=GET path=/debug/pprof/cmdline component=identity client=198.51.100.51
2026-06-16T13:21:26Z INFO tap stream opened resource=deploy/payments namespace=default client=198.51.100.51

6.4 应急排查重点

发现异常后,优先核对:

  1. 是否有人公开暴露了 linkerd-viz web
  2. enforced-host 是否被放宽
  3. tap 是否被非预期主体访问
  4. admin-http 是否对非本机/非运维平面可达
  5. enablePprof 是否被打开
  6. 是否存在异常的 metrics 大量抓取

6.5 告警建议

至少应为以下行为设置告警:

  • 访问 /debug/pprof
  • dashboard 来自公网 IP 的访问
  • tap 流被建立
  • proxy-metrics / controller-metrics 高频抓取
  • Host 校验失败的 dashboard 访问

7. 加固建议

7.1 不要直接暴露 viz

如果确实需要公开 dashboard:

  • 必须加认证
  • 保留严格的 Host 限制
  • 不要把 tapmetrics-apiprometheus 一起宽泛暴露

7.2 收紧 admin-http

admin-http 应仅供:

  • 本地排障
  • 受控运维跳板
  • 临时 port-forward

不要直接发布到业务网段或公网。

7.3 默认关闭 pprof

如果没有明确排障需求:

  • 不启用 enablePprof=true
  • 排障完成后回收

7.4 审计流量观测组件

tapmetrics-apiprometheus 不应被当作“只是可视化组件”,而应视为高价值流量观察面。


8. 打点评估清单

遇到 Linkerd 目标时,建议至少留档:

  1. web dashboard 是否可达
  2. Host 头限制是否仍生效
  3. metrics-api / prometheus 是否被公开
  4. admin-http 是否可从低信任网络到达
  5. /debug/pprof 是否启用
  6. /metrics 是否暴露 control plane 与 proxy 指标
  7. 是否能恢复 destination authority 到 endpoint 的映射
  8. 是否存在 tap 实时流量观察面

9. 总结

Linkerd 的高价值点,不在传统意义的“后台管理界面写操作”,而在它把服务网格最关键的观测与控制信号拆到了多个可直接利用的接口上:

  • dashboard 给出全局依赖与健康视图
  • metrics-apiprometheus 给出聚合指标视图
  • destination 相关诊断给出服务发现视图
  • tap 给出实时流量视图
  • admin-httppprof 给出运行时调试视图

因此,在 04 渗透攻击 的语境里,Linkerd 是非常典型的“观测面即控制面情报源”目标。只要 viztapadmin-http 进入低信任网络,攻击者就能把黑盒流量环境迅速转成白盒式服务拓扑与实时请求侦察。