Un service desk concentre des données sensibles : noms de collaborateurs, e-mails, numéros de téléphone, parfois des copies de documents d’identité, des captures d’erreurs qui révèlent l’architecture interne du SI, et la cartographie complète du parc IT. Compromettre GLPI revient à offrir une carte d’embuscade à un attaquant. Le durcissement n’est donc pas optionnel : c’est la condition pour pouvoir laisser l’outil exposé en production.
Ce tutoriel applique un programme de sécurisation en huit étapes éprouvées, depuis l’isolation réseau jusqu’à l’audit des accès. À la fin, votre instance GLPI 11 résiste aux scans automatisés courants, ralentit les attaques par dictionnaire, et trace ce qui se passe pour la suite. Le contexte ITSM global est posé dans GLPI 11 helpdesk ITIL : déployer un service desk professionnel.
Étape 1 — Forcer HTTPS et renforcer la configuration TLS
La base est posée dans le tutoriel d’installation Ubuntu avec un certificat Let’s Encrypt. Reste à durcir la configuration TLS au-delà des défauts d’Apache ou Nginx, et à activer les en-têtes de sécurité modernes.
Pour Apache, créez ou éditez /etc/apache2/conf-available/glpi-ssl-hardening.conf :
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLSessionTickets off
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self';"
Activez la configuration et rechargez :
sudo a2enconf glpi-ssl-hardening
sudo apache2ctl configtest
sudo systemctl reload apache2
La directive HSTS avec preload impose à tous les navigateurs récents d’accéder en HTTPS exclusivement pour les deux prochaines années. Testez ensuite le score TLS sur SSL Labs. Visez au minimum un grade A. Un grade B révèle généralement une cipher suite trop large ou une absence de HSTS.
La CSP « unsafe-inline » et « unsafe-eval » est nécessaire car GLPI 11 utilise encore des scripts inline dans certaines pages. Suivre la roadmap projet pour basculer sur une CSP stricte dès que possible.
Étape 2 — Fail2ban pour bloquer les attaques par force brute
Sans Fail2ban, un attaquant peut tester des milliers de mots de passe par minute sur la page de login GLPI. Avec un filtre adapté, trois échecs en moins de 5 minutes suffisent à bannir l’IP pour une heure. À noter : aucun filtre Fail2ban officiel n’est livré par le projet GLPI à ce jour, la communauté maintient l’issue de référence ouverte sur GitHub. Le filtre ci-dessous s’appuie sur le format réel des entrées du journal d’évènement GLPI.
GLPI écrit ses échecs de connexion dans son journal interne /var/www/glpi/files/_log/event.log au format [login] N: Failed login for USERNAME from IP ::ffff:A.B.C.D YYYY-MM-DD HH:MM:SS. Le filtre Fail2ban doit donc pointer sur ce fichier (pas sur le log Apache).
Créez un filtre dédié /etc/fail2ban/filter.d/glpi.conf :
[Definition]
failregex = ^.*\[login\]\s+\d+:\s+Failed login for \S+ from IP (::ffff:)?<HOST>
ignoreregex =
datepattern = {^LN-BEG}
Puis la jail /etc/fail2ban/jail.d/glpi.conf :
[glpi]
enabled = true
port = http,https
filter = glpi
logpath = /var/www/glpi/files/_log/event.log
maxretry = 3
findtime = 300
bantime = 3600
backend = auto
Le préfixe (::ffff:)? capture les IPv4 mappées en IPv6 (notation utilisée par PHP quand Apache écoute en dual-stack). Si tout votre trafic est en IPv4 pur, ce préfixe ne gêne pas, il accepte les deux formats.
Vérifiez d’abord que GLPI alimente bien event.log :
sudo tail -f /var/www/glpi/files/_log/event.log | grep -i "failed login"
Si rien ne sort lors d’un faux login, activez le journal de sécurité GLPI dans « Configuration » → « Générale » → « Système » → « Niveau de log » sur « Sécurité ». Redémarrez Fail2ban, puis testez avec trois faux logins :
sudo systemctl restart fail2ban
sudo fail2ban-client status glpi
La sortie doit indiquer la jail active. Après trois échecs, votre IP doit apparaître dans la liste « Currently banned ».
Étape 3 — Activer la double authentification pour les administrateurs
GLPI 11 propose nativement la 2FA basée sur TOTP (compatible Google Authenticator, Authy, 1Password, Bitwarden). Activez-la dans « Configuration » → « Générale » → « Sécurité » → « Authentification à deux facteurs ». Trois choix :
- Obligatoire pour tous — exigence maximale, recommandée pour les outils contenant des données très sensibles
- Obligatoire pour Super-Admin et Supervisor — bon compromis pour la plupart des organisations
- Facultative — l’utilisateur décide ; à éviter, la 2FA ne sert que si elle est forcée
Au prochain login, le compte concerné est invité à scanner un QR code et à saisir le code TOTP de son application. Une liste de codes de récupération à imprimer est générée — chaque administrateur doit la stocker dans son coffre-fort personnel pour ne pas se retrouver bloqué en cas de perte du téléphone.
Sur un compte AD/LDAP, la 2FA GLPI s’ajoute au mot de passe AD — la connexion exige les deux. Si votre AD impose déjà une 2FA (Azure MFA, Duo), vous pouvez désactiver la 2FA GLPI pour ces comptes en cochant « Désactiver la 2FA pour les comptes annuaire » et déléguer entièrement à l’IdP.
Étape 4 — Limiter l’exposition aux scans automatiques
Trois mesures réduisent fortement la surface visible :
Masquer la version GLPI dans les en-têtes de réponse. Allez dans « Configuration » → « Générale » → « Système » et décochez « Afficher la version GLPI publiquement ». Vérifiez avec curl -I https://glpi.example.com | grep -i glpi — vous ne devez plus voir la version exacte.
Bloquer l’accès direct aux fichiers de configuration. Dans le virtual host Apache, refuser explicitement :
<DirectoryMatch "/var/www/glpi/(config|files|inc|lib|vendor)">
Require all denied
</DirectoryMatch>
Désactiver les pages de statut publiques. La page /status.php de GLPI expose l’état général. Restreignez-la à un sous-réseau de monitoring :
<Location /status.php>
Require ip 10.0.10.0/24
</Location>
Ces trois mesures rendent les scans courants (Shodan, Censys, Greynoise) beaucoup moins informatifs sur votre instance.
Étape 5 — Restreindre l’accès admin par IP
La page /front/login.php est publique pour permettre aux utilisateurs Self-Service de se connecter depuis n’importe où. Mais l’accès à /front/central.php et aux sous-pages administratives n’a pas besoin d’être ouvert au monde entier. Si tous vos administrateurs travaillent depuis le siège ou via VPN, restreignez :
<LocationMatch "^/front/(central|admin|config)">
Require ip 10.0.0.0/8 192.168.0.0/16
</LocationMatch>
Tout accès depuis une IP hors de ces plages retourne 403, même avec un mot de passe valide. Pour les administrateurs en déplacement, prévoyez l’accès via VPN (WireGuard, OpenVPN, Tailscale) qui leur donne une IP interne autorisée.
Étape 6 — Activer et lire les journaux d’audit
GLPI 11 trace nativement les actions sensibles. Activez le maximum dans « Configuration » → « Générale » → « Système » → « Audit » :
- Sessions — création, fin, expiration de session
- Authentification — succès, échecs, blocages
- Modifications de tickets — qui a changé quoi quand
- API REST — chaque initSession + endpoint appelé
- Modifications de configuration — toute modification d’un paramètre sensible
Les logs s’écrivent dans /var/www/glpi/files/_log/. Configurez logrotate pour les compresser quotidiennement et les conserver 90 jours minimum. Un audit de sécurité serait incomplet sans un horizon de 3 mois de traces.
Pour aller plus loin, expédiez les logs vers un SIEM (Wazuh, Graylog, Elastic, Splunk) qui corrèle les événements GLPI avec ceux du système, du pare-feu et de l’AD. Une tentative d’élévation de privilèges déclenchée depuis une IP qui vient d’échouer 5 fois en SSH devient alors un signal exploitable, pas une ligne de log perdue.
Étape 7 — Sauvegarde et restauration testée
La meilleure défense contre un ransomware ou une corruption logicielle est une sauvegarde fonctionnelle. Le tutoriel d’installation a posé une sauvegarde quotidienne MariaDB. Trois compléments indispensables :
Sauvegarder aussi le répertoire files/ qui contient les pièces jointes, les sauvegardes internes, les caches et les uploads :
tar czf /var/backups/glpi/files-$(date +%F).tar.gz -C /var/www/glpi files/
Externaliser vers un stockage distant avec chiffrement client-side. restic ou borgbackup sont les choix open source les plus robustes. Pour restic vers un dépôt S3-compatible :
export RESTIC_REPOSITORY="s3:https://s3.exemple.com/glpi-backups"
export RESTIC_PASSWORD_FILE=/root/.restic-pw
restic backup /var/backups/glpi
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
Tester la restauration tous les trois mois sur un environnement de pré-production. Une sauvegarde jamais testée est une sauvegarde qui n’existe pas. La procédure type : restaurer un dump dans un MariaDB pré-production, restaurer files/ dans un GLPI pré-production, vérifier que les tickets et les fiches utilisateurs sont accessibles. Documentez le temps de restauration : il devient votre RTO réel et c’est lui qu’il faudra communiquer à la direction.
Étape 8 — Suivre les mises à jour de sécurité
GLPI publie régulièrement des versions de sécurité (11.0.5 en janvier 2026, 11.0.6 en mars, 11.0.7 en avril). Abonnez-vous au flux de release du projet :
- Watch sur le dépôt
glpi-project/glpisur GitHub avec l’option « Releases only » - Abonnement RSS sur le blog officiel
https://www.glpi-project.org/feed/ - Alerte hebdomadaire via Vulnerability Database (CVE Mitre, NVD NIST)
Au-delà du projet GLPI, surveillez les CVE de la pile sous-jacente : PHP, MariaDB, Apache, OpenSSL. Une faille critique sur OpenSSL ou Apache concerne directement votre instance même si GLPI n’est pas patché en parallèle.
Programmez les mises à jour mineures dans le mois suivant la sortie, après validation sur un environnement de pré-production cloné de la production. Pour les correctifs critiques (CVSS ≥ 9), la fenêtre se réduit à quelques jours.
Étape 9 — Test d’intrusion interne annuel
Toute la configuration ci-dessus suit l’état de l’art, mais l’unique manière de valider la résistance réelle est de demander à un pentester de tenter de la casser. Un test d’intrusion annuel sur GLPI couvre :
- Énumération externe et reconnaissance
- Tentatives de bypass de la 2FA
- Tentatives d’injection SQL et XSS sur les formulaires personnalisés
- Élévation de privilèges entre profils GLPI
- Accès aux fichiers de pièces jointes hors session valide
- Force brute sur l’API REST avec App-Token valide mais User Token absent
Le rapport remis identifie les failles non couvertes par les contrôles standards et oriente les correctifs prioritaires. Budgetez le test dans le forfait infogérance annuel — il coûte typiquement entre 3 et 8 jours homme d’un pentester certifié, ce qui reste modeste face au coût d’une fuite de données.
Erreurs fréquentes
| Symptôme | Cause probable | Solution |
|---|---|---|
| Fail2ban ne ban jamais | Filtre non aligné sur le format de log | Tester avec fail2ban-regex /var/www/glpi/files/_log/event.log /etc/fail2ban/filter.d/glpi.conf |
| HSTS qui bloque l’accès depuis un sous-domaine de test | preload activé trop tôt | Tester d’abord avec max-age=3600, puis monter progressivement |
| 2FA perdue, plus d’accès | Code de récupération non sauvegardé | Désactiver la 2FA depuis la base SQL en dernier recours (commande dans la doc GLPI) |
| Restauration MariaDB échoue | Version MariaDB différente entre prod et restauration | Toujours restaurer sur une version ≥ à celle qui a fait le dump |
| Log audit absent malgré la config | Permissions sur files/_log/ |
chown -R www-data:www-data /var/www/glpi/files |
Checklist de production avant ouverture aux utilisateurs
- Certificat TLS valide, score SSL Labs au moins A
- HSTS activé, en-têtes de sécurité configurés
- Fail2ban actif avec jail GLPI testée
- 2FA obligatoire pour Super-Admin et Supervisor
- Comptes par défaut désactivés ou renommés avec mots de passe forts
- Dossier
/install/supprimé - Restriction IP sur les pages admin si applicable
- Audit log activé avec rotation 90 jours minimum
- Sauvegarde quotidienne MariaDB + files/ + externalisation chiffrée
- Restauration testée au moins une fois
- Watch GitHub sur le projet glpi-project/glpi pour les releases sécurité
- Test d’intrusion planifié dans les douze mois
Articles associés
- GLPI 11 helpdesk ITIL : déployer un service desk professionnel
- Installer GLPI 11 sur Ubuntu Server 24.04 LTS
- Configurer LDAP/AD avec GLPI 11
- API REST GLPI : intégrer un script Python
Références
- Documentation sécurité GLPI
- Avis de sécurité GLPI sur GitHub
- SSL Labs — test de configuration TLS
- Fail2ban
Conformité réglementaire à anticiper
Un service desk traite presque toujours des données personnelles au sens du RGPD : nom, prénom, e-mail professionnel, parfois numéro de téléphone, parfois adresse IP des postes utilisateurs, parfois capture d’écran qui révèle des contenus métier. À ce titre, l’instance GLPI rentre dans le périmètre de votre registre des traitements et doit respecter quatre obligations minimales.
Une finalité documentée. Le registre doit mentionner explicitement que GLPI sert à traiter les incidents et demandes des collaborateurs, avec une durée de conservation des tickets (typiquement 3 ans après clôture pour les besoins d’audit). Au-delà, anonymisation ou suppression.
Un accès limité par profil. Les profils GLPI (Self-Service, Technician, Supervisor) correspondent déjà à un principe de moindre privilège. Documentez quel profil voit quelles données pour quels usages.
Une procédure de droit d’accès et d’effacement. Un collaborateur peut demander à voir ou à supprimer les données le concernant. GLPI propose un export par utilisateur dans « Administration » → « Utilisateurs » → fiche → « Exporter en CSV ». La suppression demande une attention particulière : conserver les tickets historiques anonymisés (référence interne sans nom personnel) plutôt que les supprimer purement, sinon la traçabilité opérationnelle s’effondre.
Une notification en cas de violation. En cas de fuite avérée, l’autorité de contrôle compétente doit être notifiée sous 72 heures, et les personnes concernées si le risque est élevé. Documenter à l’avance la procédure (qui contacte qui, quel modèle de notification) évite l’improvisation au pire moment.
Plan de réponse en cas d’incident de sécurité
Avoir un plan écrit avant l’incident est ce qui distingue une remédiation propre d’une débâcle improvisée. Quatre temps minimum :
- Détection et confirmation — qui identifie l’anomalie, comment, et avec quels signes (login suspect, modification non autorisée, alerte SIEM)
- Confinement — désactivation du compte compromis, blocage IP, isolation réseau de la VM GLPI si nécessaire
- Éradication et restauration — analyse de la cause racine, restauration depuis sauvegarde si compromission profonde, rotation des secrets (User Token API, App-Token, mots de passe admin)
- Retour d’expérience — réunion post-mortem dans la semaine, mise à jour des règles de détection et des procédures, partage anonymisé avec l’équipe
Ce plan tient sur une page A4. Imprimez-le et glissez-le dans le tiroir du Service Desk Manager. Le jour où un compte est compromis, personne n’a le temps d’ouvrir un wiki interne pour chercher quoi faire.