Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/pages/en/dashboard_snapshots.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,15 @@ To create a new snapshot:
1. **Name** — Enter a descriptive name (e.g., `incident-2024-02-01`, `checkout-debug`)
2. **Nodes** — Select all nodes or specific worker nodes to include
3. **Time Window** — Select any start and end time within the available raw capture data using the date/time picker
4. Click **Create**
4. **Workload Filter** (optional) — Scope the snapshot to specific workloads:
- **Namespaces** — Include only traffic involving pods in the selected namespaces
- **Pod name regex** — Include only traffic involving pods whose names match the regex pattern
5. Click **Create**

The snapshot is extracted from [Raw Capture](/en/v2/raw_capture) buffers and moved to dedicated storage on the Hub. The time window can span from minutes to days — limited only by how much raw capture data is available.

When a workload filter is applied, the resulting PCAP contains only packets where at least one peer (source or destination) matches the filter criteria. This is useful in multi-tenant clusters where most captured traffic is irrelevant to the investigation.

---

## PCAP Export
Expand Down
4 changes: 4 additions & 0 deletions src/pages/en/dns.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ layout: ../../layouts/MainLayout.astro

**Kubeshark** provides UDP layer visibility into [Kubernetes’ DNS traffic](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/) by capturing all UDP streams that include DNS traffic. Once captured, DNS traffic is dissected and become available as any other protocol supported by **Kubeshark**.

### Self-Traffic Filtering

When `tap.capture.captureSelf` is disabled (the default), Kubeshark automatically filters out its own DNS queries to the configured cloud API endpoint from the traffic stream. This prevents Kubeshark's internal housekeeping DNS lookups from appearing alongside your application traffic. Other DNS queries made by Kubeshark pods (e.g., resolving in-cluster services) are still visible.

### DNS Log

Use **Kubeshark** to view a DNS log and export into a PCAP file. To view only DNS entries, use: `dns` in the [filter](/en/v2/kfl2) input. Use the [export to PCAP button](/en/pcap#manual-pcap-export) to export the DNS traffic to a PCAP file.
Expand Down
11 changes: 10 additions & 1 deletion src/pages/en/mcp/raw_capture_tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,23 @@ Create a new snapshot.
```json
{
"name": "incident-001",
"duration": "1h"
"duration": "1h",
"workload_filter": {
"namespaces": ["production", "payments"],
"pod_regex": "checkout-.*"
}
}
```

| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Unique snapshot identifier |
| `duration` | string | Time duration to capture (e.g., `30m`, `1h`, `2h`) |
| `workload_filter` | object | (Optional) Scope the snapshot to specific workloads |
| `workload_filter.namespaces` | []string | Include only traffic involving pods in these namespaces |
| `workload_filter.pod_regex` | string | Include only traffic involving pods matching this regex |

When `workload_filter` is provided, the resulting PCAP contains only packets where at least one peer matches the filter. Both fields are optional within the filter object — omit either to not filter on that dimension.

**Response:**
```json
Expand Down
4 changes: 4 additions & 0 deletions src/pages/en/oidc.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ After configuring the values file, install Kubeshark:
helm install kubeshark kubeshark/kubeshark -f ./values.yaml
```

### Login Behavior

Kubeshark sends `prompt=login` on every OIDC authorize request, forcing the IdP to re-prompt for credentials on each login. After logging out of Kubeshark, the IdP will not silently re-authenticate the user from a leftover SSO session cookie — operators can pick a different user without clearing browser state. This does not affect the IdP session for other applications in the same org.

### Try Your OIDC-Enabled Kubeshark

Once OIDC is enabled you'll be redirected to your IdP's login page. The screenshots below show Dex; Okta / Auth0 / Keycloak follow the same flow.
Expand Down
4 changes: 4 additions & 0 deletions src/pages/en/saml.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ auth:
> - Per-role `filter` (raw KFL string) was replaced with `namespaces` (comma list, see below). Configs carrying `filter:` are ignored at unmarshal — migrate to `namespaces:`.
> - `auth.defaultFilter` is removed. The deny-default semantic moves into per-role `namespaces: ""`; opt out for admin roles with `namespaces: "*"`.

### Login Behavior

Kubeshark sends `ForceAuthn=true` on every SAML AuthnRequest, forcing the IdP to re-prompt for credentials on each login. After logging out of Kubeshark, the IdP will not silently re-authenticate the user from a leftover SSO session cookie — operators can pick a different user without clearing browser state. This does not affect the IdP session for other applications in the same org.

### X.509 Certificate & Key

```shell
Expand Down
49 changes: 49 additions & 0 deletions src/pages/en/v2/kfl2.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ Boolean variables that indicate which protocol was detected. Use these as the fi
| `grpc` | gRPC over HTTP/2 | `conn` / `flow` | L4 connection/flow tracking |
| `radius` | RADIUS | `tcp_conn` / `udp_conn` | Transport-specific connections |
| `diameter` | Diameter | `tcp_flow` / `udp_flow` | Transport-specific flows |
| `tlsx` | TLS handshake (ClientHello/ServerHello) | `mongodb` | MongoDB |
| `mysql` | MySQL | `postgresql` | PostgreSQL |

### Identity and Metadata Variables

Expand Down Expand Up @@ -249,6 +251,20 @@ gRPC traffic is detected as a sub-protocol of HTTP/2. When `grpc` is true, all H
| `tls_response_size` | int | TLS response size in bytes |
| `tls_total_size` | int | Sum of request + response sizes |

### TLS Handshake Variables (TLSX)

These variables are available when `tlsx` is true (TLS ClientHello or ServerHello entries). See [TLS Handshake Inspection](/en/tls_handshake_inspection) for details.

| Variable | Type | Description |
|----------|------|-------------|
| `tls_sni` | string | Server Name Indication hostname (from ClientHello) |
| `tls_cipher_suite` | int | Negotiated cipher suite ID (from ServerHello) |
| `tls_cipher_suites` | []string | Offered cipher suite names (from ClientHello) |
| `tls_alpn` | string | Negotiated ALPN protocol |
| `tls_version` | int | Negotiated TLS version (from ServerHello) |

> **Note:** `tlsx` is different from `tls`. The `tls` flag indicates traffic captured via eBPF TLS interception (decrypted HTTPS). The `tlsx` flag indicates TLS handshake entries (ClientHello/ServerHello) parsed from unencrypted handshake bytes.

### TCP Variables

| Variable | Type | Description |
Expand Down Expand Up @@ -648,6 +664,37 @@ KFL is statically typed. Common gotchas:
- Map access on missing keys errors — use `key in map` or `map_get()` first
- List membership uses `value in list` — not `list.contains(value)`

## Protocol Scoping

Protocol-specific variables are automatically scoped to their owning protocol. A filter like `status_code == 200` only matches HTTP entries — it will never match DNS, Kafka, or other protocol entries, even when their default value would satisfy the comparison.

This applies to all comparison operators (`==`, `!=`, `<`, `<=`, `>`, `>=`), membership (`in`), string functions (`contains`, `startsWith`, `endsWith`, `matches`), and CEL list macros (`.exists`, `.all`, `.filter`, `.map`).

You can still prefix with the protocol flag for readability (`http && status_code == 200`), but it is no longer required for correctness.

### Field Existence and Absence

Use a protocol-specific variable as a bareword to test whether entries of that protocol exist:

```cel
# Every HTTP entry (field existence)
status_code

# Every non-HTTP entry (field absence)
!status_code

# Every DNS entry
dns_questions

# Every Kafka entry
kafka_api_key

# Every TLS handshake entry
tls_sni
```

This works for all non-boolean protocol variables. Boolean protocol variables (`dns_request`, `kafka_request`, `ws_request`, etc.) retain their original value semantics when used as barewords.

## Default Values

When a variable is not present in an entry, KFL uses these defaults:
Expand All @@ -661,6 +708,8 @@ When a variable is not present in an entry, KFL uses these defaults:
| map | `{}` |
| bytes | `[]` |

> **Note:** Default values only apply within the owning protocol's scope. A filter like `status_code == 0` matches only HTTP entries where the status is actually zero — it does not match non-HTTP entries.

## Performance Tips

1. **Protocol flags first** — `http && ...` is faster than `... && http`
Expand Down
1 change: 1 addition & 0 deletions src/pages/en/v2/traffic_snapshots.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Traffic Snapshots extract any time window from the available [Raw Capture](/en/v

**Key value:**
- **Download cluster-wide PCAPs** — filtered by time, nodes, workloads, and IPs. Get exactly what matters, ready for Wireshark or any PCAP-compatible tool.
- **Workload-scoped snapshots** — scope a snapshot to specific Kubernetes namespaces and/or a pod-name regex, so the resulting PCAP contains only traffic involving the matching pods.
- **Long-term retention** — store snapshots and PCAPs in cloud storage (S3, Azure Blob) for compliance, audits, and future investigation.

---
Expand Down