Documentation
¶
Index ¶
- func ComputeHPowerTable(h [16]byte) [11][16]byte
- func GF128HPower(h [16]byte, power uint32) [16]byte
- func GF128Mul(a, b [16]byte) [16]byte
- func GHASHCompute(h [16]byte, blocks [][16]byte) [16]byte
- func GHASHIncrementalDelta(h [16]byte, changedBlocks map[int][16]byte, totalCTBlocks int) [16]byte
- type GoTLSOffsets
- type TLSOffsets
- type TLSUprobeManager
- func (m *TLSUprobeManager) AttachTLS(pid int, cgroupID uint64) error
- func (m *TLSUprobeManager) Close() error
- func (m *TLSUprobeManager) DumpDebugCounters()
- func (m *TLSUprobeManager) PollEvents(ctx context.Context) error
- func (m *TLSUprobeManager) PollExecEvents(ctx context.Context) error
- func (m *TLSUprobeManager) PopulateTrustedDNSServers(ips []net.IP) error
- func (m *TLSUprobeManager) RecordCgroupNetns(cgroupID uint64, pid int)
- func (m *TLSUprobeManager) TrackCgroup(cgroupID uint64, cgroupPath string) error
- func (m *TLSUprobeManager) TrackTGID(tgid uint32) error
- func (m *TLSUprobeManager) UntrackCgroup(cgroupID uint64) error
- func (m *TLSUprobeManager) UntrackTGID(tgid uint32) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ComputeHPowerTable ¶
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 ¶
GF128HPower computes H^power in GF(2^128) via square-and-multiply.
func GF128Mul ¶
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 ¶
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 ¶
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.