Détection — voir, et prouver qu'on voit encore¶
Machine translation of the French original.
La prévention répond à « peut-on entrer ? ». La détection répond à la question Subsequently, the key date is the one when the first attempt failed: did anyone enter, and what did they do?
This page describes the park's detection mechanisms, the question that each person answers, and, most importantly, how we ensure that they continue to function – because a A malfunctioning detector does not produce an error message; it produces silence, and silence is exactly equivalent to "no signal."
The technical terms refer to the glossary.
One question, one engine¶
The danger of a set of security tools is to assume that they cover everything. Ten tools that answer the same question leave the other nine questions unanswered. Therefore, the system starts with questions and assigns a dedicated engine to each one.
| The Question | The Engine | Beyond the Question |
|---|---|---|
| Does this image contain a known CVE? | Trivy | What the container does once it's running |
| Does this code have a vulnerability, a dependency, or a secret? | Semgrep, Trivy (dependencies), trufflehog | The program's behavior at runtime |
| Is this host hardened, integrated, and up-to-date? | Wazuh — SCA, FIM, rootcheck, vulnerabilities | An abnormal behavior, in real-time |
| What is running autonomously on this machine? | osquery (within Wazuh), KnockKnock on macOS | — |
| Does this process do anything unusual? | Falco (eBPF) | Network traffic |
| What is traversing the network? | Suricata (IDS) | The content of an end-to-end encrypted stream |
| Is this file known malware? | ClamAV | Newly discovered malware |
| What is in this file, at all levels? | Strelka + YARA | What the file would do if executed |
| Who is attacking the perimeter? | CrowdSec + community blocking | Anything that is not HTTP |
| What happened on this machine? | Velociraptor — see Response | — |
The rightmost column is not an admission: it defines where each tool ends. It indicates where its response ends, and therefore where another begins.
The Authority
Trivy has authority over what is built and versioned. Wazuh has authority over the state of a live host. Falco, Suricata and Velociraptor have authority over behavior and flows. None of them duplicate the work of another; when two engines observe the same thing, it is filtered by rule identifier, never disabling either.
flowchart LR
classDef src fill:#3f3f46,stroke:#3f3f46,color:#fff
classDef det fill:#7c2d12,stroke:#7c2d12,color:#fff
classDef hub fill:#0f766e,stroke:#0f766e,color:#fff
subgraph sources["Ce qu'on observe"]
img["Images et dépôts"]:::src
host["Hôtes<br/>fichiers · configuration · paquets"]:::src
proc["Processus et conteneurs"]:::src
net["Trafic réseau"]:::src
file["Fichiers déposés"]:::src
logs["Journaux du proxy"]:::src
end
subgraph moteurs["Les moteurs"]
trivy["Trivy · Semgrep · trufflehog<br/>scanner de vulnérabilités"]:::det
wazuh["Wazuh<br/>SIEM · osquery · listes d'IOC"]:::det
falco["Falco<br/>appels système"]:::det
suri["Suricata<br/>signatures réseau"]:::det
av["ClamAV + Strelka<br/>verdict · analyse profonde"]:::det
cs["CrowdSec<br/>comportement HTTP"]:::det
end
tri["Tableau de triage<br/>score · exposition · journal"]:::hub
hub["Répartiteur d'alertes"]:::hub
img --> trivy --> tri
host --> wazuh
proc --> falco
net --> suri
file --> av --> wazuh
logs --> cs
wazuh -->|"identifiant de règle"| hub
falco -.->|"après mesure du bruit"| hub
suri -.->|"après mesure du bruit"| hub
cs -->|"403"| logs
Dashed arrows are not just a design detail: they mark engines that collect data before notifying. The reason is deeper, found in the principles.
The SIEM – Wazuh¶
A SIEM collects logs from the entire environment, correlates them, and alerts. Here, it's Wazuh: a manager and an agent on each machine – hypervisor, container hosts, GPU host, NAS, offsite server, and workstation. A host outside the LAN communicates with the manager via a private mesh, never using a local address that doesn't exist for it.
What the agents provide:
- File integrity on sensitive paths;
- Configuration assessment against CIS benchmarks;
- Rootkit and hidden file/port detection;
- Vulnerability identification through correlation between installed packages and CVE databases;
- Hardware, package, and process inventory.
osquery, within the SIEM and not alongside¶
osquery queries the state of a machine using SQL: services, scheduled tasks, authorized SSH keys, and anything that provides persistence. It is integrated as a module of Wazuh, not as a separate service: two inventories of the same environment will always diverge, and when they do, no one knows which one to trust. The results arrive in the same index as the rest, and a probe verifies that they actually arrive – an active module that sends nothing looks like an active module.
Threat intelligence, consumed¶
Three lists of IOCs – addresses, domains, and file hashes – are sourced from public sources and refreshed by a scheduled task. Wazuh consults them when an event occurs (CDB lists). The file hash list also draws on what the file system scanners have found: a file detected once is recognized everywhere afterward.
A threat intelligence sharing platform (of the type MISP) was ruled out: it is justified when you produce intelligence, not when you consume three lists. A probe monitors the freshness of the lists – an IOC list that has stopped being updated produces no errors, only missed detections.
Two Alerting Stages¶
- Naming rules, one for each detection that you want to receive (a malware found, a canary that no longer responds, a container killed due to lack of memory), each linked to its identifier.
- A general threshold, for everything that the naming rules do not cover. It is only armed after a period of measurement of the volume it would produce on a healthy system.
Execution – Falco¶
The SIEM sees the state of a host; it does not see what a program is doing. Without telemetry of system calls, an attacker already present in a container is only visible by what it breaks.
Falco fills this gap on hosts that run containers. The deployment choices, each with its own reason:
| Choice | Why |
|---|---|
| Modern eBPF probe, no kernel module | Nothing to compile, nothing that breaks on the next kernel update |
| System package, started before the container engine | The first container launched is already being observed |
| Automatic rule updates from the internet disabled | Rules are changed through a repository, read, and never silently |
| CPU and memory limits | A security tool should not be able to compromise the host it protects |
| Buffer sized for zero burst loss | An event lost during a peak is precisely the one we were looking for |
In addition to the project's stable rules, there are also custom rules, written for the actions of an attacker on this specific system: writing to a scheduled task or SSH keys, launching a container that mounts the container engine socket without appearing on the list of authorized users, or elevating privileges within a container.
The false positives – the health probes of the databases, which alone generate tens of thousands of events per day – are processed using named exceptions, one for each case, never by disabling a rule.
A rule can load without error and never match
A version upgrade can change the meaning of a field that a rule uses. The rule loads, no errors appear during startup, and it will never trigger again. Reloading the configuration sees nothing wrong: it is correct for the previous version.
This is why the sensor: a probe launches a disposable container, opens a shell within it, and reads a sensitive file, then verifies that both actions have been observed on each host. Its reverse verification involved disabling a rule and observing the probe turn red.
The Network – Suricata¶
Suricata applies signatures of known attacks to The traffic that passes in front of it. Its output, in JSON, goes to the newspaper search engine.
An IDS only sees what passes in front of it: its location is therefore the real decision. A home mesh network does not offer a mirror port to listen on; the relevant point is where the traffic converges – a virtual network bridge can see both the communication between machines and their output to the Internet, without any additional equipment.
Like Falco, he collects before notifying, and his evidence is a test signature triggered intentionally from a machine, which is then found in the alerts.
The files – two engines, two questions¶
The architecture of the antivirus chain – a central engine, a signature mirror, and the client that logs – is described in the architecture note. Here, the question is about evidence.
- ClamAV answers "Is this a known malware?". The file-sharing service refuses to accept a file that has been detected.
- Strelka answers "What's inside it, at all levels?". It recursively unpacks archives, documents, and embedded objects, and runs dozens of scanners on each piece, including thousands of public YARA rules. It analyzes a selection of paths chosen each night.
The worst failure mode in the park – and why a counter doesn't catch it
YARA compiles its rule set into a single block. A single invalid rule causes the entire game to fail: the container remains healthy, analyses continue, and nothing is detected.
A counter of loaded rules seems sufficient. But it's not: it simply indicates how many rules are in memory, not whether they are still recognizing something. The canary rule is a home-grown rule, placed in the same directory as the others, and re-introduced with each refresh, along with a file designed to trigger it. A probe submits this file and demands detection. If the game no longer compiles, the canary fails along with it – this is exactly what we want.
Reverse verification: a deliberately broken rule file triggers a critical alert, followed by a return to normal.
For ClamAV, the canary is the file EICAR, submitted daily.
A reverse verification should break what it claims to test
To test the EICAR canary, the first idea is to ignore the test signature. It doesn't cause any failure: the engine recognizes the same file under a second signature, which takes over, and the canary remains green. A reverse verification that doesn't cause the canary to fail doesn't prove that the canary is working – it only proves that we haven't been able to make it fail.
What has been ruled out, and why.
- A dynamic sandbox: The file volume doesn't justify it, and it would add a heavy machine, exposed to hostile code. The question will resurface when a real sample passes both engines.
- A third YARA rule engine: It would read the same public rule set. Having a second tool that reads the same rules is not a second opinion.
The Perimeter — CrowdSec¶
CrowdSec reads the logs from the internal proxy, recognizes hostile behavior (scanning, brute-force, known exploits), and enforces its decision through a module integrated into the proxy, which responds with a 403. It also uses a community-shared block list, populated by all installations that share it.
Why in the application layer rather than a firewall: see the architectural note. Its verification ensures that the module actually applies a decision, not just that it is loaded.
Vulnerabilities — the scanner and its axes¶
A home-built vulnerability scanner aggregates multiple tools and, most importantly, sorts:
| Axis | Tool | What it provides |
|---|---|---|
| Images in service, on each container host | Trivy | Known CVEs, updated daily |
| Code repositories | Trivy (dependencies, IaC) + Semgrep (SAST) | Vulnerabilities and dependencies before deployment |
| Secrets remaining on hosts | trufflehog | Severity determined by the file's permissions: a secret readable by everyone is more serious than the same secret restricted to its service |
| Actionability | Comparison with upstream image | Does a fix already exist? |
| Exposure | Proxy configuration | Public, behind the identity provider, or internal |
| Exploitation | EPSS + KEV | Likely, or already observed elsewhere |
The scoring system crosses severity, exploitation, and exposure: a critical CVE on an internal service comes after a medium CVE, already exploited, on a public service. Each triage decision is recorded with its author.
OpenCVE complements this for anything that isn't a container image – the hypervisor system, the NAS system: it cross-references published CVEs with the versioned inventory of the system's components.
Two additions:
- An SBOM for each image in service, regenerated weekly. When a new vulnerability is published, the question "Are we affected?" can be answered by checking the inventory, rather than re-running a scan.
- The time to fix is itself a control. Scanning without measuring the time to fix produces a list that grows. See Compliance.
Hardening, and a second opinion¶
The SIEM configuration assessment runs continuously. A second tool (Lynis) was run occasionally, for comparison. Where the two disagreed – one module declaring a containment module inactive, the other active – the issue was resolved by a functional test: attempting the action that the module should prevent, and confirming the failure. The automated checks were incorrect.
Rootkit detection tools were not added: they duplicate what the SIEM module already does, and on containerized hosts, they generate noise that would overwhelm the rest.
What these choices have in common¶
1. Functional tests, not just counters. "The service is running," "5,000 rules loaded," "the agent is connected": these are counters, and a detector can satisfy them all without detecting anything. A functional test injects a known case and demands that it be seen. Each engine on this page has one.
2. Measure the noise before triggering an alert. A new detector first runs in collection-only mode, with a pre-set alert threshold. An alert triggered without prior measurement measures the instrument's rate, not the state of the environment – and an alert that fires every hour from day one would be filtered out before the end of the week.
3. Filter by rule ID, never by group. A group bundles together similar rules that haven't been read. A filter by group creates duplicates; an automated response by group would act on detections that we have never chosen.
4. Exceptions have names. A false positive is handled by a specific exception, tied to its case. Disabling a rule in bulk also disables all the true detections it would have made.
5. One engine per question. Adding a tool is justified by a question without an answer, not by the tool's reputation.
Next to read¶
- Answer — what happens once detection has been made.
- Compliance and evidence — how witnesses become evidence.
- Glossary.
Dernière vérification de cette page : 2026-09-11