Benchmark : Pavois vs OpenSCAP / Lynis (reproductible)
Un benchmark reproductible de Pavois face à OpenSCAP et Lynis sur une VM Debian 12 neuve. Tout ici est reconstruit depuis un snapshot propre ; rien n’est affirmé à la main. Les scripts sont dans le repo (tools/benchmark/effective-config-bench.sh, tools/coverage_gap.py).
En bref : sur le scénario drop-in SSH, Pavois FAIL (attrapé, mappé à une norme), OpenSCAP/SSG passe (faux négatif sondé sur fichier), Lynis avertit (il lit aussi sshd -T, mais en heuristique). L’edge est étroit et honnête : il porte sur la précédence drop-in / Include, pas sur les lectures runtime en général (pour sysctl, SSG lit aussi /proc/sys, donc les deux l’attrapent).
Méthode
Une VM Debian 12 neuve est provisionnée, les scanners + CINC sont installés une fois, un snapshot de base propre est pris, et chaque run restaure ce snapshot identique d’abord, donc l’état de départ ne dérive jamais.
tools/benchmark/effective-config-bench.sh <user@host> <clé> <ssg-debian12-ds.xml>met en place le scénario et lance les trois scanners.test-vms/bench.shest le wrapper lab (provision → snapshot → restore → run) ; non publié car il référence le lab local.
| Composant | Version |
|---|---|
| Pavois | CINC Auditor 7.1.7 |
| OpenSCAP | oscap 1.3.7 |
| SCAP Security Guide | ssg-debian12-ds.xml 0.1.81 (ComplianceAsCode) |
| SHA-256 du datastream SSG | ef4cb97e2566ced5146cbc6861259b79be69999759244e7fa4cbc7eafdbefbfc |
| Lynis | 3.0.8 (462 tests) |
| Cible | Debian 12, VM Incus neuve |
| Date du run | 2026-06 |
Scénario 1 : un drop-in sshd surcharge PermitRootLogin
Le /etc/ssh/sshd_config principal dit PermitRootLogin no ; un drop-in dans /etc/ssh/sshd_config.d/ dit yes (la valeur que sshd -T résout).
grep -iE '^\s*PermitRootLogin' /etc/ssh/sshd_config # -> PermitRootLogin no (ce qu’une sonde fichier lit)
sudo sshd -T | grep -i '^permitrootlogin' # -> permitrootlogin yes (la valeur effective)| Scanner | Lit | Résultat |
|---|---|---|
| Pavois | sshd -T |
FAIL, attrapé et mappé ssh-disable-root-login (CIS / BP-028 / STIG) |
| OpenSCAP 1.3.7 + SSG | OVAL sur le fichier | PASS, faux négatif : il lit le no du fichier principal et rate le drop-in |
| Lynis 3.0.8 | sshd -T |
avertit (suggestion SSH-7408), attrapé mais heuristique, non mappé |
Lynis résout le drop-in comme Pavois ; sa limite est d’être heuristique, pas cet angle mort. La règle d’OpenSCAP/SSG sondée sur le fichier le rate complètement. Pavois le résout et le mappe à chaque norme applicable qu'il porte.
Scénario 2 : sysctl runtime vs fichier (pas d’edge, gardé par honnêteté)
On a testé un second cas pour borner le claim : kernel.kptr_restrict = 2 sur disque (/etc/sysctl.d/) mais sysctl -w kernel.kptr_restrict=0 au runtime.
| Scanner | Résultat | Pourquoi |
|---|---|---|
| Pavois | FAIL | lit la valeur runtime |
| OpenSCAP + SSG | fail | l’OVAL sysctl du SSG lit aussi /proc/sys (le runtime) |
Ce n’est PAS un différenciateur Pavois : les deux l’attrapent. L’edge effective-config est donc spécifique à la précédence drop-in / Include (le cas SSH), pas aux lectures runtime en général. On le dit, plutôt que de maquiller une non-différence en victoire.
Coverage gap (auditable)
tools/coverage_gap.py mappe les contrôles Pavois aux règles SSG (via les tags ssg:) et trie le gap avec les verdicts d’oscap sur la cible réelle, donc les N/A ne le gonflent jamais.
- gap brut : 315 règles SSG que Pavois ne mappe pas
- trié : 87 applicables et en échec (le vrai backlog), 74 applicables et déjà conformes, 139 notapplicable sur Debian (ex. SELinux sous AppArmor), 15 non auto-vérifiées
- symétrique : Pavois s’applique à 523 de ses 607 contrôles Debian 12 sur un hôte frais (84 N/A)
Données complètes par règle, un backlog prêt à l’emploi (sévérité, verdict oscap, triage dérivé, et colonnes vides decision/reason/issue_url/owner/status) : coverage-gap-debian12.csv (315 lignes).
oscap xccdf eval --results gap-res.xml ssg-debian12-ds.xml # sur la cible, pour l’applicabilité
python3 tools/coverage_gap.py --os debian12 \
--datastream ssg-debian12-ds.xml --oscap-results gap-res.xml --format csv > coverage-gap-debian12.csvLes entrées high du gap sont surtout des cas d’arbitrage sur Debian (SELinux N/A sous AppArmor ; ntp/timesyncd alternatives de chrony), pas des contrôles clairement manquants. --create-issues verse le gap applicable-en-échec en backlog, et les contrôles cassés deviennent des issues bug.