ebpf

package
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 30, 2026 License: AGPL-3.0 Imports: 27 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ComputeHPowerTable

func ComputeHPowerTable(h [16]byte) [11][16]byte

ComputeHPowerTable precomputes H^(2^i) for i = 0..10, giving powers H^1, H^2, H^4, H^8, ..., H^1024. This table enables the eBPF kprobe to compute arbitrary H^n via at most 11 GF(2^128) multiplications (one per set bit in n).

func GF128HPower

func GF128HPower(h [16]byte, power uint32) [16]byte

GF128HPower computes H^power in GF(2^128) via square-and-multiply.

func GF128Mul

func GF128Mul(a, b [16]byte) [16]byte

GF128Mul multiplies two 128-bit elements in GF(2^128) using the GHASH bit convention. Both inputs and the result are 16-byte arrays in big-endian byte order with MSB-first bit numbering.

func GHASHCompute

func GHASHCompute(h [16]byte, blocks [][16]byte) [16]byte

GHASHCompute computes GHASH(H, data) where data is the concatenation of all GHASH input blocks (AAD padded + ciphertext padded + length block). Returns the 16-byte GHASH output.

func GHASHIncrementalDelta

func GHASHIncrementalDelta(h [16]byte, changedBlocks map[int][16]byte, totalCTBlocks int) [16]byte

GHASHIncrementalDelta computes the tag delta when ciphertext blocks change. changedBlocks maps block index (0-based within ciphertext) to (old XOR new) delta. totalCTBlocks is the total number of ciphertext blocks. Returns the 16-byte tag delta: new_tag = old_tag XOR delta.

Types

type GoTLSOffsets

type GoTLSOffsets struct {
	ConnToCipher uint32 // Conn.out offset + halfConn.cipher offset + 8 (interface data_ptr)
	AEADIfaceOff uint32 // prefixNonceAEAD.aead offset + 8 (interface data_ptr)
	H2HiOff      uint32 // GCM + off → high 64 bits of H×2 (byte-swapped)
	H2LoOff      uint32 // GCM + off → low 64 bits of H×2 (byte-swapped)
	ConnVersOff  uint32 // Conn + off → uint16 negotiated TLS version (e.g. 0x0303, 0x0304)
}

GoTLSOffsets contains struct offsets for extracting the GHASH H key from Go's crypto/tls internal structures. The layout must match struct go_tls_offsets in tls_uprobe.c exactly.

H extraction chain (3 pointer dereferences + GF(2^128) halving):

Conn + ConnToCipher → cipher interface data_ptr → AEAD wrapper
  + AEADIfaceOff → inner aead interface data_ptr → GCM struct
    + H2HiOff / H2LoOff → H×2 (two 64-bit words from productTable[224])

Go's gcmAesInit assembly computes H = AES_K(0^128), byte-swaps, then doubles in GF(2^128) before storing at productTable offset 224. The BPF code reads the two words and applies GF halving to recover standard H.

The word order at offset 224 is architecture-dependent:

  • AMD64 (PSHUFB full reversal): hi word at +8, lo word at +0
  • ARM64 (VREV64 per-lane reversal): hi word at +0, lo word at +8

func DetectGoTLSOffsets

func DetectGoTLSOffsets(exePath string) (version string, offsets GoTLSOffsets, err error)

DetectGoTLSOffsets reads a Go binary and returns the struct offsets needed for H extraction. Tries DWARF first, then falls back to version-based lookup.

type TLSOffsets

type TLSOffsets struct {
	SSLToWRL       uint32 // 4-hop: SSL* → WRL*. 3-hop: SSL* → EVP_CIPHER_CTX* (when WRLToEncCtx=0)
	WRLToEncCtx    uint32 // wrl* → EVP_CIPHER_CTX*. 0 = 3-hop mode (no record layer)
	EncCtxToAlgctx uint32 // enc_ctx* + off → algctx/PROV_GCM_CTX* (pointer deref)
	AlgctxToH      uint32 // algctx* + off → H (16 bytes, direct read)
	SSLToVersion   uint32 // SSL_CONNECTION* + off → int version (0xFFFFFFFF=unknown, use heuristic)
}

TLSOffsets contains struct offsets for extracting TLS key material from an SSL* object at runtime. Two chain variants exist:

4-hop (OpenSSL 3.2+):

SSL* + SSLToWRL → WRL* + WRLToEncCtx → EVP_CIPHER_CTX* + EncCtxToAlgctx → algctx* + AlgctxToH → H

3-hop (OpenSSL 3.0-3.1):

SSL* + SSLToWRL → EVP_CIPHER_CTX* + EncCtxToAlgctx → algctx* + AlgctxToH → H

The 3-hop chain skips the record layer indirection. SSLToWRL stores the enc_write_ctx offset directly, and WRLToEncCtx=0 signals 3-hop mode to BPF.

These are version-specific and must match the OpenSSL build in the container.

func DetectOpenSSLVersion

func DetectOpenSSLVersion(pid int, libPath string) (version string, offsets TLSOffsets, err error)

DetectOpenSSLVersion reads an OpenSSL/libssl shared library from a container's filesystem and determines its version. Returns the version string (e.g., "3.2.1") and the corresponding struct offsets.

The library is accessed via /proc/<pid>/root/<libPath> to reach into the container's overlay filesystem.

type TLSUprobeManager

type TLSUprobeManager struct {
	// contains filtered or unexported fields
}

TLSUprobeManager manages the loading and attaching of eBPF uprobes for TLS interception.

func NewTLSUprobeManager

func NewTLSUprobeManager(k8sReader client.Reader, cgroupRoot string, log *zap.SugaredLogger) (*TLSUprobeManager, error)

NewTLSUprobeManager initializes a new uprobe manager.

func (*TLSUprobeManager) AttachTLS

func (m *TLSUprobeManager) AttachTLS(pid int, cgroupID uint64) error

AttachTLS attaches system-wide eBPF uprobes to all TLS libraries in a container. The uprobes fire for ALL processes in the container (same overlay mount = same inode). The BPF cgroup filter restricts interception to tracked containers only.

func (*TLSUprobeManager) Close

func (m *TLSUprobeManager) Close() error

Close releases all links and the eBPF manager.

Each link.Close on a uprobe is a kernel syscall that takes ~50-100 ms, and m.links accumulates one entry per uprobe attachment over the daemonset's lifetime. On a long-running cluster with churning pods this reaches into the thousands; closing serially blows past kubelet's terminationGracePeriodSeconds and the pod is SIGKILL'd before the Go runtime gets to flush exit hooks (which lost us the e2e covcounters flush, among other things). Close concurrently with a bounded worker pool so wall time stays inside the grace period regardless of how long the controller has been running.

func (*TLSUprobeManager) DumpDebugCounters

func (m *TLSUprobeManager) DumpDebugCounters()

DumpDebugCounters reads and logs all debug counters from the BPF map.

func (*TLSUprobeManager) PollEvents

func (m *TLSUprobeManager) PollEvents(ctx context.Context) error

PollEvents reads TLS events from the ring buffer and periodically syncs secrets to the eBPF map.

func (*TLSUprobeManager) PollExecEvents

func (m *TLSUprobeManager) PollExecEvents(ctx context.Context) error

PollExecEvents reads process exec events from the proc_events ring buffer and attaches TLS uprobes to newly exec'd processes in tracked containers.

func (*TLSUprobeManager) PopulateTrustedDNSServers

func (m *TLSUprobeManager) PopulateTrustedDNSServers(ips []net.IP) error

PopulateTrustedDNSServers adds trusted DNS server IPs to the BPF map and enables the whitelist. If ips is empty, the whitelist is not enabled and all DNS responses are accepted.

func (*TLSUprobeManager) RecordCgroupNetns

func (m *TLSUprobeManager) RecordCgroupNetns(cgroupID uint64, pid int)

RecordCgroupNetns records the cgroup → netns inode mapping for a container process. This enables cleanup of the tcAttached entry (which pins the netns fd) when the cgroup is untracked on pod deletion.

func (*TLSUprobeManager) TrackCgroup

func (m *TLSUprobeManager) TrackCgroup(cgroupID uint64, cgroupPath string) error

TrackCgroup adds a container cgroup ID to the tracked_cgroups map, enabling exec/exit tracepoint processing for processes in that cgroup.

func (*TLSUprobeManager) TrackTGID

func (m *TLSUprobeManager) TrackTGID(tgid uint32) error

TrackTGID adds a process TGID to the tracked_tgids map, enabling DNS/connect tracepoint processing for that process.

func (*TLSUprobeManager) UntrackCgroup

func (m *TLSUprobeManager) UntrackCgroup(cgroupID uint64) error

UntrackCgroup removes a container cgroup ID from the tracked_cgroups map and cleans up the associated tc attachment state. When the last cgroup referencing a netns is untracked, the pinned netns fd is closed, allowing the kernel to free the inode for reuse.

func (*TLSUprobeManager) UntrackTGID

func (m *TLSUprobeManager) UntrackTGID(tgid uint32) error

UntrackTGID removes a process TGID from the tracked_tgids map. go_tls_offset_config is keyed by cgroup_id, not tgid, and is cleaned up via UntrackCgroup when the container is removed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL