<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tetragon Archives - Linuxcent</title>
	<atom:link href="https://linuxcent.com/tag/tetragon/feed/" rel="self" type="application/rss+xml" />
	<link>https://linuxcent.com/tag/tetragon/</link>
	<description>Infrastructure security, from the kernel up.</description>
	<lastBuildDate>Wed, 13 May 2026 15:36:53 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://linuxcent.com/wp-content/uploads/2026/04/favicon-512x512-1-150x150.png</url>
	<title>Tetragon Archives - Linuxcent</title>
	<link>https://linuxcent.com/tag/tetragon/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">211632295</site>	<item>
		<title>LSM and Tetragon — When the Kernel Says No</title>
		<link>https://linuxcent.com/ebpf-lsm-tetragon-runtime-security/</link>
					<comments>https://linuxcent.com/ebpf-lsm-tetragon-runtime-security/#respond</comments>
		
		<dc:creator><![CDATA[Vamshi Krishna Santhapuri]]></dc:creator>
		<pubDate>Fri, 12 Jun 2026 02:00:00 +0000</pubDate>
				<category><![CDATA[eBPF]]></category>
		<category><![CDATA[Cilium]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[linux-security]]></category>
		<category><![CDATA[LSM]]></category>
		<category><![CDATA[Runtime Security]]></category>
		<category><![CDATA[SRE]]></category>
		<category><![CDATA[Tetragon]]></category>
		<guid isPermaLink="false">https://linuxcent.com/?p=1841</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 9</span> <span class="rt-label rt-postfix">minutes</span></span>LSM hooks with eBPF enforce security policy at the syscall boundary before the operation completes. How Tetragon kills processes from kernel space and why that difference matters.</p>
<p>The post <a href="https://linuxcent.com/ebpf-lsm-tetragon-runtime-security/">LSM and Tetragon — When the Kernel Says No</a> appeared first on <a href="https://linuxcent.com">Linuxcent</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 9</span> <span class="rt-label rt-postfix">minutes</span></span><style>
pre{position:relative;background:#1e1e1e;color:#d4d4d4;
    padding:16px 16px 16px 20px;border-radius:6px;overflow-x:auto;
    font-family:'JetBrains Mono','Fira Code','Cascadia Code',Consolas,'Courier New',monospace;
    font-size:.88em;line-height:1.6;border-left:4px solid #555}
code{background:#f4f4f4;padding:2px 5px;border-radius:3px;font-size:.9em}
pre code{background:transparent;padding:0;color:inherit}
pre[data-lang="bash"],pre[data-lang="sh"],
pre[data-lang="shell"],pre[data-lang="zsh"]{border-left-color:#4ec9b0}
pre[data-lang="yaml"],pre[data-lang="json"],
pre[data-lang="toml"],pre[data-lang="xml"]{border-left-color:#569cd6}
pre[data-lang="python"],pre[data-lang="go"],pre[data-lang="rust"],
pre[data-lang="java"],pre[data-lang="c"],pre[data-lang="cpp"]{border-left-color:#c586c0}
pre[data-lang="text"],pre[data-lang="output"],
pre[data-lang="console"]{border-left-color:#888}
.lc-copy-btn{position:absolute;top:8px;right:8px;background:#2d2d2d;color:#ccc;
    border:1px solid #444;border-radius:4px;padding:3px 9px;font-size:.75em;
    font-family:system-ui,sans-serif;cursor:pointer;opacity:0;
    transition:opacity .15s,background .15s;line-height:1.6}
pre:hover .lc-copy-btn{opacity:1}
.lc-copy-btn:hover{background:#3a3a3a;color:#fff}
.lc-copy-btn.copied{color:#4ec9b0;border-color:#4ec9b0}
.lc-lang-badge{position:absolute;top:8px;left:20px;font-family:system-ui,sans-serif;
    font-size:.7em;color:#666;text-transform:uppercase;letter-spacing:.04em;
    line-height:1;pointer-events:none;opacity:0;transition:opacity .15s}
pre:hover .lc-lang-badge{opacity:1}
table{border-collapse:collapse;width:100%;margin:16px 0}
th,td{border:1px solid #ddd;padding:10px 14px;text-align:left}
th{background:#f0f0f0;font-weight:600}
tr:nth-child(even){background:#fafafa}
</style>
<p><script>
(function(){
  if(window.__lcCodeEnhanced)return;
  window.__lcCodeEnhanced=true;
  function enhance(){
    document.querySelectorAll('pre').forEach(function(pre){
      var code=pre.querySelector('code');
      var lang='';
      if(code){var m=(code.className||'').match(/language-(\S+)/);if(m)lang=m[1].toLowerCase();}
      if(lang)pre.setAttribute('data-lang',lang);
      if(lang){var badge=document.createElement('span');badge.className='lc-lang-badge';badge.textContent=lang;pre.insertBefore(badge,pre.firstChild);}
      var btn=document.createElement('button');
      btn.className='lc-copy-btn';btn.textContent='Copy';btn.setAttribute('aria-label','Copy code to clipboard');
      pre.appendChild(btn);
      btn.addEventListener('click',function(){
        var text=code?code.innerText:pre.innerText;
        if(navigator.clipboard&&window.isSecureContext){
          navigator.clipboard.writeText(text).then(function(){ok(btn);}).catch(function(){fb(text,btn);});
        }else{fb(text,btn);}
      });
    });
  }
  function ok(btn){btn.textContent='Copied!';btn.classList.add('copied');setTimeout(function(){btn.textContent='Copy';btn.classList.remove('copied');},2000);}
  function fb(text,btn){
    try{var ta=document.createElement('textarea');ta.value=text;ta.style.cssText='position:fixed;left:-9999px;top:-9999px;opacity:0';document.body.appendChild(ta);ta.select();document.execCommand('copy');document.body.removeChild(ta);ok(btn);}
    catch(e){btn.textContent='✗ Failed';setTimeout(function(){btn.textContent='Copy';},2000);}
  }
  if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',enhance);}else{enhance();}
})();
</script></p>
<p><em>eBPF: From Kernel to Cloud, Episode 12</em><br />
<a href="/what-is-ebpf/">What Is eBPF?</a> · <a href="/ebpf-verifier-safety/">The BPF Verifier</a> · <a href="/ebpf-vs-kernel-modules/">eBPF vs Kernel Modules</a> · <a href="/ebpf-program-types/">eBPF Program Types</a> · <a href="/ebpf-maps-persistent-data/">eBPF Maps</a> · <a href="/co-re-libbpf-write-once/">CO-RE and libbpf</a> · <a href="/xdp-network-fast-path/">XDP</a> · <a href="/tc-ebpf-pod-network-policy/">TC eBPF</a> · <a href="/bpftrace-kernel-observability/">bpftrace</a> · <a href="/network-flow-observability-ebpf/">Network Flow Observability</a> · <a href="/dns-kernel-observability/">DNS Observability</a> · <strong>LSM and Tetragon</strong></p>
<hr />
<p style="font-size:0.72em;font-weight:700;letter-spacing:0.12em;color:#f59e0b;text-transform:uppercase;margin:2em 0 0.75em 0;text-align:center;">Architecture Overview</p>
<figure class="wp-block-image size-full" style="margin:0 0 0.5em 0;">
<img fetchpriority="high" decoding="async" width="2400" height="1578" src="https://linuxcent.com/wp-content/uploads/2026/05/ep12-lsm-tetragon-og-2.png" alt="LSM BPF and Tetragon — kernel security enforcement architecture showing syscall interception and policy evaluation" class="wp-image-2121" style="width:100%;height:auto;display:block;border-radius:8px;" srcset="https://linuxcent.com/wp-content/uploads/2026/05/ep12-lsm-tetragon-og-2.png 2400w, https://linuxcent.com/wp-content/uploads/2026/05/ep12-lsm-tetragon-og-2-300x197.png 300w, https://linuxcent.com/wp-content/uploads/2026/05/ep12-lsm-tetragon-og-2-1024x673.png 1024w, https://linuxcent.com/wp-content/uploads/2026/05/ep12-lsm-tetragon-og-2-768x505.png 768w, https://linuxcent.com/wp-content/uploads/2026/05/ep12-lsm-tetragon-og-2-1536x1010.png 1536w, https://linuxcent.com/wp-content/uploads/2026/05/ep12-lsm-tetragon-og-2-2048x1347.png 2048w" sizes="(max-width: 2400px) 100vw, 2400px" /><figcaption style="text-align:center;font-size:0.85em;color:#6b7280;margin-top:0.75em;">LSM BPF hooks fire before every sensitive syscall — Tetragon uses them to enforce and kill, not just observe.</figcaption></figure>
<hr style="border:none;border-top:1px solid #e5e7eb;margin:0.5em 0 2em 0;"/>
<h2 id="tldr">TL;DR</h2>
<ul>
<li>LSM eBPF Tetragon integrates Linux Security Module hooks with eBPF programs — enforcement happens at the syscall boundary, before the operation completes, with no detect-and-respond window<br />
  <em>(LSM hook = Linux Security Module hook: a callback point built into the kernel that fires before a security-relevant operation completes, allowing the security module to approve or reject it)</em></li>
<li>Falco and similar sidecar-based tools detect after the fact — the syscall returns, the file is written, the connection is established, the alert fires; with LSM, the syscall never returns success</li>
<li><code class="" data-line="">BPF_PROG_TYPE_LSM</code> is the eBPF program type that attaches to LSM hooks — introduced in kernel 5.7, stable in 5.10+; available on all current Ubuntu LTS, Fedora, and EKS/GKE nodes</li>
<li>Tetragon attaches eBPF programs to LSM hooks and kprobes simultaneously — observing and enforcing from the same kernel attachment point</li>
<li>Tetragon&#8217;s enforcement sends <code class="" data-line="">SIGKILL</code> from within the kernel context — not from a userspace agent reading an audit log and then killing the process</li>
<li>Production caution: LSM enforce mode without thorough policy testing in audit mode first will kill legitimate workloads; always audit before enforce</li>
</ul>
<hr />
<p>EP11 showed how to observe DNS queries at the kernel level — seeing what a workload resolves before it establishes a connection. But observation is passive. It tells you what happened. LSM eBPF Tetragon changes the question entirely: instead of watching the workload, the kernel refuses the operation. This episode covers how that enforcement layer works and why the difference between &#8220;detect&#8221; and &#8220;prevent&#8221; matters in runtime security.</p>
<h2 id="quick-check-is-your-cluster-running-lsm-based-enforcement">Quick Check: Is Your Cluster Running LSM-Based Enforcement?</h2>
<pre><code class="" data-line=""># On any cluster node — what security modules are active?
cat /sys/kernel/security/lsm

# Expected output on a modern kernel:
# lockdown,capability,landlock,yama,apparmor,bpf
#                                              ^^^
#                            &quot;bpf&quot; here means BPF LSM is enabled
</code></pre>
<pre><code class="" data-line=""># Is Tetragon running on this cluster?
kubectl get pods -n kube-system -l app.kubernetes.io/name=tetragon

# If Tetragon is present, check what TracingPolicies are enforcing:
kubectl get tracingpolicies -A

# Sample output:
# NAMESPACE    NAME                      AGE
# kube-system  block-privileged-exec     3d
# kube-system  restrict-sensitive-paths  3d
</code></pre>
<pre><code class="" data-line=""># See what eBPF programs Tetragon has loaded
bpftool prog list | grep -i tetragon

# Output sample:
# 89: lsm  name tetragon_lsm_bprm  tag 8f2a1c3e4d5b7a9f  gpl
#     loaded_at 2026-04-22T09:13:45+0530  uid 0
#     xlated 3312B  jited 2184B  memlock 8192B
# 91: kprobe  name tetragon_kp_exec tag 3c1d8e2f7a4b5c9d  gpl
</code></pre>
<p><code class="" data-line="">lsm</code> program type confirms LSM hook attachment. If you see <code class="" data-line="">tetragon_lsm_*</code> entries, Tetragon is enforcing at the kernel level on this node.</p>
<blockquote>
<p><strong>Not running Tetragon?</strong> Check if your cluster uses AppArmor or seccomp profiles instead — <code class="" data-line="">kubectl get pod &lt;name&gt; -o jsonpath=&#039;{.metadata.annotations}&#039;</code> and look for <code class="" data-line="">seccomp.security.alpha.kubernetes.io</code> or <code class="" data-line="">container.apparmor.security.beta.kubernetes.io</code> annotations. These are userspace-applied profiles that the kernel enforces. Tetragon is additive — it can run alongside AppArmor/seccomp and provides per-process, dynamic policy that static profiles cannot.</p>
</blockquote>
<hr />
<p>Falco fired at 03:14 AM. The alert: a process inside a production container had opened <code class="" data-line="">/etc/passwd</code> for writing. By the time I was on the call, the container had been restarted by a health check failure — the compromised process had already exited. The file had already been modified. Falco had detected the open, emitted the alert, and by the time any automated response could have acted, the syscall had returned, the write had completed, and the file was changed.</p>
<p>Falco did exactly what it&#8217;s designed to do: observe and alert. The gap isn&#8217;t in Falco — it&#8217;s in the architecture. When a tool detects from userspace by reading kernel audit events, there is always a window between the operation completing and the alert firing. For a fast exploit, that window is the entire attack.</p>
<p>I added a Tetragon TracingPolicy the following week:</p>
<pre><code class="" data-line="">spec:
  kprobes:
    - call: &quot;security_inode_permission&quot;
      syscall: false
      return: false
      args:
        - index: 0
          type: &quot;inode&quot;
      selectors:
        - matchArgs:
            - index: 0
              operator: &quot;Prefix&quot;
              values: [&quot;/etc/passwd&quot;, &quot;/etc/shadow&quot;]
          matchActions:
            - action: Sigkill
</code></pre>
<p>Next time a process tries to open <code class="" data-line="">/etc/passwd</code> for writing in a container covered by that policy, the kernel sends <code class="" data-line="">SIGKILL</code> from within the LSM hook. The open never completes. There is no window.</p>
<hr />
<h2 id="how-lsm-hooks-are-placed-in-the-kernel">How LSM Hooks Are Placed in the Kernel</h2>
<p>Linux Security Modules (LSM) is a framework built into the Linux kernel that inserts hook points before security-sensitive operations. The hook fires before the operation is allowed to complete — the LSM module can return an error code that causes the kernel to reject the operation and return <code class="" data-line="">-EPERM</code> to the calling process.</p>
<pre><code class="" data-line="">Process calls open(&quot;/etc/passwd&quot;, O_WRONLY)
      ↓
VFS (Virtual Filesystem) layer receives the request
      ↓
VFS calls security_inode_permission()   ← LSM hook fires here
      ↓
LSM module checks policy
      ↓
      ├── ALLOW → open() proceeds, file descriptor returned
      └── DENY  → open() returns -EPERM, process gets &quot;Permission denied&quot;
                  File is never touched
</code></pre>
<blockquote>
<p><strong><code class="" data-line="">LSM hook</code></strong> — a callback point embedded in Linux kernel source at every security-sensitive operation: file open, execute, socket connect, capability check, mount, ptrace, and more. The kernel calls registered LSM modules at each hook. Before BPF LSM (kernel 5.7), only statically compiled security modules (SELinux, AppArmor, BPF LSM itself) could register at these hooks.</p>
<p><strong><code class="" data-line="">BPF_PROG_TYPE_LSM</code></strong> — the eBPF program type that attaches to LSM hooks. Introduced in kernel 5.7. Requires BPF LSM to be enabled in the kernel (<code class="" data-line="">lsm=bpf</code> in kernel command line, or present alongside other LSMs). When this program type is loaded and attached to an LSM hook, the eBPF program runs at the hook point and returns 0 (allow) or a negative error code (deny).</p>
</blockquote>
<p>The full list of LSM hooks:</p>
<pre><code class="" data-line=""># All LSM hook points available for eBPF attachment
bpftool feature list | grep lsm_hook | head -20

# Or browse the kernel source list:
# include/linux/security.h — every security_*() function is an LSM hook point
</code></pre>
<p>There are 200+ LSM hook points. The most operationally relevant for container security:</p>
<table>
<thead>
<tr>
<th>LSM Hook</th>
<th>What it guards</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="" data-line="">security_bprm_check</code></td>
<td>Process execution (execve)</td>
</tr>
<tr>
<td><code class="" data-line="">security_inode_permission</code></td>
<td>File read/write/execute</td>
</tr>
<tr>
<td><code class="" data-line="">security_inode_create</code></td>
<td>File creation</td>
</tr>
<tr>
<td><code class="" data-line="">security_socket_connect</code></td>
<td>Outbound TCP/UDP connect</td>
</tr>
<tr>
<td><code class="" data-line="">security_socket_bind</code></td>
<td>Port binding</td>
</tr>
<tr>
<td><code class="" data-line="">security_ptrace_access_check</code></td>
<td>ptrace (debugger attach)</td>
</tr>
<tr>
<td><code class="" data-line="">security_capable</code></td>
<td>Capability checks (CAP_SYS_ADMIN etc.)</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="how-tetragon-combines-lsm-and-kprobe">How Tetragon Combines LSM and kprobe</h2>
<p>Tetragon attaches two types of programs simultaneously for comprehensive runtime security:</p>
<pre><code class="" data-line="">kprobe programs          LSM programs
(observation layer)      (enforcement layer)
       │                        │
       ↓                        ↓
Process executes              Kernel LSM hook fires
kernel function               BEFORE operation completes
       │                        │
       ↓                        ↓
Tetragon reads context:       Tetragon checks TracingPolicy:
  - process name                - selectors match?
  - PID, UID                    - action = Sigkill?
  - namespace, pod name         │
  - parent process              ↓
  - capabilities                SIGKILL sent from kernel context
       │                        Process terminated
       ↓                        Operation never completes
Tetragon exports event
  to userspace observer
</code></pre>
<p>The kprobe side provides the rich context (pod name, namespace, process tree) because it has access to Kubernetes metadata that Tetragon&#8217;s userspace component has pre-populated into maps. The LSM side provides the enforcement capability. Together, they give you context-aware kernel enforcement.</p>
<blockquote>
<p><strong><code class="" data-line="">SIGKILL</code> from kernel vs userspace kill</strong> — When a userspace process runs <code class="" data-line="">kill -9 &lt;pid&gt;</code>, it issues a kill syscall, the kernel schedules the signal delivery, and the target process dies on its next scheduler timeslice. There is a measurable delay — and more importantly, the target process may run for several more instructions before the signal is delivered. When a BPF LSM program returns a non-zero error code or calls <code class="" data-line="">bpf_send_signal(SIGKILL)</code> from within the hook, the signal is delivered synchronously within the kernel&#8217;s execution context. The process does not execute another instruction in the problematic syscall. This is not a speed difference — it is a structural difference in when the enforcement happens relative to the operation.</p>
</blockquote>
<hr />
<h2 id="writing-a-tetragon-tracingpolicy-for-enforcement">Writing a Tetragon TracingPolicy for Enforcement</h2>
<p>Tetragon policies are Kubernetes custom resources. Here&#8217;s a policy that prevents any container from executing shells:</p>
<pre><code class="" data-line="">apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: block-shell-exec
spec:
  kprobes:
    - call: &quot;security_bprm_check&quot;
      syscall: false
      args:
        - index: 0
          type: &quot;linux_binprm&quot;
      selectors:
        - matchBinaries:
            - operator: &quot;In&quot;
              values:
                - &quot;/bin/sh&quot;
                - &quot;/bin/bash&quot;
                - &quot;/bin/dash&quot;
                - &quot;/usr/bin/sh&quot;
                - &quot;/usr/bin/bash&quot;
          matchNamespaces:
            - namespace: Pid
              operator: &quot;NotIn&quot;
              values: [&quot;1&quot;]      # exclude host namespace (PID 1 = init)
          matchActions:
            - action: Sigkill
              argError: -1       # EPERM returned to the caller
</code></pre>
<p>Apply and verify:</p>
<pre><code class="" data-line="">kubectl apply -f block-shell-exec.yaml

# Confirm it&#039;s active
kubectl get tracingpolicies
# NAME               ENABLED   REASON   AGE
# block-shell-exec   true               5s

# Verify Tetragon loaded the eBPF program for this policy
bpftool prog list | grep bprm
# 94: lsm  name tetragon_lsm_bprm  tag 8f2a1c3e4d5b7a9f  gpl
#     loaded_at 2026-04-22T14:22:13+0530  uid 0
</code></pre>
<p>Test it (in a non-production namespace):</p>
<pre><code class="" data-line="">kubectl exec -it test-pod -- /bin/sh

# Expected output:
# OCI runtime exec failed: exec failed: unable to start container process:
# error during container init: error starting executable [&quot;/bin/sh&quot;]:
# container_linux.go: ... starting container process caused: process_linux.go:
# ... SIGKILL
</code></pre>
<p>The shell never started. The <code class="" data-line="">security_bprm_check</code> LSM hook fired, the Tetragon eBPF program evaluated the policy, returned <code class="" data-line="">SIGKILL</code> from kernel space. The exec system call returned <code class="" data-line="">-EPERM</code> to the container runtime. No shell process was created.</p>
<hr />
<h2 id="audit-mode-before-enforce-mode">Audit Mode Before Enforce Mode</h2>
<p>Running a new LSM policy in enforce mode without prior testing will kill legitimate workloads. Tetragon supports audit mode for every policy:</p>
<pre><code class="" data-line="">          matchActions:
            - action: Post     # audit mode: log event, do NOT kill
</code></pre>
<p><code class="" data-line="">Post</code> emits a Tetragon event that you can observe:</p>
<pre><code class="" data-line=""># Watch audit events for the policy (before switching to Sigkill)
kubectl exec -n kube-system -it \
  $(kubectl get pod -n kube-system -l app.kubernetes.io/name=tetragon -o name | head -1) \
  -- tetra getevents --event-types PROCESS_KPROBE | grep bprm
</code></pre>
<p>Sample audit event:</p>
<pre><code class="" data-line="">{
  &quot;process_kprobe&quot;: {
    &quot;process&quot;: {
      &quot;pod&quot;: {&quot;name&quot;: &quot;my-app-6d4f9-xk2p1&quot;, &quot;namespace&quot;: &quot;production&quot;},
      &quot;binary&quot;: &quot;/bin/sh&quot;,
      &quot;pid&quot;: 18293
    },
    &quot;function_name&quot;: &quot;security_bprm_check&quot;,
    &quot;action&quot;: &quot;KPROBE_ACTION_POST&quot;
  }
}
</code></pre>
<p>If <code class="" data-line="">my-app</code> legitimately needs <code class="" data-line="">/bin/sh</code> for its health check script, you&#8217;ll see it here before you kill it. Refine the selector (add <code class="" data-line="">matchLabels</code> to exclude that specific deployment, or add the binary to an allowlist) and then switch to <code class="" data-line="">Sigkill</code>.</p>
<hr />
<h2 id="production-gotchas"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Production Gotchas</h2>
<p><strong>Enforce mode kills anything the selector matches — including health checks and init containers.</strong> Most production containers have some shell usage: liveness probes that run <code class="" data-line="">sh -c</code>, init containers that <code class="" data-line="">chmod</code> files, entrypoint wrappers. Run in <code class="" data-line="">Post</code> (audit) mode for at least 48 hours across a representative workload set before switching to <code class="" data-line="">Sigkill</code>. Track all matched events and understand every process in the trace before enforcing.</p>
<p><strong>LSM hooks fire in kernel context — eBPF program complexity is limited.</strong> The verifier enforces strict limits on LSM programs because they run synchronously in the kernel&#8217;s hot path. Policies with many conditions or complex map lookups may be rejected by the verifier. Tetragon&#8217;s policy engine compiles your TracingPolicy into eBPF that stays within verifier limits, but very complex <code class="" data-line="">matchArgs</code> chains with many values can hit limits. Test with <code class="" data-line="">kubectl apply</code> and check Tetragon pod logs for verifier rejection messages.</p>
<p><strong><code class="" data-line="">BPF_PROG_TYPE_LSM</code> requires kernel 5.7+ and BPF LSM enabled.</strong> Check <code class="" data-line="">/sys/kernel/security/lsm</code> for <code class="" data-line="">bpf</code> in the list. EKS nodes running Amazon Linux 2 with kernel 5.10+ have BPF LSM available. GKE nodes with kernel 5.10+ on Container-Optimized OS have it enabled. Ubuntu 22.04 (kernel 5.15) has it enabled by default. Ubuntu 20.04 kernels before 5.7 do not — check your actual kernel version.</p>
<p><strong>Policy scope: Tetragon TracingPolicies are cluster-wide by default.</strong> A policy without a <code class="" data-line="">matchNamespaces</code> or <code class="" data-line="">matchLabels</code> selector applies to every pod on every node. Start with namespace-scoped policies during testing. Use <code class="" data-line="">namespaced</code> TracingPolicy resources (Tetragon 0.10+) to limit scope to a specific namespace.</p>
<p><strong><code class="" data-line="">bpf_send_signal(SIGKILL)</code> vs returning an error code.</strong> Tetragon&#8217;s <code class="" data-line="">Sigkill</code> action uses <code class="" data-line="">bpf_send_signal()</code> rather than returning a negative error from the LSM hook. This means the syscall may return before the signal is delivered — there can be a single instruction window. For critical enforcement paths, combining LSM deny (return <code class="" data-line="">-EPERM</code>) with <code class="" data-line="">bpf_send_signal(SIGKILL)</code> is the belt-and-suspenders approach; Tetragon&#8217;s maintainers have documented which actions use which mechanism.</p>
<hr />
<h2 id="quick-reference">Quick Reference</h2>
<table>
<thead>
<tr>
<th>What you want</th>
<th>Command</th>
</tr>
</thead>
<tbody>
<tr>
<td>Is BPF LSM enabled?</td>
<td><code class="" data-line="">cat /sys/kernel/security/lsm</code> (look for <code class="" data-line="">bpf</code>)</td>
</tr>
<tr>
<td>What LSM programs are loaded?</td>
<td><code class="" data-line="">bpftool prog list | grep lsm</code></td>
</tr>
<tr>
<td>What Tetragon policies exist?</td>
<td><code class="" data-line="">kubectl get tracingpolicies -A</code></td>
</tr>
<tr>
<td>Audit events (before enforce)</td>
<td><code class="" data-line="">tetra getevents --event-types PROCESS_KPROBE</code></td>
</tr>
<tr>
<td>Watch Tetragon enforcement</td>
<td><code class="" data-line="">kubectl logs -n kube-system -l app.kubernetes.io/name=tetragon -f</code></td>
</tr>
<tr>
<td>Test a policy safely</td>
<td>Set <code class="" data-line="">action: Post</code> before <code class="" data-line="">action: Sigkill</code></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Tetragon action</th>
<th>Effect</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="" data-line="">Post</code></td>
<td>Log event only — audit mode</td>
</tr>
<tr>
<td><code class="" data-line="">Sigkill</code></td>
<td>Send SIGKILL from kernel context</td>
</tr>
<tr>
<td><code class="" data-line="">Override</code></td>
<td>Return custom error code to syscall caller</td>
</tr>
<tr>
<td><code class="" data-line="">FollowFD</code></td>
<td>Track file descriptor for future hook correlation</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>LSM hook</th>
<th>Protects</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="" data-line="">security_bprm_check</code></td>
<td>exec (block shell spawning)</td>
</tr>
<tr>
<td><code class="" data-line="">security_inode_permission</code></td>
<td>file access (block reads/writes to sensitive paths)</td>
</tr>
<tr>
<td><code class="" data-line="">security_socket_connect</code></td>
<td>outbound connections (block C2 connections)</td>
</tr>
<tr>
<td><code class="" data-line="">security_capable</code></td>
<td>capability escalation (block CAP_SYS_ADMIN attempts)</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="key-takeaways">Key Takeaways</h2>
<ul>
<li>LSM eBPF Tetragon enforces at the syscall boundary — the operation either never completes or returns an error before the kernel performs the action, with no detect-and-respond window</li>
<li>Falco, Datadog, and sidecar-based tools detect events after the syscall returns; this is architectural, not a product limitation — they operate at a layer where the operation has already occurred</li>
<li><code class="" data-line="">BPF_PROG_TYPE_LSM</code> attaches eBPF programs directly to Linux Security Module hooks; available on kernel 5.7+, enabled on all current EKS/GKE LTS node images</li>
<li>Tetragon sends <code class="" data-line="">SIGKILL</code> from kernel context using <code class="" data-line="">bpf_send_signal()</code> — not from a userspace agent polling an audit log</li>
<li>Always run Tetragon policies in <code class="" data-line="">Post</code> (audit) mode for 48+ hours before switching to <code class="" data-line="">Sigkill</code> — legitimate workloads trigger many of the same LSM hooks that attacks use</li>
<li>The combination of kprobe (rich context: pod name, namespace, process tree) and LSM (enforcement) gives Tetragon context-aware kernel enforcement that static profiles (AppArmor, seccomp) cannot provide dynamically</li>
</ul>
<hr />
<h2 id="whats-next">What&#8217;s Next</h2>
<p>LSM hooks prevent operations in the moment. But after an incident — when enforcement failed, or when you&#8217;re doing post-hoc forensics — the question changes: what did this process spawn, what files did it touch, what connections did it make, and in what order? Answering that from logs alone is guesswork. Answering it from kernel-level process lineage is reconstruction.</p>
<p>EP13 covers how eBPF kprobe hooks on <code class="" data-line="">fork</code> and <code class="" data-line="">exec</code> build a complete, tamper-resistant process tree. Even after the attacker&#8217;s process has exited, the record remains — in kernel maps, exported to a persistent store, tied to the pod that ran it.</p>
<p><em>Next: <a href="/process-lineage-ebpf/">process lineage with eBPF — reconstructing what happened after the fact</a></em></p>
<p>Get EP13 in your inbox when it publishes → <a href="https://linuxcent.com/subscribe">linuxcent.com/subscribe</a></p>
<p><a class="a2a_button_mastodon" href="https://www.addtoany.com/add_to/mastodon?linkurl=https%3A%2F%2Flinuxcent.com%2Febpf-lsm-tetragon-runtime-security%2F&amp;linkname=LSM%20and%20Tetragon%20%E2%80%94%20When%20the%20Kernel%20Says%20No" title="Mastodon" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_email" href="https://www.addtoany.com/add_to/email?linkurl=https%3A%2F%2Flinuxcent.com%2Febpf-lsm-tetragon-runtime-security%2F&amp;linkname=LSM%20and%20Tetragon%20%E2%80%94%20When%20the%20Kernel%20Says%20No" title="Email" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_whatsapp" href="https://www.addtoany.com/add_to/whatsapp?linkurl=https%3A%2F%2Flinuxcent.com%2Febpf-lsm-tetragon-runtime-security%2F&amp;linkname=LSM%20and%20Tetragon%20%E2%80%94%20When%20the%20Kernel%20Says%20No" title="WhatsApp" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_reddit" href="https://www.addtoany.com/add_to/reddit?linkurl=https%3A%2F%2Flinuxcent.com%2Febpf-lsm-tetragon-runtime-security%2F&amp;linkname=LSM%20and%20Tetragon%20%E2%80%94%20When%20the%20Kernel%20Says%20No" title="Reddit" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Flinuxcent.com%2Febpf-lsm-tetragon-runtime-security%2F&amp;linkname=LSM%20and%20Tetragon%20%E2%80%94%20When%20the%20Kernel%20Says%20No" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_linkedin" href="https://www.addtoany.com/add_to/linkedin?linkurl=https%3A%2F%2Flinuxcent.com%2Febpf-lsm-tetragon-runtime-security%2F&amp;linkname=LSM%20and%20Tetragon%20%E2%80%94%20When%20the%20Kernel%20Says%20No" title="LinkedIn" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_copy_link" href="https://www.addtoany.com/add_to/copy_link?linkurl=https%3A%2F%2Flinuxcent.com%2Febpf-lsm-tetragon-runtime-security%2F&amp;linkname=LSM%20and%20Tetragon%20%E2%80%94%20When%20the%20Kernel%20Says%20No" title="Copy Link" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Flinuxcent.com%2Febpf-lsm-tetragon-runtime-security%2F&#038;title=LSM%20and%20Tetragon%20%E2%80%94%20When%20the%20Kernel%20Says%20No" data-a2a-url="https://linuxcent.com/ebpf-lsm-tetragon-runtime-security/" data-a2a-title="LSM and Tetragon — When the Kernel Says No"></a></p><p>The post <a href="https://linuxcent.com/ebpf-lsm-tetragon-runtime-security/">LSM and Tetragon — When the Kernel Says No</a> appeared first on <a href="https://linuxcent.com">Linuxcent</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxcent.com/ebpf-lsm-tetragon-runtime-security/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1841</post-id>	</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 

Served from: linuxcent.com @ 2026-07-03 01:21:21 by W3 Total Cache
-->