De la source au verdict, puis à la preuve
Installez le binaire vérifié, lancez votre premier scan A à E, puis durcissez une cible et re-scannez. Du téléchargement au verdict en quelques commandes, sans chaîne d’outils à installer.
En bref : de zéro au verdict
Le chemin le plus court, sur l’hôte courant (la config effective exige root). Trois choses, dans cet ordre : le binaire, le moteur de scan, le scan. Rien à compiler, le binaire embarque son corpus de règles.
# 1. le binaire, vérifié
BASE=https://github.com/stephrobert/pavois/releases/download/v0.1.1
curl -fsSLO $BASE/pavois-linux-amd64 && curl -fsSLO $BASE/checksums.txt
sha256sum --ignore-missing --check checksums.txt # intégrité
sudo install -m 0755 pavois-linux-amd64 /usr/local/bin/pavois
pavois doctor # corpus embarqué, prêt à scanner
# 2. le moteur : Pavois exécute ses contrôles avec CINC Auditor
META="https://omnitruck.cinc.sh/stable/cinc-auditor/metadata?p=el&pv=9&m=x86_64"
URL=$(curl -sS "$META" | awk '/^url/{print $2}') # le paquet de cette plateforme
SUM=$(curl -sS "$META" | awk '/^sha256/{print $2}') # et son empreinte publiée
curl -fsSLO "$URL"
echo "$SUM ${URL##*/}" | sha256sum --check # intégrité, avant toute exécution
sudo dnf install -y "./${URL##*/}" # Debian/Ubuntu : sudo apt install ./<fichier>
pavois doctor # moteur CINC (natif) : /usr/bin/cinc-auditor
# 3. le scan
pavois scan local --sudo --format html # audite cet hôte, note A à E
pavois serve # http://localhost:8098L’étape 2 n’est pas facultative et aucun gestionnaire de paquets ne peut la faire à votre place : CINC Auditor n’est dans aucun dépôt de distribution, donc même les paquets .deb et .rpm de Pavois ne peuvent pas le déclarer en dépendance. Sans lui, le premier scan s’arrête sur no native CINC engine found, ce qui se lit comme une dépendance manquante alors que rien ne manque au paquet. Le détail, les autres plateformes et le repli Docker : le moteur de scan.
Télécharger un fichier puis vérifier son empreinte n’est pas tuber un script dans un shell. Pavois ne vous demandera jamais de faire curl | sh : un outil de durcissement qui commence par là a déjà perdu le débat. Ici rien ne s’exécute avant que sha256sum n’ait confirmé l’empreinte publiée, et la page installation ajoute la vérification de provenance SLSA, qui prouve en plus QUI a construit le fichier. Paquets .deb et .rpm au même endroit.
Prérequis
Pour installer Pavois : curl, et rien d’autre. Le binaire est statique et embarque son corpus de règles, donc il n’y a ni chaîne d’outils, ni Go, ni Python à mettre en place. mise n’intervient que si vous modifiez Pavois, et c’est décrit en fin de page.
Pour scanner, il faut en plus le moteur, et c’est le seul prérequis que rien n’installe à votre place. Pavois exécute ses contrôles avec CINC Auditor (le build open-source de Chef InSpec), qui n’est dans aucun dépôt de distribution : aucun gestionnaire de paquets ne peut aller le chercher, et Pavois ne l’installe jamais de lui-même. La commande est à l’étape 1 ci-dessous. Sans lui, les cibles distantes se rabattent sur un conteneur Docker et local refuse (un conteneur ne peut pas auditer son hôte). Sur une cible distante, --on-target n’installe le moteur que si vous passez --bootstrap-cinc. Enfin, la lecture de la config effective d’un service exige root, donc sudo, et une cible distante exige une clé SSH.
1. Installer Pavois et son moteur de scan
Chaque release publie un binaire statique par plateforme (Linux et macOS, amd64 et arm64), des paquets .deb et .rpm, un checksums.txt, un SBOM et une attestation de provenance SLSA. Le binaire est autoporté : le corpus de règles est dedans, il n’y a rien à générer.
BASE=https://github.com/stephrobert/pavois/releases/download/v0.1.1
curl -fsSLO $BASE/pavois-linux-amd64 && curl -fsSLO $BASE/checksums.txt
sha256sum --ignore-missing --check checksums.txt # intégrité
sudo install -m 0755 pavois-linux-amd64 /usr/local/bin/pavois
pavois doctor # corpus embarqué, prêt à scannersha256sum confirme l’intégrité face aux empreintes publiées. Il ne dit pas QUI a construit le fichier : quelqu’un qui remplace le binaire ET le checksums.txt produit un couple parfaitement cohérent. Pour répondre à cette question il faut l’attestation de provenance SLSA, et c’est la seule chose que GitHub CLI apporte de plus ici, sur un binaire déjà téléchargé :
gh attestation verify pavois-linux-amd64 --repo stephrobert/pavois # qui l’a construitFacultatif mais recommandé. Cette vérification interroge un journal de transparence public, donc elle ne demande aucun accès au dépôt. Les paquets .deb et .rpm, les autres plateformes et le dépannage : page installation.
Puis le moteur de scan
Le binaire seul sait lire un rapport archivé, pas auditer une machine. Pour ça il lui faut CINC Auditor, et c’est à vous de l’installer : il n’est dans aucun dépôt de distribution, donc aucun gestionnaire de paquets ne peut le tirer, et les paquets .deb et .rpm de Pavois ne peuvent pas le déclarer en dépendance. Le point d’entrée metadata d’omnitruck publie l’URL du paquet et son empreinte, donc on télécharge, on vérifie, on installe avec le gestionnaire du système :
META="https://omnitruck.cinc.sh/stable/cinc-auditor/metadata?p=el&pv=9&m=x86_64"
URL=$(curl -sS "$META" | awk '/^url/{print $2}') # le paquet de cette plateforme
SUM=$(curl -sS "$META" | awk '/^sha256/{print $2}') # et son empreinte publiée
curl -fsSLO "$URL"
echo "$SUM ${URL##*/}" | sha256sum --check # intégrité, avant toute exécution
sudo dnf install -y "./${URL##*/}" # Debian/Ubuntu : sudo apt install ./<fichier>
pavois doctor # moteur CINC (natif) : /usr/bin/cinc-auditorLes clés p et pv sont celles d’omnitruck : el/8, el/9, debian/12, debian/13, ubuntu/22.04, ubuntu/24.04 ; AlmaLinux et Rocky se déclarent en el. La documentation amont propose aussi un script tubé dans un shell root, que ce site ne vous demandera pas. Le repli Docker et les cas particuliers : le moteur de scan.
doctor confirme que tout est prêt et donne la commande exacte pour chaque manque :
# tout est prêt
[OK ] CINC engine (native) /usr/bin/cinc-auditor
[OK ] sudo /usr/bin/sudo
[OK ] ssh /usr/bin/ssh
[OK ] rule corpus embedded, 5928 controls across 9 OS profile(s)
[OK ] local OS detected debian 12
ready: try: pavois scan local --sudo
# exemples de manques signalés (avec la correction)
[FAIL] CINC engine no scan engine: install cinc-auditor (https://pavois.dev/en/installation/#engine) or docker
[WARN] sudo not found; effective-config reads need root, pass --sudo2. Premier scan (note A à E)
Le plus simple : auditer l’hôte courant avec sudo (la config effective exige root) :
pavois scan local --sudoPour une cible distante via SSH :
pavois scan user@host --key ~/.ssh/id_ed25519 --sudoLe drapeau --key n’est pas facultatif, même si ssh user@host fonctionne. Pavois passe par le transport SSH du moteur, qui ne lit pas ~/.ssh/config et ne retombe pas sur ~/.ssh/id_ed25519 comme le fait la commande ssh. Sans lui, la commande s’arrête sur « could not reach or identify user@host », alors que vous vous connectez à la main une seconde plus tard. Indiquez --key <chemin>, ou ajoutez la clé à ssh-agent.
Le profil (OS) est auto-détecté ; --profile ne sert que pour un profil custom.
# (profil personnalisé, optionnel)
# pavois scan user@host --key ~/.ssh/id_ed25519 --sudo --profile profiles/linux/debian12La sortie liste les écarts par sévérité et affiche la note A à E en grosse lettre, plus le chemin du rapport HTML. Pour servir les rapports : pavois serve (http://localhost:8098).
Voir un rapport d’exemple (scan réel) + campagne avant/après →
3. Durcir, puis prouver
Planifiez les correctifs, activez ceux que vous voulez, convergez un run Chef natif, et re-scannez :
pavois harden plan user@host --key ~/.ssh/id_ed25519 --sudo
# éditez le plan : passez des règles à apply: true
pavois harden apply hardening-plan-debian12.yml --scanAjoutez --reboot pour redémarrer la cible et re-scanner après le boot : un PASS y est alors reboot-proven. Voir le verdict qualifié.
4. Converger (un apply ne suffit pas)
Un plan est un instantané de l’état AVANT durcissement, or le durcissement change cet état. Pavois installe les paquets qu’un contrôle exige pour avoir un sens, et un paquet apporte ses propres fichiers : installer at crée /etc/at.deny, qu’un autre contrôle exige absent. Il était absent quand le plan a été écrit : rien ne l’a supprimé. Un apply en une passe ne peut donc pas fermer les trous qu’il crée lui-même.
Mesuré sur une Debian 12 neuve : la première passe arme 211 écarts, la seconde en arme 37, dont 10 qui n’existaient que parce que la première avait installé le logiciel qu’ils auditent. postfix arrive en dépendance et apporte un bandeau qui nomme la distribution ; sssd livre un profil AppArmor en mode complain ; installer at crée /etc/at.deny. Aucun de ces écarts n’était visible au moment du premier plan, pour la bonne raison qu’aucun n’existait encore.
La boucle : re-scanner, re-planifier, ré-appliquer, jusqu’à ce qu’une passe n’ait plus rien à faire.
# jusqu’au point fixe (2 à 3 passes en pratique)
pavois scan user@host --key ~/.ssh/id_ed25519 --sudo
pavois harden plan user@host --key ~/.ssh/id_ed25519 --sudo --from reports/<last>.json
pavois harden apply --target user@host --key ~/.ssh/id_ed25519 --sudo-prompt plan.ymlAttention aux contrôles qui se contredisent : un paquet installé par l’un peut être retiré par l’autre. Corrigez la paire avant de boucler, sinon la boucle oscille.
5. Ce qu’un apply ne peut pas fermer
Chaque règle porte une classe de remédiation. Trois d’entre elles ne se règlent pas par un apply :
- install-time : un système de fichiers séparé (/var, /var/log, /tmp) se décide à l’installation. Pavois livre une recette de partitionnement LVM, pas un tour de passe-passe.
- kernel-build : une option KSPP absente du noyau de la distribution exige un noyau recompilé. Pavois livre la recette de build.
- dangerous : un mot de passe GRUB, un pare-feu en deny par défaut, kernel.modules_disabled. Ces règles peuvent vous verrouiller dehors : elles exigent un acquittement explicite dans le plan et ne s’appliquent jamais toutes seules.
C’est pourquoi le rapport affiche DEUX notes : la note brute, et la posture remédiable (ce que pavois peut atteindre par lui-même, hors install-time et kernel-build). Sur une debian 12 sortie d’une image cloud, la campagne complète (noyau KSPP, partitions LVM, apply convergé) donne note B et remédiable A, mesurés le 13 juillet 2026 sur une VM neuve. Un lynis lancé ensuite sur la même machine affiche un indice de durcissement de 89 : c’est un contrôle croisé par un outil indépendant, pas un verdict de conformité (lynis n’en produit pas).
6. Prouver que l’hôte a survécu
Une machine durcie qui a perdu une fonction vitale est un échec, pas une note. Après un apply, vérifiez que le pare-feu tourne, que sshd répond, que le gestionnaire de paquets est sain et que la machine journalise encore. Un hôte peut afficher 560 contrôles au vert et n’écrire plus une ligne dans /var/log/syslog.
# redémarrage puis re-scan : un PASS après reboot est reboot-proven
pavois harden apply --target user@host --key ~/.ssh/id_ed25519 --sudo-prompt --reboot --scan plan.yml
# validation comportementale : tenter l’action interdite
pavois verify user@host --key ~/.ssh/id_ed25519pavois verify ne lit pas la configuration : il tente les actions interdites et regarde ce qui se passe. Huit sondes, dont la connexion root en SSH (qui doit être refusée), l’absence de clients en clair, et quatre sondes qui déclenchent un vrai événement (un chmod, une suppression, une lecture refusée de /etc/shadow) puis vérifient qu’auditd l’a effectivement ENREGISTRÉ. C’est la seule preuve qui ne dépend d’aucune interprétation.
7. En CI
Le code de sortie porte le verdict, et le format de sortie s’adapte à votre outillage :
# échoue la CI sous 80/100 ; SARIF pour GitHub code scanning
pavois scan user@host --key ~/.ssh/id --sudo --fail-under 80 --format sarif --out ./out
# un paquet de preuve horodaté, avec manifeste et empreintes
pavois bundle before.json after.json --plan plan.yml --out evidence/Codes de sortie : 0 conforme, 1 sous le seuil, 2 erreur technique. Formats : table, json, sarif, junit, csv, html.
8. Revenir en arrière
Pavois sait annuler son propre durcissement. Parmi les outils qui remédient (OpenSCAP, l’USG d’Ubuntu, les CIS Build Kits, ansible-lockdown), aucun ne livre l’inverse de sa propre remédiation. C’est possible ici pour une raison précise : le plan est déclaratif, donc ce que le run va toucher est connu AVANT qu’il ne tourne. Là où vous disposez d’instantanés (NixOS, rpm-ostree, ZFS, LVM, une VM), ceux-là sont strictement meilleurs : servez-vous-en. Le chapitre rollback détaille le précédent (Bastille Linux, 2003) et les limites.
Avant de converger, harden apply photographie l’état antérieur : le contenu de chaque fichier que la recette va écrire, la liste de ceux qui n’existaient pas encore (le rollback les supprime), et l’état installé/activé de chaque paquet et service touché.
# l’apply écrit un point de restauration, puis converge
pavois harden apply --target user@host --key ~/.ssh/id --sudo-prompt --yes plan.yml
# pavois: 📸 restore point → restore-points/user_192-0-2-10-20260714-1505
# annuler : fichiers restaurés, paquets purgés, services remis, démons rechargés
pavois harden rollback restore-points/user_192-0-2-10-20260714-1505 --key ~/.ssh/id --sudo-prompt --yesMesuré sur une debian 12 neuve, un apply complet de 268 items puis un rollback : 597 des 620 contrôles reviennent à un état identique, soit 96 %. Le rollback recharge aussi les démons : un sshd_config restauré que personne n’a rechargé n’a rien annulé.
Ce n’est pas une machine à remonter le temps, et le manifeste le dit. Les 23 qui ne reviennent pas sont publiés un par un : douze durcissements ont survécu au rollback (un /tmp déjà monté, une valeur sysctl vivante), sept contrôles sont devenus applicables (les journaux que le run a créés existent toujours), un a cessé de l’être, et trois contrôles qui PASSAIENT échouent désormais (purger un paquet supprime son utilisateur système, et ses fichiers deviennent sans propriétaire). Un rollback n’est pas une opération neutre, et le manifeste le dit avant que vous ne confirmiez.
Reste la règle de prudence : prenez un instantané avant le premier apply en production, et faites votre premier essai sur un clone. Un rollback à 96 % est un filet, pas un permis d’imprudence.
9. Toute une flotte
Un run de pavois audite UNE cible. Il n’y a pas d’agrégation de flotte intégrée : c’est un manque assumé, pas une fonction cachée. En pratique, une boucle et un dossier de rapports suffisent, parce que chaque scan émet un JSON complet et autoporté.
# un scan par hôte, un JSON par hôte
while read -r host; do
pavois scan "$host" --key ~/.ssh/id_ed25519 --sudo --on-target \
--format json --out reports/ --fail-under 70 || echo "$host below threshold"
done < inventory.txt
# la note et les échecs de chaque hôte, en une ligne
jq -r '.grade + " " + (.failed|tostring) + " " + .target' reports/*.jsonLe durcissement suit la même logique : un plan par hôte, revu, puis appliqué. Rien n’empêche de piloter la boucle depuis Ansible ou Rundeck : pavois est un binaire sans agent, qui utilise votre ssh_config et votre sudo.
Construire depuis les sources (contributeurs)
Tout ce qui précède se fait avec le binaire publié. Cette section s’adresse à qui modifie Pavois, et à personne d’autre : la compilation tire une chaîne Go, Node et Python épinglée, puis régénère le corpus de règles et le paquet OSCAL qu’un binaire de release porte déjà en lui.
sudo apt install -y extrepo && sudo extrepo enable mise # dépôt signé, jamais un script tubé
sudo apt update && sudo apt install -y mise
# Fedora / RHEL : dnf copr enable jdxcode/mise && dnf install mise
# macOS : brew install mise
git clone https://github.com/stephrobert/pavois.git && cd pavois
mise trust && mise install # Go, Node, Python épinglés
mise run build # -> go/pavois
mise run regen # corpus .rb + OSCAL depuis la référence
./go/pavois doctor # vérifie CINC, sudo, SSH, OS, corpusSur Fedora ou RHEL : dnf copr enable jdxcode/mise && dnf install mise ; sur macOS : brew install mise. Détails et dépannage : Installation.
À retenir
- Trois commandes :
build,scan,harden. - Pas d’agent : Pavois utilise votre ~/.ssh/config et votre sudo, comme oscap/lynis.
- Un A net exige une posture reboot-proof, pas seulement active.
- Un apply ne suffit pas : le durcissement modifie l’état sur lequel le plan a été calculé. Converge jusqu’au point fixe.
- Partitions et noyau ne se corrigent pas à chaud : ce sont des recettes, et la note remédiable dit ce que pavois peut atteindre sans elles.
- Vérifiez toujours qu’un hôte durci fonctionne encore : pare-feu, sshd, gestionnaire de paquets, journalisation.