276 lines
8.4 KiB
Markdown
276 lines
8.4 KiB
Markdown
# Probe Reference
|
|
|
|
## Overview
|
|
|
|
This document details each eBPF probe used for runtime evidence collection, including kernel requirements, captured data, and known limitations.
|
|
|
|
## Tracepoint Probes
|
|
|
|
### sys_enter_openat
|
|
|
|
**Location:** `tracepoint/syscalls/sys_enter_openat`
|
|
|
|
**Purpose:** Capture file access operations to prove which files were read or written.
|
|
|
|
**Kernel Requirement:** 2.6.16+ (openat syscall), 4.14+ for eBPF attachment
|
|
|
|
**Source File:** `src/Signals/__Libraries/StellaOps.Signals.Ebpf/Probes/Bpf/syscall_openat.bpf.c`
|
|
|
|
**Captured Fields:**
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `timestamp_ns` | u64 | Nanoseconds since boot |
|
|
| `pid` | u32 | Process ID |
|
|
| `tid` | u32 | Thread ID |
|
|
| `cgroup_id` | u64 | Kernel cgroup ID |
|
|
| `dfd` | int | Directory file descriptor |
|
|
| `flags` | int | Open flags (O_RDONLY, O_WRONLY, etc.) |
|
|
| `mode` | u16 | File mode for creation |
|
|
| `filename` | char[256] | File path |
|
|
| `comm` | char[16] | Process command name |
|
|
|
|
**Filtering:**
|
|
- Cgroup-based: Only capture events from specified containers
|
|
- Path-based: Allowlist/denylist patterns applied in user space
|
|
|
|
**Fallback:** For kernels without `openat` (pre-2.6.16), attaches to `sys_enter_open` instead.
|
|
|
|
**Performance Impact:** ~1-2% CPU at 10,000 opens/second
|
|
|
|
---
|
|
|
|
### sched_process_exec
|
|
|
|
**Location:** `tracepoint/sched/sched_process_exec`
|
|
|
|
**Purpose:** Capture process execution to prove which binaries were invoked.
|
|
|
|
**Kernel Requirement:** 3.4+ for tracepoint, 4.14+ for eBPF attachment
|
|
|
|
**Source File:** `src/Signals/__Libraries/StellaOps.Signals.Ebpf/Probes/Bpf/syscall_exec.bpf.c`
|
|
|
|
**Captured Fields:**
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `timestamp_ns` | u64 | Nanoseconds since boot |
|
|
| `pid` | u32 | Process ID (after exec) |
|
|
| `ppid` | u32 | Parent process ID |
|
|
| `cgroup_id` | u64 | Kernel cgroup ID |
|
|
| `filename` | char[256] | Executed binary path |
|
|
| `comm` | char[16] | Process command name |
|
|
| `argv0` | char[128] | First argument |
|
|
|
|
**Argv Capture:**
|
|
- Limited to first 4 arguments for safety
|
|
- Each argument truncated to 128 bytes
|
|
- Uses `bpf_probe_read_user_str()` with bounds checking
|
|
|
|
**Interpreter Detection:**
|
|
- Recognizes shebangs for Python, Node, Ruby, Shell scripts
|
|
- Maps `/usr/bin/python script.py` to script path
|
|
|
|
**Performance Impact:** Minimal (exec rate typically low)
|
|
|
|
---
|
|
|
|
### inet_sock_set_state
|
|
|
|
**Location:** `tracepoint/sock/inet_sock_set_state`
|
|
|
|
**Purpose:** Capture TCP connection lifecycle to prove network communication patterns.
|
|
|
|
**Kernel Requirement:** 4.16+ (tracepoint added), BTF recommended for CO-RE
|
|
|
|
**Source File:** `src/Signals/__Libraries/StellaOps.Signals.Ebpf/Probes/Bpf/syscall_network.bpf.c`
|
|
|
|
**Captured Fields:**
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `timestamp_ns` | u64 | Nanoseconds since boot |
|
|
| `pid` | u32 | Process ID |
|
|
| `cgroup_id` | u64 | Kernel cgroup ID |
|
|
| `oldstate` | u8 | Previous TCP state |
|
|
| `newstate` | u8 | New TCP state |
|
|
| `sport` | u16 | Source port |
|
|
| `dport` | u16 | Destination port |
|
|
| `family` | u8 | AF_INET (2) or AF_INET6 (10) |
|
|
| `saddr_v4` / `saddr_v6` | u32 / u8[16] | Source address |
|
|
| `daddr_v4` / `daddr_v6` | u32 / u8[16] | Destination address |
|
|
| `comm` | char[16] | Process command name |
|
|
|
|
**State Transition Filtering:**
|
|
- Default: Only `* -> ESTABLISHED` and `* -> CLOSE`
|
|
- Configurable: All transitions for debugging
|
|
|
|
**Address Formatting:**
|
|
- IPv4: Dotted decimal (e.g., `192.168.1.1`)
|
|
- IPv6: RFC 5952 compressed (e.g., `2001:db8::1`)
|
|
|
|
**Performance Impact:** ~1% CPU at high connection rate
|
|
|
|
---
|
|
|
|
## Uprobe Probes
|
|
|
|
### libc connect/accept
|
|
|
|
**Location:**
|
|
- `uprobe/libc.so.6:connect`
|
|
- `uretprobe/libc.so.6:connect`
|
|
- `uprobe/libc.so.6:accept`
|
|
- `uprobe/libc.so.6:accept4`
|
|
|
|
**Purpose:** Capture network operations at libc level as alternative to kernel tracepoints.
|
|
|
|
**Library Support:**
|
|
- glibc: `libc.so.6`
|
|
- musl: `libc.musl-*.so.1`
|
|
|
|
**Source File:** `src/Signals/__Libraries/StellaOps.Signals.Ebpf/Probes/Bpf/uprobe_libc.bpf.c`
|
|
|
|
**Captured Fields (connect):**
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `timestamp_ns` | u64 | Nanoseconds since boot |
|
|
| `pid` | u32 | Process ID |
|
|
| `cgroup_id` | u64 | Kernel cgroup ID |
|
|
| `fd` | int | Socket file descriptor |
|
|
| `family` | u16 | Address family |
|
|
| `addr` | varies | Remote address |
|
|
| `port` | u16 | Remote port |
|
|
| `comm` | char[16] | Process command name |
|
|
| `result` | int | Return value (from uretprobe) |
|
|
|
|
**Library Path Resolution:**
|
|
1. Parse `/etc/ld.so.cache` for library locations
|
|
2. Fall back to common paths (`/lib/x86_64-linux-gnu/`, etc.)
|
|
3. Handle container-specific paths via `/proc/{pid}/root`
|
|
|
|
**Byte Counting (optional):**
|
|
- `uprobe/libc.so.6:read` and `uprobe/libc.so.6:write`
|
|
- Tracks bytes per file descriptor
|
|
- Aggregated to prevent event flood
|
|
|
|
---
|
|
|
|
### OpenSSL SSL_read/SSL_write
|
|
|
|
**Location:**
|
|
- `uprobe/libssl.so.3:SSL_read`
|
|
- `uretprobe/libssl.so.3:SSL_read`
|
|
- `uprobe/libssl.so.3:SSL_write`
|
|
- `uretprobe/libssl.so.3:SSL_write`
|
|
|
|
**Purpose:** Capture TLS traffic volumes without decryption.
|
|
|
|
**Library Support:**
|
|
- OpenSSL 1.1.x: `libssl.so.1.1`
|
|
- OpenSSL 3.x: `libssl.so.3`
|
|
- LibreSSL: `libssl.so.*` (best-effort)
|
|
- BoringSSL: Limited support
|
|
|
|
**Source File:** `src/Signals/__Libraries/StellaOps.Signals.Ebpf/Probes/Bpf/uprobe_openssl.bpf.c`
|
|
|
|
**Captured Fields:**
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `timestamp_ns` | u64 | Nanoseconds since boot |
|
|
| `pid` | u32 | Process ID |
|
|
| `cgroup_id` | u64 | Kernel cgroup ID |
|
|
| `operation` | u8 | READ (0) or WRITE (1) |
|
|
| `requested_bytes` | u32 | Bytes requested |
|
|
| `actual_bytes` | u32 | Bytes transferred (from uretprobe) |
|
|
| `ssl_ptr` | u64 | SSL context pointer |
|
|
| `comm` | char[16] | Process command name |
|
|
|
|
**Session Correlation:**
|
|
- `ssl_ptr` can correlate with `SSL_get_fd` for socket mapping
|
|
- Optional: `SSL_get_peer_certificate` for peer info
|
|
|
|
**Byte Aggregation:**
|
|
- High-throughput connections aggregate to periodic summaries
|
|
- Prevents event flood on bulk data transfer
|
|
|
|
---
|
|
|
|
### Function Tracer (Generic)
|
|
|
|
**Location:** `uprobe/{binary}:{symbol}`
|
|
|
|
**Purpose:** Attach to arbitrary function symbols for custom evidence.
|
|
|
|
**Source File:** `src/Signals/__Libraries/StellaOps.Signals.Ebpf/Probes/Bpf/function_tracer.bpf.c`
|
|
|
|
**Captured Fields:**
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `timestamp_ns` | u64 | Nanoseconds since boot |
|
|
| `pid` | u32 | Process ID |
|
|
| `cgroup_id` | u64 | Kernel cgroup ID |
|
|
| `address` | u64 | Runtime address |
|
|
| `symbol_id` | u32 | Symbol identifier (from BPF map) |
|
|
| `comm` | char[16] | Process command name |
|
|
|
|
**Symbol Resolution:**
|
|
- User-space resolves address to symbol via ELF tables
|
|
- ASLR offset calculated from `/proc/{pid}/maps`
|
|
- Cached for performance
|
|
|
|
---
|
|
|
|
## Kernel Version Compatibility
|
|
|
|
| Feature | Minimum Kernel | Recommended |
|
|
|---------|---------------|-------------|
|
|
| Basic eBPF | 4.14 | 5.x+ |
|
|
| BTF (CO-RE) | 5.2 | 5.8+ |
|
|
| Ring buffer | 5.8 | 5.8+ |
|
|
| `sys_enter_openat` | 4.14 | 5.x+ |
|
|
| `sched_process_exec` | 4.14 | 5.x+ |
|
|
| `inet_sock_set_state` | 4.16 | 5.x+ |
|
|
| Uprobes | 4.14 | 5.x+ |
|
|
|
|
## Known Limitations
|
|
|
|
### Tracepoints
|
|
- **sys_enter_openat**: Path may be relative; resolution requires dfd lookup
|
|
- **sched_process_exec**: Argv reading limited by verifier complexity
|
|
- **inet_sock_set_state**: UDP not covered; use kprobe for UDP if needed
|
|
|
|
### Uprobes
|
|
- **Library resolution**: May fail for statically linked binaries
|
|
- **musl libc**: Some symbol names differ from glibc
|
|
- **OpenSSL**: Version detection required for correct symbol names
|
|
- **Stripped binaries**: Uprobes require symbol tables
|
|
|
|
### General
|
|
- **eBPF verifier**: Complex programs may be rejected
|
|
- **Container namespaces**: Paths may differ from host view
|
|
- **High event rate**: Ring buffer overflow possible under extreme load
|
|
|
|
## Troubleshooting
|
|
|
|
### Probe Failed to Attach
|
|
```
|
|
Error: Failed to attach tracepoint/syscalls/sys_enter_openat
|
|
```
|
|
- Check kernel version supports the tracepoint
|
|
- Verify eBPF is enabled (`CONFIG_BPF=y`, `CONFIG_BPF_SYSCALL=y`)
|
|
- Check permissions (CAP_BPF or root required)
|
|
|
|
### Missing BTF
|
|
```
|
|
Error: BTF not found for kernel version
|
|
```
|
|
- Install kernel BTF package (`linux-image-*-dbg` on Debian/Ubuntu)
|
|
- Use BTFHub for external BTF files
|
|
- Fall back to pre-compiled probes for specific kernel
|
|
|
|
### Ring Buffer Overflow
|
|
```
|
|
Warning: Ring buffer full, events dropped
|
|
```
|
|
- Increase buffer size: `--ring-buffer-size 1M`
|
|
- Enable more aggressive filtering
|
|
- Enable rate limiting: `--max-events-per-second 10000`
|