Network Perimeter / Service Mesh — Query Catalog
Generated: 2026-05-31 from Stage −1 OSINT pass (4 platforms). See: data/platform-intel/service-mesh-perimeter-osint-2026-05-31.md for full intel.
Threat model: These planes describe the cluster’s internal traffic by design. A reachable control/observability plane = cluster-wide recon API (service graph, pod IPs, mesh identities, mTLS certs, L7 metadata). Most ship no-auth-by-default and rely on network placement as the only control.
Source routing. High/odd ports (15000, 15014, 4191, 4245, 9962-9965, 20001, 8084) are Shodan-undersampled → Censys-preferred (full-range coverage). Shodan brand-dorks will undercount this category. Censys discovery search = web UI / Playwright (cencli search 403 on free); cencli view = per-asset verify, 1 credit. Identity-probe column is the aimap/grpcurl verification probe, not a dork.
Istio / Envoy
Auth default: Envoy admin (15000) no-auth, loopback-bound (reachable via co-tenant / nodePort). istiod debug (15014/15010) unauth pre-1.30. Kiali anonymous strategy = full cluster read.
Exposure class: /config_dump = full mesh topology + cert material; istiod /debug/registryz = full service registry; Kiali anon = cluster-wide read via Kiali SA.
| Label | Query | Source | Rationale | FP Risk |
|---|---|---|---|---|
| envoy-admin | port:15000 http.html:"config_dump" | Censys/Shodan | Envoy admin landing page links the admin endpoints | Med |
| istiod-metrics | port:15014 "pilot_xds" | Censys | pilot_xds* metric prefix is Istio-exclusive | Low |
| kiali-panel | http.title:"Kiali" | Shodan | Exact UI title | Low |
| spiffe-san | ssl:"spiffe://cluster.local" | Shodan/Censys | Workload URI SAN; custom trust domain attributes operator | Low |
| jaeger-codeploy | http.title:"Jaeger UI" | Shodan | Co-deployed trace UI, no-auth default | Low |
| identity-probe | GET :15000/server_info → json state=LIVE + node.user_agent_name=envoy + body sidecar~ | — | Confirms Istio-managed Envoy vs standalone | — |
| identity-probe | GET :15014/debug/endpointz → "serviceAccount"+"namespace"+.svc.cluster.local | — | istiod registry, gated 401 on 1.30+ | — |
Linkerd
Auth default: proxy admin (4191) no-auth on 0.0.0.0; viz dashboard (8084) no auth layer (Host-header guard only).
Exposure class: 4191 /env.json = proxy env (creds if env-injected); /metrics = workload graph; viz = full topology; tap = live cross-pod request headers (auth material).
| Label | Query | Source | Rationale | FP Risk |
|---|---|---|---|---|
| viz-panel | http.html:"data-controller-namespace=\"linkerd" | Shodan | Dashboard namespace attr (matches verified nuclei) | Low |
| viz-title | http.title:"Linkerd" | Shodan | UI title; pair with namespace attr | Med |
| proxy-admin | port:4191 "proxy_build_info" | Censys | Proxy metric, not in generic exporters | Low |
| identity-issuer | ssl.cert.subject.cn:"identity.linkerd.cluster.local" | Shodan/Censys | High-precision operator-attribution pivot | Low |
| trust-anchor | ssl:"root.linkerd.cluster.local" | Shodan/Censys | Linkerd trust anchor CN | Low |
| identity-probe | GET :4191/metrics → proxy_build_info+inbound_http_authz_allow_total; GET :4191/env.json → LINKERD2_PROXY_ | — | Presence + unauth env confirmation | — |
Cilium / Hubble
Auth default: Hubble Relay (4245) external listener plaintext gRPC, no auth by default. Hubble UI no auth. Metrics/health no auth.
Exposure class: GetFlows on 4245 = cluster-wide live flow tap (pods, identities, L7 HTTP/DNS/Kafka, policy verdicts). The category’s crown jewel.
| Label | Query | Source | Rationale | FP Risk |
|---|---|---|---|---|
| hubble-ui | http.title:"Hubble UI" | Shodan | Unique product title | V.Low |
| hubble-metrics | port:9965 "hubble_flows_processed_total" | Censys | Zero-FP Hubble metric | V.Low |
| cilium-metrics | "cilium_drop_count_total" | Censys | Cilium-exclusive metric namespace | V.Low |
| operator-metrics | port:9963 "cilium_operator" | Censys | Operator metrics, default-on all-iface | Low |
| hubble-grpc-san | ssl:"hubble-grpc.cilium.io" | Shodan/Censys | Relay/server cert SAN; leaks cluster name | V.Low |
| relay-grpc | port:4245 (full-range) → grpcurl reflect | Censys/tiptoe | gRPC, Shodan-dark; aimap gap, grpcurl manual | — |
| identity-probe | grpcurl -plaintext :4245 list → observer.Observer; observer.Observer/ServerStatus → num_flows,version | — | Identity + unauth confirmation in one call | — |
Pomerium
Auth default: Pomerium IS the auth layer. Presence trivial; finding is behavioral (public route → open relay). Exposure class: misconfigured route fronting internal tooling (Grafana/Kibana/Jupyter/Argo CD/Vault UI); pprof/metrics on public iface (split mode, <0.17.1); databroker JWT (<0.27.1).
| Label | Query | Source | Rationale | FP Risk |
|---|---|---|---|---|
| pomerium-cookie | http.headers.set_cookie:"_pomerium" | Shodan | Distinctive session cookie name | Low |
| pomerium-html | http.html:"pomerium" | Shodan | Catches login/error pages — also docs | Med |
| authenticate-san | ssl.cert.subject.an:"authenticate." | Censys/Shodan | authenticate. | Med |
| identity-probe | GET /.well-known/pomerium/jwks.json → json keys.0.use=sig+kty=EC | — | Deterministic unauth presence (NOT generic /.well-known/jwks.json) | — |
| misconfig-probe | route / returns 200 upstream content, no OIDC redirect to authenticate.pomerium.com in body | — | Behavioral open-relay state; not a finding until manually verified | — |
FP traps documented (do not re-run blind)
http.html:"pomerium"andhttp.title:"Linkerd"are single-token — pair with a second conjunct (cookie / namespace attr) per Insight #7.- nuclei
linkerd-ssrf*.yamltarget Linkerd 1.x l5d-dtab — silent-miss on 2.x; do not treat a null as “not vulnerable”. ssl:"spiffe://cluster.local"/*.default.hubble-grpc.cilium.iowith default names are noisy across many clusters; the custom trust-domain / cluster-name variants are the attribution-grade signals.- 200 on Envoy admin / Hubble UI / Linkerd viz = identity, not auth-state (Insight #16) — confirm with the data-layer identity-probe before counting unauth.
VERIFIED RESULTS (2026-05-31 survey, aimap v1.9.42)
23-host console-tier corpus (title-dorks). Per-plane data-layer verification:
- Kiali
http.title:"Kiali": 10 candidates, 4 confirmed anonymous via /kiali/api/namespaces (full ns array unauth), 6 unconfirmed. The 4 anon are bare-port (:80, :20001); the 6 unconfirmed are :443 TLS-ingress (gated auth-on or title reflection). The ~50% rule holds (Insight #15). Pattern: TLS-ingress Kiali tends auth-on, bare-port tends anon. - Hubble UI
http.title:"Hubble UI": 9 confirmed exposed (no login by design). Fingerprint anchors on the literal<title>Hubble UI</title>tag, not a bare “Hubble UI” substring (case-insensitive prose FP). - Cilium metrics
port:9965 "hubble_flows_processed_total"/"cilium_drop_count_total": zero-FP metric names, unauth by construction. - kube-apiserver (Cilium cluster-cert pivot, :6443): /version anon-readable (identity) but /api/v1/namespaces anon DENIED by RBAC. Do NOT score an exposed apiserver as unauth without the data-layer probe; 3/3 held here.
Console-tier bias (Insight #71 corollary). Title-dorks select the console tier. The data-plane tier (Envoy admin 15000, istiod 15014, Linkerd proxy-admin 4191, Hubble Relay 4245) is Shodan-dark and unmeasured by this corpus; Hubble Relay 4245 was internal on 0/12 confirmed Cilium hosts. Measure the data-plane tier with Censys full-range or tiptoe/naabu, not Shodan title-dorks.