Aller au contenu

Tableaux de bord Grafana — DashRiver

DashRiver permet d'afficher les indicateurs d'InfraRiver (vulnérabilités, verdicts SSVC, constats CrossRiver…) dans votre propre Grafana, ou dans tout autre outil de BI compatible MySQL/MariaDB.

Pas de Grafana embarqué

InfraRiver n'installe pas de Grafana : vous avez déjà le vôtre, durci et validé chez vous. DashRiver fournit ce qu'il faut pour vous y brancher proprement : une source de données en lecture seule et des tableaux de bord d'exemple.

Page : Analyse → DashRiver (/dashriver/). Elle affiche les paramètres de connexion, la liste des vues exposées sur votre instance et les tableaux de bord d'exemple à télécharger.

flowchart LR
    G["Votre Grafana"] -- "MySQL, port 3306<br/>compte grafana_ro" --> V["Vues vw_dash_*<br/>(lecture seule)"]
    V --> T[("Tables internes<br/>d'InfraRiver")]
    G -. "aucun accès" .-x T

Principe et cloisonnement

  • InfraRiver expose des vues SQL préfixées vw_dash_*. Elles forment une interface stable : elles ne changent pas quand InfraRiver fait évoluer ses tables internes.
  • Grafana s'y connecte avec un compte MariaDB dédié en lecture seule, grafana_ro.
  • Ce compte ne peut lire que ces vues. Il n'a aucun accès aux tables, à la configuration, aux secrets ni aux comptes d'InfraRiver. Les vues s'exécutent avec les droits de leur créateur (SQL SECURITY DEFINER) : Grafana lit le résultat sans jamais voir les tables. Ce n'est pas une consigne, c'est une impossibilité technique.
  • Pour un audit, la liste des droits du compte (SHOW GRANTS) décrit de façon exhaustive tout ce que la BI peut voir.

État courant, pas d'historique

Les vues renvoient l'état actuel du parc, recalculé à chaque requête. Elles ne contiennent pas d'historique : les panneaux de type « courbe dans le temps » ne sont pas adaptés. Utilisez des panneaux Stat, Jauge, Tableau, Barres ou Camembert.


Prérequis

Élément Qui Détail
Grafana 10 ou supérieur Équipe Grafana Source de données MySQL intégrée (aucun plugin à installer)
Accès root au serveur InfraRiver Administrateur InfraRiver Pour ouvrir MariaDB au réseau et créer le compte
Adresse IP du serveur Grafana Équipe Grafana Le compte et le pare-feu sont restreints à cette seule adresse
Flux réseau Grafana → InfraRiver, TCP 3306 Réseau À ouvrir uniquement depuis le serveur Grafana

Dans les exemples ci-dessous, le serveur Grafana a l'adresse 10.0.0.20 et le serveur InfraRiver l'adresse 10.0.0.10. Remplacez-les par vos valeurs.


Étape 1 — Préparer InfraRiver (administrateur)

Toutes les commandes s'exécutent en root sur le serveur InfraRiver.

1.1 Rendre MariaDB joignable depuis le réseau

Par défaut, MariaDB n'écoute que localement. Dans /etc/my.cnf.d/mariadb-server.cnf, section [mysqld], indiquez l'adresse du serveur InfraRiver :

[mysqld]
bind-address = 10.0.0.10

Autorisez ensuite le port 3306 pour le seul serveur Grafana, puis redémarrez MariaDB :

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.20/32" port port="3306" protocol="tcp" accept'
firewall-cmd --reload
systemctl restart mariadb

Coupure brève

Le redémarrage de MariaDB interrompt InfraRiver quelques secondes. Faites-le hors des heures de production.

N'ouvrez jamais le port 3306 à tout le réseau ni à Internet

Utilisez une règle ciblée sur l'adresse du serveur Grafana, comme ci-dessus. Pas de --add-port=3306/tcp global.

1.2 Créer le compte grafana_ro

Générez un mot de passe robuste et créez le compte, limité à l'adresse du serveur Grafana :

openssl rand -base64 24          # mot de passe à conserver dans votre coffre-fort
mysql -e "CREATE USER 'grafana_ro'@'10.0.0.20' IDENTIFIED BY 'LE_MOT_DE_PASSE';"

1.3 Donner la lecture sur les vues, et seulement sur elles

La commande suivante génère puis applique un GRANT SELECT pour chaque vue vw_dash_* présente dans la base opsportal :

mysql -N opsportal <<'SQL' | mysql
SELECT CONCAT('GRANT SELECT ON opsportal.', TABLE_NAME, ' TO ''grafana_ro''@''10.0.0.20'';')
FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_SCHEMA = 'opsportal' AND TABLE_NAME LIKE 'vw\_dash\_%';
SQL

Vérifiez le résultat :

mysql -e "SHOW GRANTS FOR 'grafana_ro'@'10.0.0.20';"

Vous devez obtenir une ligne GRANT USAGE (connexion seule) et une ligne GRANT SELECT ON opsportal.vw_dash_… par vue. Aucune ligne ne doit porter sur opsportal.* ni sur une table.

Nouvelle vue après une mise à jour

Quand une mise à jour ou un nouveau connecteur ajoute une vue vw_dash_* (elle apparaît sur la page DashRiver), relancez la commande de l'étape 1.3 : elle est sans effet sur les droits déjà accordés.

1.4 Tester depuis le serveur Grafana

Si le client MariaDB est installé sur le serveur Grafana :

mysql -h 10.0.0.10 -u grafana_ro -p opsportal -e "SHOW TABLES;"

Seules les vues vw_dash_* doivent apparaître.


Étape 2 — Déclarer la source de données dans Grafana

  1. Connections → Data sources → Add data source → MySQL.
  2. Renseignez :

    Champ Grafana Valeur
    Name InfraRiver (libre)
    Host URL 10.0.0.10:3306 — l'adresse réseau du serveur InfraRiver
    Database name opsportal
    Username grafana_ro
    Password le mot de passe créé à l'étape 1.2
  3. Cliquez sur Save & test : Grafana doit afficher Database Connection OK.

« localhost » sur la page DashRiver

La page DashRiver affiche l'hôte de la base tel que le voit le serveur InfraRiver (souvent localhost). Dans Grafana, indiquez toujours l'adresse réseau du serveur InfraRiver.


Étape 3 — Importer le tableau de bord d'exemple

Le tableau de bord « CVE & SSVC — Exposition infrastructure » (cve_kpis.json) est un bon point de départ. Il contient :

  • quatre indicateurs : findings ouverts, CVE distinctes présentes au catalogue KEV de la CISA, CVE distinctes à EPSS ≥ 10 %, verdicts SSVC Act ;
  • le top 20 des CVE par EPSS ;
  • la répartition des verdicts SSVC.

Finding ou CVE ?

Un finding est une CVE ouverte sur un serveur : une même CVE présente sur 40 serveurs compte pour 40 findings, mais pour 1 CVE.

  1. Sur la page DashRiver, cliquez sur ↓ télécharger en face de cve_kpis.json.
  2. Dans Grafana : Dashboards → New → Import, chargez le fichier. Grafana détecte que le tableau de bord référence une source de données et affiche un champ InfraRiver (nom donné à l'entrée générique du fichier — sans rapport avec le nom que vous avez choisi à l'étape 2) : sélectionnez-y votre source InfraRiver créée à l'étape 2.
  3. Import.

Le tableau de bord de l'évolution des indicateurs

Un second fichier, indicators.json (nom affiché : dashriver), reprend dans votre Grafana l'historique des indicateurs des tableaux de bord InfraRiver : il lit la vue vw_dash_indicators. L'import se fait comme ci-dessus.

Choisissez l'indicateur dans la liste Indicateur en haut de la page. Vous obtenez :

  • sa dernière valeur, sa courbe et sa répartition ;
  • le dernier chiffre de chaque indicateur ;
  • pour Où en est-on ?, la note et les constats de chaque page d'analyse.

  • Chaque ligne de la vue est un instantané pris sur tout le parc ; la date est en UTC.

  • Les points où une source ne répondait pas (sources_ok plus petit que sources_total) sont écartés de la courbe, comme dans InfraRiver : une panne de connecteur n'est pas une baisse.
  • parts (la répartition) et sources (l'état de chaque source) sont du JSON ; ouvrez-les avec JSON_TABLE comme le font les panneaux du fichier.
  • Si vous avez créé le compte grafana_ro avant la mise à jour qui apporte cette vue, relancez la commande de l'étape 1.3 pour lui accorder SELECT sur vw_dash_indicators.

Étape 4 — Créer votre propre tableau de bord

Le principe d'un panneau

  1. Dashboards → New → New dashboard → Add visualization, puis choisissez la source InfraRiver.
  2. Dans l'éditeur de requête, passez de Builder à Code et saisissez la requête SQL.
  3. Choisissez Format : Table : les vues n'ont pas de colonne de temps.
  4. À droite, choisissez le type de visualisation, puis donnez un titre au panneau.
  5. Apply, puis enregistrez le tableau de bord (icône disquette).

Exemple 1 — Indicateur « Findings KEV »

Visualisation Stat :

SELECT SUM(kev_count) AS value FROM vw_dash_cve_kpis

Dans Thresholds, mettez la base en vert et ajoutez un seuil rouge à 1 : le panneau passe au rouge dès qu'une vulnérabilité activement exploitée est présente sur le parc. Le chiffre compte des findings (couples serveur × CVE), pas des CVE distinctes.

Exemple 2 — Top 20 des CVE les plus probablement exploitées

Visualisation Table :

SELECT cve_id AS "CVE", severity AS "Sévérité", cvss AS "CVSS",
       epss AS "EPSS", is_kev AS "KEV", servers_affected AS "Serveurs"
FROM vw_dash_top_cves
ORDER BY COALESCE(epss, 0) DESC
LIMIT 20

Pour rendre le tableau plus lisible :

  • Overrides → Fields with name EPSS : Unit Percent (0.0-1.0) et Cell type Colored background, avec des seuils (par exemple orange à 0,1, rouge à 0,5).
  • Overrides → Fields with name KEV : Value mappings 1 → KEV (rouge) et 0 → —.

Exemple 3 — Répartition des verdicts SSVC

Visualisation Pie chart :

SELECT verdict AS metric, cnt AS value FROM vw_dash_ssvc_verdicts

Dans Value options → Show, choisissez All values pour obtenir une part par verdict.

Exemple 4 — Constats CrossRiver ouverts par famille, avec filtre

Visualisation Bar chart :

SELECT family AS "Famille",
       open_critical_count AS "Critiques",
       open_high_count     AS "Élevés"
FROM vw_dash_crossriver_summary
WHERE family IN ($famille)
ORDER BY open_critical_count DESC

$famille est une variable de tableau de bord, qui ajoute une liste de choix en haut de l'écran :

  1. Dashboard settings → Variables → Add variable, type Query, nom famille.
  2. Source InfraRiver, requête :

    SELECT DISTINCT family FROM vw_dash_crossriver_summary ORDER BY family
    
  3. Cochez Multi-value et Include All option, puis enregistrez.

Actualisation

Les vues sont recalculées à chaque requête, et les données d'InfraRiver évoluent au rythme des synchronisations des connecteurs et des collecteurs. Une actualisation automatique toutes les 5 à 15 minutes (sélecteur en haut à droite du tableau de bord) suffit largement. Des intervalles plus courts chargent la base sans rien apporter.


Référence des vues

La liste exacte des vues présentes sur votre instance est affichée sur la page DashRiver. Pour voir toutes les colonnes d'une vue, depuis Grafana (Explore, source InfraRiver) :

SHOW COLUMNS FROM vw_dash_cve_kpis
Vue Contenu Colonnes principales
vw_dash_cve_kpis Indicateurs de vulnérabilité, une ligne par sévérité (d'où les SUM) severity, total_cves, servers_affected, total_findings, kev_count, high_epss_count, kev_cves, high_epss_cves, computed_at
vw_dash_top_cves Les 20 CVE ouvertes les plus probablement exploitées (EPSS) cve_id, severity, cvss, epss, is_kev, servers_affected
vw_dash_ssvc_verdicts Nombre de findings (couples serveur × CVE) par verdict SSVC verdict, cnt, computed_at
vw_dash_top_servers Les 15 serveurs ayant le plus de findings ouverts hostname, ip_address, environment, criticality, open_findings, max_epss
vw_dash_indicators L'historique des indicateurs des tableaux de bord InfraRiver : une ligne par instantané indicator_id, question, taken_at (UTC), kind (scheduled ou manual), value, parts (répartition, JSON), sources (état de chaque source, JSON), sources_total, sources_ok
vw_dash_crossriver_summary Constats CrossRiver, une ligne par famille family, total_findings, open_count, open_critical_count, open_high_count, ai_classified_count, last_seen_at, computed_at

kev_count/high_epss_count vs kev_cves/high_epss_cves

Les deux premiers comptent des findings (couples serveur × CVE) — une CVE KEV ouverte sur 40 serveurs vaut 40. Les deux derniers comptent des CVE distinctes — la même situation vaut 1. Pour un indicateur « combien de CVE activement exploitées touchent mon parc », utilisez kev_cves/high_epss_cves.

Les autres vues ne sont pas exposées

Certains connecteurs créent aussi des vues v_* pour leur usage interne. Elles ne font pas partie de l'interface DashRiver et le compte grafana_ro n'y a pas accès.


Dépannage

Symptôme Cause probable Solution
Save & test : délai dépassé ou connection refused MariaDB n'écoute pas sur le réseau, ou le pare-feu bloque Vérifier bind-address (étape 1.1) et la règle firewalld ; ss -ltn \| grep 3306 sur le serveur InfraRiver
Access denied for user 'grafana_ro'@'…' Mot de passe erroné, ou l'adresse vue par MariaDB n'est pas celle du CREATE USER (NAT, proxy) Comparer l'adresse citée dans le message avec celle du compte ; recréer le compte avec la bonne adresse
SELECT command denied … for table 'vw_dash_…' Vue ajoutée après la création du compte Relancer la commande de l'étape 1.3
Datasource … was not found après import La source InfraRiver n'a pas été sélectionnée dans le champ affiché à l'import Ouvrez chaque panneau, sélectionnez la source InfraRiver, puis enregistrez — ou réimportez en renseignant le champ cette fois
Panneau vide (No data) Format Time series au lieu de Table, ou module sans données Passer en Format : Table ; vérifier que le connecteur concerné a bien synchronisé
Une vue attendue n'existe pas Module ou connecteur non activé sur votre instance La page DashRiver liste les vues réellement présentes

Bonnes pratiques de sécurité

  • Un compte par serveur Grafana, restreint à son adresse IP. Jamais 'grafana_ro'@'%'.
  • Mot de passe conservé dans un coffre-fort, jamais dans un ticket ni un courriel. Pour le changer : ALTER USER 'grafana_ro'@'10.0.0.20' IDENTIFIED BY '…';, puis mise à jour de la source dans Grafana.
  • Chiffrement : si MariaDB est configuré en TLS, ajoutez REQUIRE SSL au compte et activez Use TLS Client Auth / With CA Cert dans la source Grafana.
  • Audit : SHOW GRANTS FOR 'grafana_ro'@'10.0.0.20'; donne la liste close de ce que la BI peut lire.
  • Révocation : DROP USER 'grafana_ro'@'10.0.0.20'; puis suppression de la règle firewalld.

Ce qui n'est pas dans DashRiver

  • Les graphes (chemins d'attaque, cartographie) : ils vivent dans PathFinder et TopoMap.
  • Les indicateurs affichés dans InfraRiver lui-même (tableau de bord d'accueil, cartes de chaque page) : ils sont gérés par chaque module, indépendamment de DashRiver.