GLPI-Sicherheit: Hardening und Best Practices

Praxis-Checkliste für das Hardening von GLPI im Produktivbetrieb: Webroot in public/, Nginx-Virtual-Host, Sicherheits-Header, Secure-Session-Cookie hinter einem Proxy, Berechtigungen, Konten und SQL-Diagnose – direkt aus dem Betrieb von NexTool-Umgebungen.

In diesem Artikel8 Abschnitte

Ein GLPI fällt selten durch einen Zero-Day. Es fällt durch einen vergessenen Installer, einen Webroot im falschen Verzeichnis und ein Session-Cookie ohne Flag Secure hinter dem Proxy. Dieser Leitfaden ist die Checkliste, die wir beim Betrieb von Kundenumgebungen anwenden: die Befehle, der Virtual Host und die Diagnoseabfragen, mit denen wir die Angriffsfläche eines produktiven GLPI schließen.

Wie ein GLPI tatsächlich kompromittiert wird

Beim Betrieb von Dutzenden Umgebungen wiederholt sich ein Muster: Die Kompromittierung kommt fast nie durch eine exotische Schwachstelle im Core. Sie kommt durch Konfiguration. Die vier Angriffsvektoren, die wir am häufigsten finden, sind in dieser Reihenfolge: (1) install/install.php, nach dem Deployment nie entfernt; (2) DocumentRoot zeigt auf die Wurzel der Installation statt auf public/, wodurch files/_log/ und Konfigurations-Backups als Text abrufbar sind; (3) Standard-Zugangsdaten (glpi/glpi) sind noch aktiv; und (4) TLS endet am Reverse Proxy, während ein Backend reines HTTP spricht und ein Session-Cookie ohne Secure unterwegs ist. Keiner dieser Punkte braucht einen Exploit, nur ein curl. Beginnen Sie Ihr Audit, indem Sie genau dies testen:

# Instalador ainda no ar? (esperado: 404)
curl -s -o /dev/null -w "%{http_code}\n" https://glpi.cliente.com.br/install/install.php

# Log de erros exposto? (esperado: 403/404, NUNCA 200 com conteúdo)
curl -s https://glpi.cliente.com.br/files/_log/php-errors.log | head

# Backup de config vazando credencial do banco? (esperado: nada)
curl -s https://glpi.cliente.com.br/config/config_db.php.bak | head

Wenn einer dieser Aufrufe Inhalt zurückliefert, stoppen Sie alles: Ihre Umgebung ist jetzt exponiert, und die Behebung hat oberste Priorität.

1. Schließen Sie die Angriffsfläche: Webroot in public/ und keine Installationsreste

  1. Lassen Sie DocumentRoot (bzw. root in Nginx) auf /var/www/glpi/public zeigen, niemals auf /var/www/glpi. Seit GLPI 10 darf nur Ordner public/ als Webroot dienen.
  2. Entfernen Sie install/install.php nach Abschluss von Installation oder Upgrade. Ein Upgrade legt diese Datei neu an: Der häufige Fehler ist, GLPI zu aktualisieren und zu vergessen, sie erneut zu entfernen.
  3. Stellen Sie sicher, dass config/, files/ sowie jede .bak- oder .git-Datei außerhalb der Reichweite des Webservers liegen.

2. Virtual Host: richtige Wurzel, Header und nur index.php führt PHP aus

Seit GLPI 10 gilt: Alles wird über public/index.php geroutet, und keine andere .php-Datei darf direkt ausgeführt werden. Dies ist der Server-Block, den wir in Nginx als Grundlage verwenden:

# /etc/nginx/sites-available/glpi.conf
server {
    listen 443 ssl;
    http2 on;
    server_name glpi.cliente.com.br;

    root /var/www/glpi/public;   # nunca /var/www/glpi
    index index.php;

    ssl_certificate     /etc/letsencrypt/live/glpi.cliente.com.br/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/glpi.cliente.com.br/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    # Cabeçalhos de segurança
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    location / {
        try_files $uri /index.php$is_args$args;
    }

    # Somente o index.php roteia PHP
    location ~ ^/index\.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    # Qualquer outro .php: negar
    location ~ \.php$ {
        return 404;
    }
}

In Apache entspricht dem DocumentRoot /var/www/glpi/public mit einem eingeschränkten Block <Directory> und denselben Headern über Header set. Ein Hinweis aus der Praxis: Aktivieren Sie Strict-Transport-Security (HSTS) erst, wenn Ihr Zertifikat zu 100 % funktioniert. Mit aktivem HSTS und fehlerhaftem TLS sperren Sie die gesamte Domain im Browser der Benutzer für die Dauer von max-age.

3. Session und Cookies: die stille Lücke hinter dem Proxy

Dieser Befund wird am häufigsten übersehen. Wenn TLS am Proxy (Nginx/HAProxy) endet und GLPI im Backend über HTTP läuft, muss ein Session-Cookie weiterhin als Secure und HttpOnly markiert sein. Erzwingen Sie unter Einrichten > Allgemein in der Registerkarte Sicherheit sichere Cookies und eine Passwortrichtlinie (Mindestlänge, Komplexität, Ablauf). Ohne diese Einstellung läuft jedes Session-Cookie über den internen HTTP-Abschnitt ohne Secure, und es genügt, den Datenverkehr in diesem Segment mitzuschneiden, um die Session eines angemeldeten Technikers zu übernehmen. Passen Sie außerdem die Lebensdauer der Session an ein Maß an, welches zum Risiko Ihrer Umgebung passt, statt den langen Standardwert zu belassen.

4. Konten und Authentifizierung

Ändern Sie sofort die Passwörter von glpi, tech, normal und post-only, oder deaktivieren Sie ungenutzte Konten. Führen Sie diese Diagnose direkt in der Datenbank aus, um zu ermitteln, was noch von lokalen Passwörtern (authtype = 1) abhängt und für MFA/SSO oder Deaktivierung in Frage kommt:

-- Contas padrão do GLPI ainda ativas
SELECT name, is_active, last_login
FROM   glpi_users
WHERE  name IN ('glpi','tech','normal','post-only');

-- Todas as contas com senha LOCAL ativa (authtype = 1)
-- authtype: 1=local  2=mail  3=LDAP  4=externa  5=CAS
SELECT id, name, is_active, last_login
FROM   glpi_users
WHERE  authtype = 1 AND is_active = 1
ORDER  BY last_login;

Unsere Empfehlung für den Produktivbetrieb: SSO (Azure AD/Entra ID oder ein anderer Anbieter) mit MFA und lokale Anmeldung beschränkt auf ein einziges Notfallkonto (Break-Glass) mit starkem Passwort, in einem Tresor verwahrt. Der Core von GLPI hat weder natives MFA noch eine Sperre nach Fehlversuchen: Für MFA nutzen Sie ein geeignetes Plugin oder Ihr SSO; gegen Brute Force stellen Sie GLPI hinter fail2ban, welches Zugriffslogs des Proxys auswertet. Lesen Sie auch unseren Leitfaden zu SSO mit Azure AD/Entra ID.

5. Berechtigungen: Code nur lesbar, Schreibzugriff nur wo nötig

Ein einfaches Prinzip: Der Benutzer von PHP-FPM (www-data) soll Code lesen, aber niemals schreiben können. Einziger beschreibbarer Baum ist GLPI_VAR_DIR. So kann selbst eine Schwachstelle in der Anwendung keinen Schadcode im ausgelieferten Verzeichnis ablegen.

VerzeichnisRolleBesitzer:GruppeSchreibzugriff www-data
/var/www/glpiCode + Webroot public/root:www-dataNein (750 / 640)
/etc/glpiKonfiguration (config_db.php)root:www-dataNein (750 / 640)
/var/lib/glpiGLPI_VAR_DIR (files, Cache, Sessions)www-data:www-dataJa (750)
/var/log/glpiAnwendungslogswww-data:www-dataJa (750)

config/ und files/ aus dem Webroot auszulagern (über GLPI_CONFIG_DIR und GLPI_VAR_DIR) ist unser Standardlayout: Wird der Webroot eines Tages versehentlich exponiert, gehen Konfiguration und Daten nicht mit.

6. Updates und kontinuierliches Monitoring

Halten Sie Ihre Version aktuell. Für die meisten CVEs von GLPI gibt es bereits einen Patch, wenn sie in den Nachrichten auftauchen; das eigentliche Risiko ist eine Umgebung, die drei Versionen zurückliegt. Überwachen Sie Authentifizierungsversuche (Spitzen bei fehlgeschlagenen Anmeldungen deuten auf Brute Force hin) in Zabbix/Grafana und verfolgen Sie die CVEs der installierten Version. Dafür nutzen wir Modul CVE Scan, welches die GLPI-Version mit bekannten CVEs abgleicht und Punkte der Umgebung prüft. Und betreiben Sie Hardening nicht ohne Wiederherstellungsplan: Lesen Sie unseren Leitfaden zu Backup und Disaster Recovery.

Häufige Fehler, die wir im Betrieb sehen

  • Konfigurations-Backup im Webroot: Jemand speichert config_db.php.bak vor einer Änderung; da .bak nicht von PHP ausgeführt wird, liefert der Server die Datenbank-Zugangsdaten im Klartext aus.
  • Überlebender Legacy-Alias: Der neue vhost zeigt auf public/, aber ein alter Alias /glpi exponiert weiterhin die Wurzel.
  • HSTS vor dem Zertifikat: HSTS bei unvollständigem TLS zu aktivieren sperrt die Domain im Browser der Benutzer.
  • Lokale Anmeldung ohne Break-Glass deaktiviert: Man schaltet lokale Anmeldung ab, verlässt sich zu 100 % auf SSO, und wenn SSO ausfällt, kommt niemand mehr als Admin hinein.

Einmal umgesetzt ist dies einfach; es in Dutzenden Kundenumgebungen aufrechtzuerhalten, während wiederkehrende Upgrades install/ neu anlegen, ist Betriebsarbeit. Genau dies macht NexTool: Der GLPI-Betrieb von NexTool validiert den Webroot, härtet den Virtual Host, prüft Berechtigungen und führt diese Prüfroutine als Teil des Wartungszyklus aus.


Geprüft vom Team von NexTool Solutions.

Häufig gestellte Fragen

Führen Sie einen curl auf /install/install.php, /files/_log/php-errors.log und /config/config_db.php.bak aus. Erwartet wird 403 oder 404; jede Antwort 200 mit Inhalt bedeutet eine Exposition. Ursache ist fast immer ein DocumentRoot, der auf die Wurzel der Installation statt auf public/ zeigt.

Es funktioniert, ist aber unsicher. Mit der falschen Wurzel werden Dateien wie files/_log/ und Konfigurations-Backups als Text vom Webserver ausgeliefert. Seit GLPI 10 ist public/ der einzig richtige Webroot, weil er index.php vom Rest der Installation isoliert.

Nicht im Core. Stellen Sie GLPI hinter fail2ban, welches Zugriffslogs des Reverse Proxys auswertet, oder nutzen Sie SSO/MFA, um die Angriffsfläche zu verkleinern. Überwachen Sie parallel in Zabbix oder Grafana Spitzen bei fehlgeschlagenen Anmeldungen, ein typisches Anzeichen für einen Brute-Force-Angriff.

Aktivieren Sie unter Einrichten > Allgemein in der Registerkarte Sicherheit sichere Cookies; stellen Sie sicher, dass der Proxy X-Forwarded-Proto weiterleitet und GLPI erkennt, dass es unter HTTPS läuft. Ohne Flag Secure läuft ein Session-Cookie über den internen HTTP-Abschnitt und kann in diesem Segment mitgeschnitten werden.

Nicht nativ im Core. Nutzen Sie ein MFA-Plugin (TOTP) oder SSO mit Azure AD/Entra ID oder Okta, die MFA bereits mitbringen. Behalten Sie immer ein lokales Notfallkonto (Break-Glass) mit starkem Passwort, damit Sie den administrativen Zugang nicht verlieren, wenn SSO ausfällt.

Brauchen Sie Hilfe?