NetDTL — Manuel de référence

Référence complète de l'application web d'inventaire réseau agentless et de diagnostic NetDTL v3.0.

version3.0 stackPHP 8.x / MySQL / Nmap licenceMIT auteurDidier DTL Morandi

Présentation

NetDTL est une application web auto-hébergée pour la découverte réseau agentless et la gestion d'inventaire sur infrastructure Windows. Elle fonctionne sur un stack PHP/MySQL/Nmap (XAMPP ou LAMP) et fournit un scan en temps réel via Server-Sent Events, le profilage des machines, des diagnostics réseau et la gestion du panneau de brassage — le tout via une interface web sombre sans dépendance JavaScript externe.

L'application est structurée en un ensemble de pages PHP, chacune responsable d'un domaine fonctionnel, partageant une couche de base de données commune (db.php), une feuille de style CSS (style.php) et des partiels de mise en page (topbar.php, sidebar.php).

Prérequis

ComposantVersionNotes
PHP8.xExtensions requises : pdo_mysql, mbstring
MySQL / MariaDBtoute version récenteUtilisé via PDO
Nmaptoute version récenteDoit être accessible depuis le processus PHP ; chemin défini via NMAP_PATH
XAMPP or LAMPTout environnement serveur PHP+MySQL standard
PowerShell5.1 / 7+Requis pour les descriptions WMI et les requêtes IP/services locaux
Note Windows : lorsque le serveur web tourne sous Windows, Nmap et PowerShell sont invoqués via shell_exec. Le compte du processus PHP doit disposer de privilèges suffisants, et Nmap doit être dans le PATH système ou son chemin complet renseigné dans db.php.

Installation

Déployer les fichiers de l'application dans la racine du serveur web (ex. htdocs/netdtl/ sous XAMPP, ou un virtual host dédié).

1. Créer la base de données

CREATE DATABASE netdtl CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'netdtl'@'localhost' IDENTIFIED BY 'yourpassword';
GRANT ALL PRIVILEGES ON netdtl.* TO 'netdtl'@'localhost';
FLUSH PRIVILEGES;

2. Configurer db.php

Modifier les constantes en haut de db.php pour correspondre à l'environnement. Le schéma de base de données est créé automatiquement au premier démarrage par initDB().

3. Premier démarrage

Ouvrir l'application dans un navigateur. initDB() créera toutes les tables requises si elles n'existent pas. Se connecter avec les identifiants définis dans AUTH_USER / AUTH_PASS.

Configuration

Toute la configuration se trouve dans db.php sous forme de constantes PHP. Il n'existe pas de fichier de configuration séparé.

ConstanteDescription
DB_HOSTHôte MySQL, typiquement localhost
DB_NAMENom de la base de données
DB_USERUtilisateur de la base de données
DB_PASSMot de passe de la base de données
AUTH_USERNom d'utilisateur HTTP Basic Auth
AUTH_PASSMot de passe HTTP Basic Auth (en clair dans la version actuelle)
NMAP_PATHChemin complet vers le binaire Nmap, ex. C:/Program Files (x86)/Nmap/nmap.exe
DEFAULT_NETWORKPlage CIDR pré-remplie affichée sur la page de découverte
APP_VERSIONChaîne de version affichée dans le pied de la barre latérale

Schéma de base de données

Les tables sont créées automatiquement par initDB() dans db.php via CREATE TABLE IF NOT EXISTS.

machines

Table d'inventaire centrale. Une ligne par adresse IP (clé unique sur ip).

ColonneTypeDescription
idINT AUTO_INCREMENTClé primaire
hostnameVARCHARHostname court ou IP si aucun nom résolu
ipVARCHAR(45)Adresse IPv4 — contrainte d'unicité
macVARCHAR(17)Adresse MAC en majuscules séparée par des deux-points
vendorVARCHARFabricant de la carte réseau issu de la table OUI Nmap
osVARCHARChaîne OS issue de la détection Nmap ou d'une saisie manuelle
switch_portVARCHARÉtiquette du port switch (ex. port1.0.3), renseigné manuellement
patch_portVARCHARÉtiquette du port brassage (ex. B31), renseigné manuellement
open_portsTEXTListe des ports ouverts séparés par des virgules, issus du dernier scan de ports
statusENUM('up','down','unknown')Statut de joignabilité courant
last_ping_msINTRTT ping moyen en millisecondes du dernier ping
commentTEXTNote libre ; aussi alimentée par l'enrichissement WMI / NetBIOS
first_seenDATETIMEDéfinie à l'INSERT, jamais mise à jour
last_seenDATETIMEMise à jour à chaque hit de scan ou ping

scan_history

Une ligne par scan de découverte terminé.

ColonneTypeDescription
idINT AUTO_INCREMENTClé primaire
scan_dateDATETIMEHorodatage de fin de scan
networkVARCHARPlage CIDR qui a été scannée
hosts_upINTNombre d'hôtes trouvés actifs
hosts_downINTStocké à 0 dans la version actuelle
duration_sINTDurée du scan en secondes

diag_history

Journal de toutes les opérations de diagnostic (ping, traceroute, DNS, scan de ports, détection OS).

ColonneTypeDescription
idINT AUTO_INCREMENTClé primaire
actionVARCHARNom de l'outil : ping, nmap, traceroute, dns, ports, infos, services, nmap_os
targetVARCHARIP, hostname ou CIDR ciblé
resultTEXT20 premières lignes de la sortie de la commande
successTINYINTToujours 1 dans la version actuelle
createdDATETIMEHorodatage de l'opération

patch_panel

Ports du panneau de brassage physique, généralement alimentés par import (CSV ou SQL direct).

ColonneTypeDescription
idINT AUTO_INCREMENTClé primaire
priseVARCHARÉtiquette de la prise murale (ex. B31) — unique
typeVARCHARRJ45, RJ11, ou autre
entiteVARCHAREntité ou département propriétaire
local_nameVARCHARNom du local ou de la pièce
etageVARCHARÉtage
posteVARCHARRéférence du poste ou du bureau
switchVARCHARNom ou identifiant du switch
port_switchVARCHARPort switch (ex. port1.0.3)
notesTEXTNotes libres

patch_machines

Jointure many-to-many entre les ports du panneau de brassage et les machines (un port peut desservir plusieurs IP).

ColonneTypeDescription
idINT AUTO_INCREMENTClé primaire
priseVARCHARRéférence étrangère vers patch_panel.prise
machine_ipVARCHARAdresse IP de la machine sur ce port
hostnameVARCHARHostname au moment de l'association

Pages

Tableau de bord

index.php
Page d'entrée et de vue d'ensemble. Affiche les statistiques globales de l'inventaire, les 8 machines les plus récemment vues et les 5 dernières opérations de diagnostic.
Accès

Nécessite une authentification via requireAuth(). Page d'accueil par défaut après connexion.

Requêtes de données
Aucune action POST

Page en lecture seule. Toutes les actions (ping, ajout, suppression) se trouvent sur inventory.php et machine.php.

Inventaire

inventory.php
Liste complète des machines avec recherche, filtrage par statut, ping inline, ajout manuel, suppression et export CSV. Interface de gestion principale de la table machines.
Paramètres GET
ParamètreDescription
qRecherche libre sur hostname, IP, OS, commentaire
statusFiltre par statut : up, down, ou unknown
export=csvDéclenche le téléchargement CSV de l'inventaire complet (ignore tous les filtres)
Actions POST
ChampAction
add_machineInsère une nouvelle ligne machine. Champs obligatoires : hostname, ip (IP valide). Optionnels : os, comment, switch_port, patch_port.
delete_idSupprime la machine avec l'ID donné. Demande une confirmation JavaScript avant soumission.
ping_idLance un ping contre l'IP de la machine via runPing(), met à jour status, last_ping_ms, last_seen.
ping_allPing toutes les machines de l'inventaire séquentiellement. Met à jour tous les champs de statut.
Export CSV

Déclenché par ?export=csv. Exporte toutes les machines triées par INET_ATON(ip) (tri IP numérique). Colonnes : Hostname, IP, MAC, Fabricant, Port switch, Brassage, OS, Statut, Ports ouverts, Ping (ms), Dernière vue, Commentaire. BOM ajouté pour compatibilité Excel UTF-8.

Détection IP du serveur : la page d'inventaire détecte l'IP propre du serveur web via $_SERVER['SERVER_ADDR'] et remplace l'affichage du champ MAC par ce PC (en italique) pour éviter toute confusion avec la MAC de Nmap (que Nmap ne peut pas lire pour la machine qui scanne).

Fiche machine

machine.php
Page de profil par machine. Affiche les informations réseau complètes, permet la modification de l'OS, du port switch, du port brassage et du commentaire, et fournit des actions de diagnostic rapide. Tous les résultats de diagnostic sont affichés dans un bloc terminal et enregistrés dans diag_history.
Paramètres GET
ParamètreDescription
idID de la machine (entier). Redirige vers inventory.php si non trouvée.
Actions POST
Champ / valeurAction
saveMet à jour os, switch_port, patch_port, comment pour la machine.
diag=pingLance un ping via runPing(). Met à jour status et last_ping_ms.
diag=portsLance nmap -p 21,22,23,25,80,110,143,443,445,3306,3389,5900,8080. Met à jour open_ports en BDD.
diag=tracerouteLance tracert (Windows).
diag=dnsLance nslookup.
diag=nmap_osLance nmap -O --host-timeout 10s. Extrait et sauvegarde la ligne OS details dans machines.os.
Rendu de la sortie terminal

Chaque ligne de sortie est classifiée et colorée : les lignes correspondant à TTL, Reply ou open sont en vert ; timeout / unreachable / filtered en orange ; error / failed en rouge. Un élément <pre id="raw-output"> masqué contient le texte brut pour la copie dans le presse-papier.

La détection OS nécessite des privilèges élevés : nmap -O requiert que le processus PHP s'exécute en tant qu'Administrateur (Windows) ou root (Linux).

Découverte réseau

discovery.php
Page de découverte. L'utilisateur saisit une plage CIDR, sélectionne des options d'enrichissement optionnelles et lance un scan. Les résultats sont diffusés en temps réel via Server-Sent Events depuis scan_stream.php. Les hôtes découverts sont automatiquement insérés ou mis à jour dans la table machines.
Contrôles de l'interface
ContrôleDescription
Champ réseauPlage CIDR (ex. 192.168.1.0/24). Pré-rempli avec DEFAULT_NETWORK.
Ports communsSi coché, lance un scan de ports supplémentaire sur chaque hôte découvert (?ports=1).
Détection OSAjoute -O à la commande Nmap (?os=1). Requiert admin/root.
Identifier NetBIOSLance une seconde passe de requêtes nbstat après le scan principal (?nbstat=1).
Descriptions WMIInterroge chaque hôte actif via PowerShell WMI pour la description OS (?wmi=1).
Flux d'événements SSE

La page ouvre une connexion EventSource vers scan_stream.php avec des paramètres de requête reflétant les options sélectionnées. Les événements sont traités par handleEvent(data) en JavaScript.

Type d'événementDescription
lineLigne brute de sortie Nmap. Classifiée par couleur et ajoutée au bloc terminal.
host_savedUn hôte a été inséré ou mis à jour. Ajoute une ligne au tableau des hôtes découverts dans l'interface.
macAdresse MAC et fabricant résolus pour une IP. Met à jour la ligne correspondante dans le tableau.
osChaîne OS détectée. Met à jour la ligne correspondante dans le tableau.
nbstatNom NetBIOS résolu. Met à jour la colonne description dans le tableau des hôtes.
wmiDescription WMI récupérée. Ajoutée à la colonne description dans le tableau des hôtes.
doneScan terminé. Met à jour les stats (nombre d'hôtes, durée), ajoute une ligne au tableau d'historique, complète la barre de progression.
errorErreur fatale côté serveur. Ferme l'EventSource, affiche le message d'erreur.
Historique des scans

Le bas de la page affiche les 10 entrées les plus récentes de scan_history. Une nouvelle ligne est ajoutée dynamiquement en JavaScript à la réception de l'événement done, sans rechargement de la page.

Endpoint SSE de découverte

scan_stream.php
Endpoint Server-Sent Events consommé exclusivement par discovery.php. Exécute Nmap, analyse sa sortie ligne par ligne, insère ou met à jour les machines en base de données, et lance optionnellement des passes d'enrichissement NetBIOS et WMI. Non destiné à être accédé directement.
Paramètres GET
ParamètreDéfautDescription
networkDEFAULT_NETWORKPlage CIDR à scanner. Validée par isValidTarget() avant utilisation.
ports0Si 1, lance un scan de ports sur chaque hôte découvert après le sweep ping.
os0Si 1, utilise nmap -sS -O au lieu de nmap -sn. Requiert des privilèges élevés.
nbstat0Si 1, lance une passe NetBIOS après le scan principal.
wmi0Si 1, interroge les descriptions WMI via PowerShell après le scan principal.
Phases du scan
Upsert en base de données

La fonction saveMachineStream() utilise INSERT ... ON DUPLICATE KEY UPDATE sur la colonne ip. Les valeurs existantes pour MAC, fabricant et OS sont préservées avec COALESCE(VALUES(col), col) — un scan n'écrasera pas les données saisies manuellement avec une valeur nulle.

Encodage

La sortie Nmap sous Windows est typiquement en CP850. Chaque ligne est convertie en UTF-8 via mb_convert_encoding($raw, 'UTF-8', 'CP850') avant d'être émise comme payload JSON SSE.

Durée d'exécution : set_time_limit(600) est appelé. Les grands réseaux ou les hôtes lents peuvent approcher cette limite. Le buffering de sortie est désactivé (ob_end_flush()) pour garantir que les événements sont diffusés dès leur arrivée.

Panneau de brassage

patch.php
Vue en lecture seule du panneau de brassage physique. Affiche les enregistrements de prises murales depuis la table patch_panel jointe aux IPs et hostnames de machines associées depuis patch_machines. Supporte le filtrage par switch, entité et recherche libre.
Paramètres GET
ParamètreDescription
qRecherche libre sur l'étiquette de prise, le nom du local, le poste, l'IP, le hostname
switchFiltre par identifiant de switch
entiteFiltre par entité / département
Alimentation des données

La table patch_panel n'est pas alimentée par NetDTL lui-même. Elle est destinée à être remplie par import externe (CSV, script SQL ou le moteur de patch panel du NetDTL Installer). L'application fournit uniquement l'interface de consultation et de filtrage.

Résolution IP et hostname

Pour chaque port, les machines associées sont récupérées depuis patch_machines via une jointure GROUP_CONCAT. Plusieurs IPs et hostnames par port s'affichent sous forme de listes séparées par des virgules.

Colorisation des badges

Les types de ports sont colorés : RJ45 en bleu, RJ11 en orange, inconnu en gris. Les badges d'entité distinguent l'équipement local (bleu-vert) du délégué (vert) par une correspondance insensible à la casse sur le mot locale dans le nom de l'entité.

Composants partagés

Base de données & helpers

db.php
Fichier d'inclusion central. Définit toutes les constantes de configuration, la connexion à la base de données, l'initialisation du schéma, l'authentification et les fonctions helper. Inclus en haut de chaque page.
Fonctions clés
FonctionDescription
getDB()Retourne une connexion PDO singleton. Lève une exception en cas d'échec.
initDB()Crée toutes les tables si elles n'existent pas.
requireAuth()Envoie un challenge WWW-Authenticate: Basic si les identifiants sont absents ou incorrects. Termine l'exécution en cas d'échec.
runCommand(string $cmd)Exécute une commande shell via shell_exec(), convertit l'encodage de CP850 vers UTF-8, retourne un tableau de lignes non vides.
runPing(string $ip)Lance ping -n 4 (Windows) ou ping -c 4 (Linux). Retourne les lignes de sortie.
parsePingStats(array $lines)Analyse la sortie ping et retourne ['sent', 'recv', 'lost_pct', 'avg_ms'].
isValidTarget(string $t)Retourne true si $t est une IP valide, un hostname ou une plage CIDR.
timeAgo(string $date)Retourne une chaîne de temps relatif lisible (ex. "il y a 3 minutes").

Feuille de style

style.php
Génère une balise <link> pour Google Fonts (IBM Plex Mono + IBM Plex Sans) et un bloc <style> complet contenant tout le CSS partagé. Inclus dans le <head> de chaque page via <?php include __DIR__ . '/style.php'; ?>.
Tokens de design (variables CSS)
VariableValeurUsage
--bg#0d1117Fond de page
--bg2#161b22Panneaux, barre latérale, barre supérieure
--bg3#1c2230En-têtes de tableau, cartes de stats
--accent#3fb950Vert — états actifs, badges "up", succès
--accent2#58a6ffBleu — liens, adresses IP, valeurs de ports
--warn#d29922Orange — avertissements, statut inconnu, étiquettes switch
--err#f85149Rouge — erreurs, badges "down"
--purple#bc8cffÉtiquettes de ports du panneau de brassage
--teal#64c8c8Badges d'entité locale, historique infos/services
--txt#c9d1d9Texte principal
--txt2#8b949eTexte secondaire / atténué
--txt3#484f58Placeholder / texte très atténué
--monoIBM Plex MonoTout le contenu monospace (IPs, ports, terminal)
--sansIBM Plex SansÉtiquettes, badges, chrome de l'interface

Barre de navigation supérieure

topbar.php
Affiche la barre supérieure fixe avec le logo NetDTL, les liens de navigation principaux (Tableau de bord, Inventaire, Découverte, Brassage, Diagnostics) et le nom de l'utilisateur connecté. L'état actif est défini en comparant basename($_SERVER['PHP_SELF'], '.php') à la cible de chaque lien. Le lien Inventaire est aussi actif sur machine.php.

Barre latérale gauche

sidebar.php
Affiche la barre latérale de navigation gauche fixe avec deux sections : Navigation (Tableau de bord, Inventaire, Découverte, Brassage) et Diagnostics (les sept outils). La chaîne de version de APP_VERSION et la version PHP sont affichées en bas. Les états actifs suivent la même logique que topbar.php ; pour les liens d'outils de diagnostic, l'outil actif est lu depuis $action (défini dans menu.php) ou depuis $_GET['tool'].

Sécurité

NetDTL utilise l'authentification HTTP Basic implémentée dans requireAuth(). Les identifiants sont stockés en clair dans db.php. Cela est acceptable pour un déploiement sur un réseau local de confiance, mais ne doit pas être exposé sur internet sans protection complémentaire (reverse proxy avec TLS, filtrage IP, etc.).

Identifiants : la constante AUTH_PASS est stockée en clair. Ne pas réutiliser un mot de passe sensible. Pour les environnements de production, envisager de remplacer requireAuth() par une authentification basée sur les sessions ou de déléguer l'authentification au serveur web.

Limitations connues

 

NetDTL Web site