Table of contents
Getting started
- Not sure what Kernloom does yet? Read Core Concepts first.
- Not sure if Kernloom fits your environment? Try the Exposure Assessment
Requirements
- Linux with root access
- Kernel 5.10 LTS or newer (BPF ring buffer + stable XDP support)
- On Synology NAS: requires a newer nk-platform (DSM 7.2+ on supported models)
Kernels below 5.10 may lack BPF ring buffer support and have unstable XDP behaviour. 5.10 LTS is the minimum tested baseline.
1) Install
curl -fsSL https://linkl.it/kernloom | sudo sh
To install a specific version:
curl -fsSL https://linkl.it/kernloom | sudo KERNLOOM_VERSION=v0.2.3 sh
The installer uses two separate trees — one for attested binaries, one for mutable runtime state:
| Path | What it is |
|---|---|
/opt/kernloom/attested/klshield | Shield CLI (IMA-attested) |
/opt/kernloom/attested/kliq | IQ CLI (IMA-attested) |
/opt/kernloom/attested/bpf/xdp_kernloom_shield.bpf.o | XDP kernel object |
/opt/kernloom/attested/etc/whitelist.txt | Permanent exemptions |
/opt/kernloom/attested/etc/pdp/ | PDPConfig profiles |
/var/lib/kernloom/iq/state.json | Autotune state (runtime) |
/var/lib/kernloom/iq/feedback.json | Temporary exemptions (runtime) |
/var/lib/kernloom/iq/kliq.db | Graph + baseline database (runtime) |
Files under
/opt/kernloom/attested/are part of the IMA-measured tree and can be attested by Keylime. Files under/var/lib/kernloom/iq/change every tick and are intentionally outside the attested tree.
2) Ensure bpffs is mounted
mount | grep -q "/sys/fs/bpf" || sudo mount -t bpf bpf /sys/fs/bpf
On most modern Linux distributions this is already mounted automatically.
3) Attach Shield to your interface
Replace eth0 with your actual interface (ip link to list them):
sudo klshield attach-xdp \
--iface eth0 \
--obj /opt/kernloom/attested/bpf/xdp_kernloom_shield.bpf.o
Verify counters are moving:
sudo klshield stats
sudo klshield top-src -n 20 -by pkts
4) Choose your rollout path
Two paths depending on whether you want Graph Learning from day one.
Path A — Progressive enforcement only
For public-facing and internal nodes.
Choose the PDPConfig that matches your node type. Bootstrap profiles start with blocking disabled and high thresholds — safer for the first learning period:
# Copy the right PDPConfig for your node (see /kernloom-iq/ for full list)
sudo cp /opt/kernloom/attested/etc/pdp/ziti-controller-bootstrap.yaml \
/opt/kernloom/attested/etc/pdp/node.yaml
# Bootstrap: 14-day dry-run, learn whitelist as you go
sudo /opt/kernloom/attested/kliq \
--pdp-config=/opt/kernloom/attested/etc/pdp/node.yaml \
--dry-run=true \
--whitelist-learn=true
--profile still works as a shorthand, but --pdp-config is recommended — it gives you the full autotune bootstrap schedule and is Forge-compatible.
Watch STATE ... transitions. When dry-run output looks reasonable, enable enforcement:
sudo /opt/kernloom/attested/kliq \
--pdp-config=/opt/kernloom/attested/etc/pdp/node.yaml \
--dry-run=false \
--whitelist-learn=true
Check overall status and bootstrap phase at any time:
kliq status
Path B — Progressive enforcement + Graph Learning
For internal nodes only.
Important: Graph learning is only useful on internal nodes with a small, stable set of known clients (identity provider, database, internal API). On public-facing nodes the graph never converges because new internet client IPs appear constantly. Use Path A for public-facing nodes.
Start IQ with graph learning active:
sudo /opt/kernloom/attested/kliq \
--pdp-config=/opt/kernloom/attested/etc/pdp/idp-bootstrap.yaml \
--graph --graph-mode=learn \
--dry-run=true --whitelist-learn=true
This runs both systems simultaneously:
- Progressive enforcement observes and acts on anomalous behaviour
- Graph Learner silently records all service-to-service communication paths
No disruption from graph learning in learn mode — it is fully passive.
Check which subsystems are active:
kliq runtime status graph-learning
5) The bootstrap timeline
| When | What to do |
|---|---|
| Day 1 | Install, attach Shield, start IQ in dry-run + learn mode. Add whitelist entries for known-good monitoring, office NAT, trusted partners. |
| Day 2–3 | Review dry-run output. Check klshield top-src for unexpected top talkers. Enable enforcement if it looks clean: set --dry-run=false. |
| Day 7 | Autotune has completed phase 1 (48h) and most of phase 2 (5d). Thresholds are much more accurate now. Run kliq graph export to review learned paths. |
| Day 14 | Bootstrap is complete. Thresholds are stable. Ready to freeze the graph baseline. |
| After day 14 | Switch to --graph-mode=frozen-observe for a few more days to catch false positives, then switch to --graph-mode=frozen-enforce for strict Zero Trust. |
6) Freezing the graph baseline
Once you are satisfied with the learned graph (after ~7–14 days):
Step 1 — review:
kliq graph export # all edges
kliq graph export --sort=state # grouped by state
kliq graph edges --sort=state # overview with counts
kliq graph baselines --sort=obs # per-edge EWMA baselines and peaks
Step 2 — approve or deny specific IPs:
kliq graph approve-ip 203.0.113.7 # mark as trusted
kliq graph deny-ip 198.51.100.99 # explicitly block this path
Step 3 — check readiness before freezing:
kliq graph freeze --dry-run
Reports how many edges would be frozen, how many candidates are still immature, and whether it is safe to proceed. Does not write anything.
Step 4 — freeze:
kliq graph freeze
Step 5 — switch to frozen-observe (give it a few days):
# update your kliq command or systemd unit:
--graph-mode=frozen-observe
Watch for unexpected signals. If a legitimate source triggers violations, approve-ip it and add it to the whitelist.
Step 6 — full enforcement:
--graph-mode=frozen-enforce
From this point, any source attempting an unknown communication path is immediately blocked by IQ.
Step 7 — XDP allow-mode (optional, strongest posture):
Once frozen-enforce has run cleanly for several days, you can move the enforcement boundary from IQ down into the XDP layer itself. In allow-mode, Shield drops any tuple not in the frozen allow-list immediately at the kernel hook — before IQ even sees the packet. There is no race window.
klshield tuple-enforce allow
IQ populates the edge4_allow map from the frozen graph automatically when running in graph-enforce feature profile. Verify what is in the allow list:
klshield list-edge-allow
Only for internal nodes. Allow-mode requires a small, stable set of clients. On a public-facing node the allow map fills up instantly and the node becomes unreachable. See Architecture for the two-scenario model.
To undo:
klshield tuple-enforce off
7) Quick recovery
Temporary exemption — edit /var/lib/kernloom/iq/feedback.json, IQ reloads within 10 seconds:
[
{"target":"203.0.113.7","action":"forgive","ttl":"24h","notes":"known good"}
]
Or send SIGUSR1 for immediate reload:
sudo kill -SIGUSR1 $(pidof kliq)
Permanent exemption — add to /opt/kernloom/attested/etc/whitelist.txt:
203.0.113.7
203.0.113.0/24
Next steps
| Integration Patterns | Real-world deployment examples for your node type |
| IQ reference | Every flag, PDPConfig profiles, graph learner workflow |
| Shield reference | Tuple enforcement, allow/deny/rate-limit commands |
| Architecture | The PDP/PEP model, two-scenario model, full data flow |
| Operations | systemd, observability, troubleshooting |