InfraGuard

Diagnostic de sécurité

Lancez des analyses de rootkits et de durcissement sur de nombreux serveurs à la fois, notez chaque hôte de A à F et promouvez automatiquement les échecs critiques en cas de Résolution des problèmes.

Vue d’ensemble — à quoi cela sert

Diagnostic de sécurité exécute une analyse des traces de rootkit ainsi qu’une analyse de durcissement du système sur vos serveurs enregistrés, note chaque résultat sous forme d’un score de 0 à 100 assorti d’une note de A à F, et affiche sur un seul écran la posture de sécurité de l’ensemble de votre parc. Chaque contrôle est accompagné d’une explication quoi/pourquoi/comment corriger, et tout constat qui est un échec dont la sévérité est critique (fail + crit) est promu automatiquement en cas de Résolution des problèmes (dédoublonné, et résolu automatiquement dès que le contrôle passe de nouveau).

Composants principaux :

Exécuter la sonde en tant que root active les contrôles privilégiés tels que /etc/shadow, sudoers et sshd -T. Sans les droits root, les contrôles privilégiés sont rétrogradés en skip et exclus du dénominateur du score (aucune pénalité).

Quand l’utiliser

Disposition

Zone Contenu
Bandeau de KPI Score moyen du parc · nombre d’hôtes analysés · cas critiques ouverts · total des contrôles en échec · heure de la dernière analyse
Répartition des notes Histogramme du nombre d’hôtes A/B/C/D/F
Scores par catégorie Consolidation des 9 catégories (moyenne du parc, ordre du catalogue, couleur de tonalité)
Tendance du score Les 60 dernières analyses par ordre chronologique
Hôtes par note Grille de cartes d’hôtes — triées du score le plus bas (le plus risqué) en premier. Chaque carte affiche la note, les compteurs pass/warn/fail/crit, la source d’entrée et l’heure de l’analyse. Clic → fenêtre de rapport
Fenêtre de rapport Score et note globaux + résumé (SE/noyau) + détail par contrôle (quoi/pourquoi/correctif/preuve) + lien vers le cas promu

Barre d’outils supérieure : [Lancer l’analyse] (exécution distante multi-serveurs) · [Coller le résultat] · Actualiser · Bascule d’actualisation automatique · Plein écran.

Comment l’utiliser

Quatre voies d’entrée

infr_sec_scan.source classe la manière dont une analyse a été reçue :

source Point d’entrée Méthode
emulate Fenêtre [Lancer l’analyse] Sélectionnez les instances → déployez et exécutez la sonde à distance. Un collage ou une application d’émulation distante portant un instance_id est également enregistré comme emulate
paste Fenêtre [Coller le résultat] Collez le JSON de la sonde produit directement sur la cible, sans liaison à une instance
api POST /api/v1/security/scan Le cron de chaque hôte exécute la sonde → envoie via une clé d’API (la voie du rapporteur)
manual Repli Valeur par défaut lorsque la valeur de source n’est pas valide

1) Exécution distante multi-serveurs — interrogation asynchrone

Une exécution complète synchrone dépasserait le temps d’exécution de PHP sur de nombreux hôtes ; le flux est donc enregistrer → worker lancé sans attente → interroger.

  1. [Lancer l’analyse] → cochez les instances cibles (chacune indique joignable / injoignable).
  2. POST /security/diagnostics/run → crée un enregistrement de progression et renvoie immédiatement run_id (Cache, TTL 30 min).
  3. Le front end appelle POST /security/diagnostics/run-worker/{runId} sans attendre → le worker traite tous les hôtes séquentiellement sous set_time_limit(0) et ignore_user_abort (l’échec d’un hôte n’arrête pas les autres).
  4. Le front end interroge GET /security/diagnostics/run-status/{runId} pour mettre à jour la progression (done/total/ok).

Une instance marquée injoignable ne correspond à aucun nœud du collecteur run_report : elle ne peut donc pas être exécutée à distance. Exécutez la sonde directement sur l’hôte et soumettez-la via [Coller le résultat]. Voir Émulation distante pour le câblage de l’exécution distante.

2) Collage / ingestion de JSON

Exécutez la sonde sur l’hôte cible et collez son JSON.

# Sur l’hôte cible (recommandé : root)
node infr_seccheck_probe.cjs --min

--min produit du JSON sur une seule ligne. Forme de la sortie :

{
  "host": "web-01",
  "generated_at": "2026-08-13T03:30:00Z",
  "os": "Rocky Linux 9.3",
  "kernel": "5.14.0-362.el9",
  "root": true,
  "checks": [
    { "key": "ssh_root_login", "category": "ssh", "status": "fail", "severity": "crit", "detail": "PermitRootLogin yes", "evidence": "/etc/ssh/sshd_config:32" },
    { "key": "svc_firewall",   "category": "services", "status": "pass", "severity": "crit", "detail": "firewalld active" }
  ],
  "summary": {}
}

C’est POST /security/diagnostics/ingest qui le reçoit. Lier une instance enregistre source=emulate ; laisser la liaison vide enregistre source=paste.

3) Rapporteur d’API (automatisation)

Le cron de chaque hôte exécute la sonde et pousse le résultat dans InfraGuard. Émettez la clé d’API dans Administration ▸ Clés API ; la clé doit porter la portée scan.write.

30 3 * * *  node /opt/infr/infr_seccheck_probe.cjs --min | curl -sS -X POST https://infraguard.example.com/api/v1/security/scan -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" --data @-

Réponse (201) :

{ "ok": true, "scan_id": 812, "host": "web-01", "score": 74, "grade": "C" }

Notation — SecurityCheckbook

Le score est un rapport pondéré de la pondération et du statut de chaque contrôle.

Facteur de statut (STATUS_FACTOR) — seuls ceux-ci comptent ; skip/info sont exclus du dénominateur :

Statut Facteur
pass 1.0
warn 0.6
fail 0.0
skip · info exclus

Multiplicateur de sévérité (SEV_MUL) — plus l’implication d’un échec est lourde, plus il déplace le score :

fail_severity Multiplicateur
crit 1.6
warn 1.0
info 0.5

Pondération par contrôle w = check_weight(1–3) × severity_multiplier ; score global = round(100 × Σ(w × status_factor) / Σw). Les scores par catégorie utilisent la même formule au sein de chaque catégorie.

Note et tonalité :

Score Note Tonalité
≥ 90 A good
≥ 80 B good
≥ 70 C warn
≥ 60 D warn
< 60 F crit

(Les notes sont A/B/C/D/F ; la tonalité est good ≥ 80 · warn ≥ 60 · crit < 60.)

9 catégories · 36 contrôles

Chaque catégorie possède une pondération d’affichage et une icône ; la notation réelle utilise la pondération par contrôle × multiplicateur de sévérité ci-dessus.

Catégorie Libellé Contrôles Contrôles notables (implication en cas d’échec)
rootkit Rootkit / logiciel malveillant 6 rk_known_files·rk_ld_preload·rk_hidden_proc (crit)
patch Correctifs / mises à jour 3 pt_security_updates·pt_eol_os (crit)
ssh Configuration SSH 5 ssh_root_login·ssh_empty_pass (crit)
accounts Comptes / privilèges 5 acc_uid0·acc_empty_pass (crit)
network Exposition réseau 3 net_legacy_services·net_db_exposed (crit)
filesystem Permissions du système de fichiers 5 fs_shadow_perm (crit)·fs_world_writable·fs_suid (warn)
hardening Durcissement du système 5 hd_selinux·hd_aslr·hd_syncookies (warn)
services Services / pare-feu 2 svc_firewall (crit)·svc_unnecessary (info)
logging Audit / journalisation 2 log_auditd·log_syslog (warn)

Les clés inconnues sont absorbées dans la catégorie other. Le texte « quoi / pourquoi / correctif » de chaque contrôle est rendu dans la fenêtre de rapport depuis seccheck.check.*.

Constats critiques → promotion en Résolution des problèmes

À chaque ingestion, reconcileCases() réconcilie les cas de l’hôte.

Les contrôles promus apparaissent dans la fenêtre de rapport avec un badge « promu en résolution » et un lien [Voir le cas]. Les cas se traitent sur le tableau Sécurité ▸ Résolution des problèmes.

Supprimer une analyse (POST /security/diagnostics/delete) ne supprime pas les cas qu’elle a promus : ils sont indépendants.

Sources de données

Source Rôle
infr_sec_scan (000766) Résultats d’analyse (un par hôte). JSON score·grade·pass/warn/fail/crit/total_count·category_scores·summary·findings. Index (host,scanned_at)·(instance_id,scanned_at)·grade·score
infr_instance Instances cibles (résout host → instance_id par alias/hostname)
infr_incident / infr_incident_event Cas critiques promus et leur chronologie
infr_api_key Authentification du rapporteur d’API (portée scan.write)
Cache Agrégat du tableau de bord mis en cache 20 s (infr:sec:diag:build) · enregistrement de progression de l’exécution asynchrone (TTL 1800 s)
infr_seccheck_probe.cjs La sonde source (locale, en lecture seule)

Accès

Pour le modèle de niveaux en général (middleware infr.level:N), voir Niveaux RBAC.

Dépannage et FAQ

Q. Une instance apparaît « injoignable » dans [Lancer l’analyse]. Elle ne correspond à aucun nœud du collecteur run_report, il n’y a donc pas de câblage d’exécution distante. Exécutez la sonde directement sur l’hôte et soumettez-la via [Coller le résultat].

Q. Erreur « No checks found ». Le JSON collé ne contient pas de tableau checks (ni items), ou ses entrées n’ont pas de key. Collez la sortie de infr_seccheck_probe.cjs --min telle quelle.

Q. Le score est faible alors que le nombre d’échecs est réduit. C’est le multiplicateur de sévérité. Un échec crit pèse 1,6 fois un warn. Utilisez les scores par catégorie et la fenêtre de rapport pour repérer le constat qui tire le score vers le bas.

Q. Tous les contrôles privilégiés sont en skip. La sonde a été exécutée avec un compte non root. Des contrôles comme /etc/shadow, sudoers ou sshd -T nécessitent root. skip est exclu du dénominateur (aucune pénalité), mais exécutez la sonde en root (ou via la passerelle) pour un diagnostic complet.

Q. Une exécution prend du temps — puis-je fermer le navigateur ? Oui. Le worker est lancé sans attente et continue sous ignore_user_abort même si la requête est interrompue. Rouvrez et interrogez run-status, ou lisez simplement les notes une fois qu’elles apparaissent sur le tableau de bord. L’enregistrement de progression est conservé 30 minutes.

Q. Un cas a disparu de lui-même. Si une analyse ultérieure ne signale plus ce constat comme fail+crit (corrigé ou non détecté), le moteur résout automatiquement le cas. C’est le comportement attendu.

Voir aussi

보안 진단 — 점검 결과와 등급
보안 진단 — 점검 결과와 등급