Table of Contents
- Technisches Implementierungshandbuch: PHP-basierte Active Directory-Verwaltung mit IIS auf Windows Server 2025
- Zusammenfassung
- Teil 1: Einrichtung der Basisinfrastruktur (IIS, PHP & FastCGI)
- 1.1 Installation der IIS-Serverrolle
- 1.2 Installation der PHP-Laufzeitumgebung
- 1.3 Konfiguration von IIS für PHP (Handler Mapping)
- 1.4 Konfiguration der „Default Web Site“
- 1.5 Validierung der Basisinstallation
- Teil 2: Konfiguration der Host-Dienste (SNMP & Active Directory)
- 2.1 Aktivierung und Konfiguration des SNMP-Dienstes
- 2.2 Vorbereitung von Active Directory (OU und Dienstkonto)
- Teil 3: Konfiguration von Secure LDAP (LDAPS) auf dem Domänencontroller
- Teil 4: Erweiterte PHP-Konfiguration (LDAP und SNMP aktivieren)
- 4.1 Bearbeitung der php.ini
- 4.2 Aktivierung der PHP-Erweiterungen
- 4.3 Behebung von Windows-spezifischen DLL-Abhängigkeiten
- 4.4 Konfiguration von PHP für LDAPS-Vertrauensstellung
- Schritt 1: Root-CA-Zertifikat exportieren
- Schritt 2: OpenLDAP-Konfigurationsverzeichnis erstellen
- Schritt 3: ldap.conf konfigurieren
- 4.5 Überprüfung der geladenen Module
- Teil 5: Die PowerShell-Automatisierungsebene
- 5.1 Skript für einzelne Benutzererstellung (Create-ADUser.ps1)
- 5.2 Skript für CSV-Massenimport (Bulk-Create-ADUsers.ps1)
- Teil 6: Sicherheitsarchitektur (IIS, PHP und PowerShell)
- 6.1 Analyse des Sicherheitsproblems
- 6.2 Konfiguration der IIS-Anwendungspool-Identität
- 6.3 Delegierung von AD-Berechtigungen
- 6.4 PowerShell-Ausführungsrichtlinie
- 6.5 Dateisystemberechtigungen (NTFS)
- Teil 7: Implementierung der PHP-Anwendungslogik
- 7.1 Modul 1: Administrator-Authentifizierung (LDAP-Login)
- 7.2 Modul 2: Server-Monitoring (SNMP)
- 7.3 Modul 3: Einzelne Benutzererstellung
- 7.4 Modul 4: CSV-Massenimport
- Teil 8: Abschließendes Sicherheits-Audit und Risikobewertung
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Technisches Implementierungshandbuch: PHP-basierte Active Directory-Verwaltung mit IIS auf Windows Server 2025
Zusammenfassung
Dieses Dokument beschreibt die detaillierte, produktionsreife Implementierung einer PHP-Webanwendung auf einem Windows Server 2025 Datacenter, die über die Internet Information Services (IIS) bereitgestellt wird.
Die Anwendung erfüllt folgende hoch privilegierte Aufgaben:
- Authentifizierung von Administratoren über LDAP
- Abfrage von Servermetriken über SNMP
- Erstellung von Active-Directory-(AD)-Benutzern (einzeln und als CSV-Massenimport)
Die AD-Benutzererstellung wird durch die sichere Ausführung von PowerShell-Skripten aus PHP heraus realisiert. Die Skripte verarbeiten sowohl Einzelbenutzer als auch CSV-Massenimporte.
Der Schwerpunkt dieses Handbuchs liegt auf der Konfiguration einer robusten und sicheren Architektur nach dem Least-Privilege-Prinzip, um Risiken durch Web-basierten Zugriff auf AD und Serverdienste zu minimieren.
Teil 1: Einrichtung der Basisinfrastruktur (IIS, PHP & FastCGI)
Dieser Abschnitt legt das Fundament für die Webanwendung durch die Installation und Konfiguration des Webservers und der PHP-Laufzeitumgebung auf einem sauberen Windows Server 2025.
1.1 Installation der IIS-Serverrolle
- Öffnen des Server-Managers.
- Auswahl von Verwalten → Rollen und Features hinzufügen.
- Im Assistenten zur Seite Serverrollen navigieren.
- Webserver (IIS) auswählen.
- Im erscheinenden Pop-up auf Features hinzufügen klicken.
- Zur Seite Rollendienste fortfahren.
- Unter Webserver → Anwendungsentwicklung den Knoten erweitern.
- Das Kontrollkästchen CGI aktivieren.
Technische Erläuterung:
Die Auswahl von CGI ist entscheidend. Diese Option installiert nicht nur klassisches CGI, sondern auch das moderne FastCGI-Modul, das für die performante und stabile Anbindung von PHP an IIS erforderlich ist. Ohne FastCGI kann IIS nicht mit php-cgi.exe kommunizieren.
- Den Assistenten abschließen und die Installation abwarten.
1.2 Installation der PHP-Laufzeitumgebung
Die Installation von PHP erfolgt manuell, da der Web Platform Installer (WPI) nicht mehr unterstützt wird.
Voraussetzung: Visual C++ Redistributable
PHP unter Windows benötigt das Microsoft Visual C++ 2015–2022 Redistributable (x64).
- Neueste x64-Version von Microsoft herunterladen: vc_redist.x64.exe.
- Installation ausführen und abschließen.
PHP-Download
- Zur offiziellen Download-Seite für PHP unter Windows wechseln: PHP
- Die x64 Non-Thread Safe (NTS) Version der gewünschten PHP-Version (z.B. PHP 8.4) im Zip-Format auswählen.
Technische Erläuterung:
Die NTS-Version ist für den Betrieb mit IIS + FastCGI optimiert. FastCGI übernimmt das Prozess-Pooling, daher ist Thread-Safety in PHP selbst nicht erforderlich. Die Verwendung einer Thread-Safe-Version (TS) kann hier zu Performance- und Stabilitätsproblemen führen.
PHP-Installation
- Ein Verzeichnis für PHP erstellen, z.B.:
C:\PHP - Das heruntergeladene ZIP-Archiv nach
C:\PHPentpacken.
1.3 Konfiguration von IIS für PHP (Handler Mapping)
Nun muss IIS angewiesen werden, wie .php-Dateien behandelt werden. Dies erfolgt über eine Handler-Zuordnung.
-
IIS-Manager starten (
inetmgr). -
Im linken Bereich Verbindungen den Servernamen (oberste Ebene) auswählen.
-
Im mittleren Bereich auf Handlerzuordnungen doppelklicken.
-
Im rechten Bereich unter Aktionen auf Modulzuordnung hinzufügen… klicken.
-
Felder wie folgt ausfüllen:
- Anforderungspfad:
*.php - Modul:
FastCgiModule - Ausführbare Datei:
C:\PHP\php-cgi.exe(Pfad ggf. anpassen) - Name: z.B.
PHP via FastCGI
- Anforderungspfad:
-
Mit OK bestätigen.
-
Die Nachfrage, ob eine FastCGI-Anwendung angelegt werden soll, mit Ja bestätigen.
1.4 Konfiguration der „Default Web Site“
- Im IIS-Manager im linken Bereich Websites erweitern.
- Rechtsklick auf Default Web Site → Verwalten der Website → Erweiterte Einstellungen…
- Die Eigenschaft Physischer Pfad suchen.
- Den Standardpfad (z.B.
%SystemDrive%\inetpub\wwwroot) ändern auf denpublic-Ordner des Projekts, z.B.:
C:\Web\AdAdminPanel\public - Mit OK bestätigen.
Ab jetzt leitet IIS Anfragen an http://localhost/ in das Verzeichnis C:\Web\AdAdminPanel\public.
1.5 Validierung der Basisinstallation
-
Eine neue Textdatei
phpinfo.phpin
C:\Web\AdAdminPanel\publicerstellen. -
Folgenden Inhalt einfügen:
<?php phpinfo(); -
Im Browser
http://localhost/phpinfo.phpaufrufen.
Wenn alles korrekt ist, erscheint die PHP-Info-Seite mit allen Konfigurationsdetails.
Wichtig:
Den Wert bei Loaded Configuration File (php.ini) Path notieren. Dieser Pfad ist wichtig für die Konfiguration in Teil 3.
Sicherheit:
Die Datei phpinfo.php nach der Validierung wieder löschen.
Teil 2: Konfiguration der Host-Dienste (SNMP & Active Directory)
Bevor die PHP-Anwendung konfiguriert wird, müssen die Zieldienste auf dem Server (SNMP) und in der Domäne (Active Directory) vorbereitet werden.
2.1 Aktivierung und Konfiguration des SNMP-Dienstes
Installation des SNMP-Dienstes
Unter Windows Server 2025 erfolgt die Installation bevorzugt über PowerShell:
Install-WindowsFeature SNMP-Service,SNMP-WMI-Provider -IncludeManagementTools
Konfiguration des SNMP-Dienstes
services.mscöffnen.- Den Dienst SNMP Service suchen und Eigenschaften öffnen.
Registerkarte „Agent“:
- Optional Kontakt und Standort eintragen.
- Unter Dienst passende Kategorien aktivieren (z.B. Physisch, Anwendungen, Internet).
Registerkarte „Sicherheit“ (kritischer Schritt):
- Unter Akzeptierte Communitynamen → Hinzufügen…
- Rechte: SCHREIBGESCHÜTZT (READ ONLY)
- Community-Name, z.B.
public_ro(nichtpublicverwenden).
- Unter SNMP-Pakete von diesen Hosts annehmen → Hinzufügen…
127.0.0.1eintragen.
Technische Erläuterung:
Die Beschränkung auf 127.0.0.1 stellt sicher, dass nur lokale Prozesse (z.B. PHP) den SNMP-Dienst abfragen können. Anfragen anderer Hosts werden verworfen.
Den SNMP-Dienst nach der Konfiguration neu starten.
2.2 Vorbereitung von Active Directory (OU und Dienstkonto)
Organisationseinheit (OU) erstellen
- Active Directory-Benutzer und -Computer (
dsa.msc) öffnen. - Rechtsklick auf die Domäne → Neu → Organisationseinheit.
- Namen vergeben, z.B.
WebAppUsers.
Diese OU dient als isolierter Container für alle Benutzer, die über die PHP-Anwendung erstellt werden. Dort wird später die Rechte-Delegierung vorgenommen.
Dienstkonto (Service Account) erstellen
- Einen neuen Standard-Domänenbenutzer erstellen, z.B.:
- Benutzername:
svc_iis_php_ad
- Benutzername:
- Keiner administrativen Gruppe (z.B. Domänen-Admins) hinzufügen.
- Ein langes, komplexes Kennwort vergeben (25+ Zeichen).
- Kontooptionen:
- Kennwort läuft nie ab aktivieren.
- Benutzer kann Kennwort nicht ändern aktivieren.
- Benutzer muss Kennwort bei der nächsten Anmeldung ändern deaktivieren.
Dieses Konto wird später als Identität des IIS-Anwendungspools verwendet.
Teil 3: Konfiguration von Secure LDAP (LDAPS) auf dem Domänencontroller
Standard-LDAP (Port 389) überträgt Anmeldeinformationen unverschlüsselt. Für eine Produktionsumgebung ist die Aktivierung von LDAPS (LDAP über SSL, Port 636) zwingend erforderlich.
- Voraussetzung: SSL-Zertifikat
LDAPS funktioniert nur, wenn der Domänencontroller (DC) ein gültiges SSL-Zertifikat besitzt. Dieses Zertifikat muss für den Zweck "Serverauthentifizierung" ausgestellt sein und der FQDN des Domänencontrollers (z. B. dc01.yourdomain.com) muss im Antragstellernamen (Subject Name) oder Alternativen Antragstellernamen (SAN) enthalten sein. - Empfohlene Methode: Active Directory-Zertifikatdienste (AD CS)
Die einfachste und robusteste Methode zur Bereitstellung dieses Zertifikats ist die Installation der Active Directory-Zertifikatdienste (AD CS)-Rolle auf dem Server.- Den Server-Manager auf dem DC öffnen.
- Verwalten > Rollen und Features hinzufügen auswählen.
- In der Rollenauswahl Active Directory-Zertifikatdienste anklicken.
- Im Assistenten für Rollendienste mindestens Zertifizierungsstelle aktivieren.
- Abschluss der Installation und die anschließende Konfiguration der Rolle abwarten ("Unternehmens-CA" auswählen).
- Nach der Installation und Konfiguration erhält der Domänencontroller (oder alle DCs in der Domäne, abhängig von der Konfiguration) automatisch ein gültiges Zertifikat von der neuen internen Zertifizierungsstelle.
- Automatische Aktivierung von LDAPS
Sobald ein gültiges Zertifikat im persönlichen Zertifikatspeicher des Domänencontrollers vorhanden ist, beginnt der AD-Dienst (LSASS.exe) automatisch, auf den LDAPS-Ports zu lauschen:- TCP 636 (für LDAPS)
- TCP 3269 (für LDAPS zum globalen Katalog)
- Verifizierung der LDAPS-Verbindung (auf dem DC)
ldp.exestarten (ein AD-Verwaltungstool).- Danach Verbindung > Verbinden... auswählen.
- Server: FQDN des DCs eingeben (z. B. dc01.yourdomain.com).
- Port: 636
- Kontrollkästchen SSL aktivieren.
- Auf OK klicken.
- Wenn die Verbindung erfolgreich ist, werden die RootDSE-Informationen im rechten Fensterbereich angezeigt. Dies bestätigt, dass der Server LDAPS-Verbindungen akzeptiert.
Teil 4: Erweiterte PHP-Konfiguration (LDAP und SNMP aktivieren)
Nun werden die PHP-Erweiterungen aktiviert, die für LDAP-Authentifizierung und SNMP-Abfragen benötigt werden.
4.1 Bearbeitung der php.ini
- Zum PHP-Installationsverzeichnis wechseln, z.B.
C:\PHP. - Falls keine
php.iniexistiert:php.ini-productionnachphp.inikopieren.
php.inimit einem Editor (z.B. Notepad++ als Administrator) öffnen.
4.2 Aktivierung der PHP-Erweiterungen
-
In der
php.ininachextension_dirsuchen und sicherstellen, dass es auf dasext-Verzeichnis zeigt:extension_dir = "ext" -
Folgende Zeilen aktivieren (Semikolon am Zeilenanfang entfernen):
extension=ldap extension=snmp extension=openssl
- ldap: für Administrator-Authentifizierung via LDAP
- snmp: für SNMP-Abfragen (Servermetriken)
- openssl: u.a. für LDAPS (LDAP über SSL/TLS)
4.3 Behebung von Windows-spezifischen DLL-Abhängigkeiten
Erweiterungen wie php_ldap.dll benötigen zusätzliche DLLs (z.B. libsasl.dll, libcrypto-*.dll, libssl-*.dll), die sich im PHP-Stammverzeichnis befinden.
Typische Symptome:
- In
phpinfo()fehlen die Sektionenldapodersnmp. - In der Ereignisanzeige oder in IIS-Logs erscheinen PHP-Startwarnungen.
Lösung (Best Practice):
- Systemsteuerung → System → Erweiterte Systemeinstellungen.
- Umgebungsvariablen… öffnen.
- Unter Systemvariablen die Variable
Pathbearbeiten. - Neu:
C:\PHPhinzufügen. - Alle Fenster mit OK schließen.
Erforderlicher Schritt:
- Vollständigen Neustart des Servers durchführen
oder zumindest die Dienste W3SVC und WAS neu starten, damit der IIS-Prozessw3wp.exeden aktualisiertenPATHübernimmt.
4.4 Konfiguration von PHP für LDAPS-Vertrauensstellung
Das Aktivieren von extension=ldap allein reicht nicht aus, um LDAPS mit einer internen Zertifizierungsstelle zu verwenden. Hintergrund ist, dass PHP unter Windows nicht auf den Windows-Zertifikatspeicher zugreift. Ohne zusätzliche Konfiguration führt dies bei LDAPS-Verbindungen zu dem Fehler „Unknown CA“. Damit PHP der internen Zertifizierungsstelle vertraut, muss das Root-Zertifikat manuell in einer separaten OpenLDAP-Konfigurationsstruktur hinterlegt werden.
Schritt 1: Root-CA-Zertifikat exportieren
- Auf einem beliebigen domänenangehörigen System
mmc.exestarten. - Datei → Snap-In hinzufügen/entfernen… auswählen.
- Zertifikate hinzufügen → Computerkonto → Lokaler Computer.
- Zu Vertrauenswürdige Stammzertifizierungsstellen → Zertifikate navigieren.
- Das Stammzertifikat der internen CA auswählen.
- Rechtsklick → Alle Aufgaben → Exportieren….
- Format Base-64-codiert X.509 (.CER) wählen.
- Das Zertifikat z. B. als
C:\InternalRootCA.cerspeichern.
Schritt 2: OpenLDAP-Konfigurationsverzeichnis erstellen
- Auf dem IIS-Server das folgende Verzeichnis anlegen:
C:\openldap\sysconf\ - Die exportierte Datei
InternalRootCA.cerin dieses Verzeichnis kopieren. - Im selben Verzeichnis eine Datei ldap.conf anlegen.
Schritt 3: ldap.conf konfigurieren
C:\openldap\sysconf\ldap.confmit einem Editor öffnen.- Folgende Zeile eintragen (Dateiname ggf. anpassen):
4.5 Überprüfung der geladenen Module
phpinfo.phperneut aufrufen.- Mit
Strg+Fnachldapundsnmpsuchen.
Sind separate Konfigurationsblöcke für ldap und snmp sichtbar, wurden die Module korrekt geladen.
Tabelle 1: Erforderliche PHP-Erweiterungen und Abhängigkeiten
| Erweiterung | php.ini-Eintrag |
Wichtige DLLs (im PHP-Stammverzeichnis) | Zweck |
|---|---|---|---|
| LDAP | extension=ldap |
libsasl.dll, libcrypto-*.dll, libssl-*.dll |
Administrator-Authentifizierung (Login) |
| SNMP | extension=snmp |
(i.d.R. keine zusätzlichen DLLs) | Abfrage von Serverinformationen (CPU, RAM, Uptime) |
| OpenSSL | extension=openssl |
libcrypto-*.dll, libssl-*.dll |
LDAPS/HTTPS-Funktionalität |
Teil 5: Die PowerShell-Automatisierungsebene
Die AD-Operationen werden über PowerShell-Skripte ausgeführt, die als sichere, parametrisierte Schnittstelle zwischen PHP und Active Directory dienen.
Pfad für Skripte:
C:\Web\AdAdminPanel\scripts\powershell\
5.1 Skript für einzelne Benutzererstellung (Create-ADUser.ps1)
# C:\Web\AdAdminPanel\scripts\powershell\Create-ADUser.ps1
param(
[Parameter(Mandatory=$true)][string]$Username,
[Parameter(Mandatory=$true)][string]$Password,
[Parameter(Mandatory=$true)][string]$GivenName,
[Parameter(Mandatory=$true)][string]$Surname,
[Parameter(Mandatory=$true)][string]$OUPath
)
try {
Import-Module ActiveDirectory -ErrorAction Stop
# Kritisch: Konvertierung des Klartext-Passworts in einen SecureString
$SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
$userParams = @{
Name = "$GivenName $Surname"
GivenName = $GivenName
Surname = $Surname
SamAccountName = $Username
UserPrincipalName = "$Username@yourdomain.com" # "yourdomain.com" anpassen
AccountPassword = $SecurePassword
Path = $OUPath
Enabled = $true
ChangePasswordAtLogon = $true
}
New-ADUser @userParams
Write-Output "Erfolg: Benutzer $Username wurde in der OU $OUPath erstellt."
}
catch {
Write-Error "Fehler bei der Benutzererstellung für $Username: $($_.Exception.Message)"
exit 1
}
5.2 Skript für CSV-Massenimport (Bulk-Create-ADUsers.ps1)
# C:\Web\AdAdminPanel\scripts\powershell\Bulk-Create-ADUsers.ps1
param(
[Parameter(Mandatory=$true)][string]$CsvPath,
[Parameter(Mandatory=$true)][string]$OUPath
)
$domainSuffix = "@yourdomain.com" # Anpassen
try {
Import-Module ActiveDirectory -ErrorAction Stop
# Erwartete Spalten: SamAccountName, GivenName, Surname, Password
$users = Import-Csv -Path $CsvPath
if ($null -eq $users) {
Write-Warning "Die CSV-Datei unter $CsvPath ist leer oder konnte nicht gelesen werden."
exit 0
}
foreach ($user in $users) {
try {
$SecurePassword = ConvertTo-SecureString -String $user.Password -AsPlainText -Force
$userParams = @{
Name = "$($user.GivenName) $($user.Surname)"
GivenName = $user.GivenName
Surname = $user.Surname
SamAccountName = $user.SamAccountName
UserPrincipalName = "$($user.SamAccountName)$domainSuffix"
AccountPassword = $SecurePassword
Path = $OUPath
Enabled = $true
ChangePasswordAtLogon = $true
}
New-ADUser @userParams
Write-Output "Erfolg (Bulk): Benutzer $($user.SamAccountName) wurde erstellt."
}
catch {
Write-Warning "Fehler bei Benutzer $($user.SamAccountName): $($_.Exception.Message)"
}
}
Write-Output "Massenimport abgeschlossen."
}
catch {
Write-Error "Schwerwiegender Fehler beim Massenimport: $($_.Exception.Message)"
exit 1
}
Teil 6: Sicherheitsarchitektur (IIS, PHP und PowerShell)
Die größte Herausforderung ist die sichere Verbindung zwischen der IIS-Webanwendung (niedrige Vertrauensstellung) und Active Directory (hohe Vertrauensstellung).
6.1 Analyse des Sicherheitsproblems
shell_exec() in PHP wird im Sicherheitskontext des IIS-Anwendungspool-Benutzers ausgeführt. Standardmäßig ist dies ein virtuelles Konto wie IIS APPPOOL\DefaultAppPool mit sehr wenigen Rechten. Dieses Konto darf weder:
- das AD-PowerShell-Modul nutzen,
- noch AD-Objekte erstellen,
- noch sich an Domänencontrollern authentifizieren.
Falsche Lösung: Dem AppPool Domänen-Admin-Rechte geben → massive Sicherheitslücke.
Korrekte Lösung: Verwendung des dedizierten Dienstkontos svc_iis_php_ad (Least Privilege) und gezielte Rechte-Delegierung.
6.2 Konfiguration der IIS-Anwendungspool-Identität
- IIS-Manager öffnen.
- Anwendungspools auswählen.
- Rechtsklick → Anwendungspool hinzufügen…
- Name:
PHP_AD_AppPool - .NET CLR-Version: Kein verwalteter Code
- Name:
- Auf die Website (z.B. Default Web Site) wechseln → Basis-Einstellungen… bzw. Standardeinstellungen… und den Anwendungspool auf
PHP_AD_AppPoolumstellen. - In der Liste der Anwendungspools:
PHP_AD_AppPoolmarkieren → Erweiterte Einstellungen…- Unter Prozessmodell → Identität → Benutzerdefiniertes Konto auswählen.
- Festlegen… → Anmeldeinformationen für
IHREDOMÄNE\svc_iis_php_adeintragen.
Ab jetzt läuft der AppPool im Kontext des Dienstkontos.
6.3 Delegierung von AD-Berechtigungen
- Auf einem Domänencontroller
dsa.mscöffnen. - Rechtsklick auf OU WebAppUsers → Objektverwaltung zuweisen…
- Im Assistenten:
- Weiter → Hinzufügen… → Konto
svc_iis_php_adauswählen. - Weiter → Eine benutzerdefinierte Aufgabe zum Zuweisen erstellen.
- Objekttyp: Nur die folgenden Objekttypen im Ordner → Benutzerobjekte aktivieren.
- Berechtigungen:
- Diese Objekte im Ordner erstellen (ggf. auch löschen).
- Alle Eigenschaften schreiben
- Kennwort zurücksetzen
- Kennwort ändern
- Weiter → Hinzufügen… → Konto
Ergebnis:
svc_iis_php_ad kann nur Benutzerobjekte innerhalb der OU WebAppUsers erstellen/ändern – und sonst nichts.
6.4 PowerShell-Ausführungsrichtlinie
Standardmäßig gilt Restricted. Statt die Richtlinie global zu ändern, wird sie pro Aufruf übergangen mit:
-ExecutionPolicy ByPass -NoProfile
Dies wird in den PHP-Skripten beim Aufruf von powershell.exe verwendet.
6.5 Dateisystemberechtigungen (NTFS)
Dem Dienstkonto svc_iis_php_ad werden nur die minimal erforderlichen NTFS-Rechte gewährt:
C:\PHP→ Lesen & AusführenC:\Web\AdAdminPanel\public→ LesenC:\Web\AdAdminPanel\scripts\powershell→ Lesen & AusführenC:\Web\AdAdminPanel\storage\uploads→ Ändern/Schreiben (für CSV-Uploads)C:\openldap\sysconf→ Lesen (damit es die ldap.conf und die .cer-Datei lesen kann)
Teil 7: Implementierung der PHP-Anwendungslogik
Die folgenden PHP-Dateien liegen im Web-Stammverzeichnis, z.B.:
C:\Web\AdAdminPanel\public
7.1 Modul 1: Administrator-Authentifizierung (LDAP-Login)
Datei: login.php
<?php
// login.php
session_start();
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Domänencontroller und Domäne anpassen
$ldap_server = "ldap://dc01.yourdomain.com";
$domain = "@yourdomain.com";
// Anmeldung mit UPN
$ldap_user_dn = $_POST['username'] . $domain;
$ldap_pass = $_POST['password'];
$ldap_conn = ldap_connect($ldap_server);
if (!$ldap_conn) {
$error = "Fehler: Verbindung zum LDAP-Server fehlgeschlagen.";
} else {
ldap_set_option($ldap_conn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap_conn, LDAP_OPT_REFERRALS, 0);
// @ unterdrückt Warnungen bei fehlerhaftem Login
if (@ldap_bind($ldap_conn, $ldap_user_dn, $ldap_pass)) {
$_SESSION['admin_user'] = $ldap_user_dn;
header("Location: dashboard.php");
exit;
} else {
$error = "LDAP-Bind fehlgeschlagen: Ungültiger Benutzername oder Passwort.";
}
ldap_close($ldap_conn);
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Admin Login</title>
</head>
<body>
<h2>Admin Login</h2>
<?php if ($error): ?>
<p style="color:red;"><?php echo htmlspecialchars($error); ?></p>
<?php endif; ?>
<form method="post" action="login.php">
Benutzername: <input type="text" name="username"><br>
Passwort: <input type="password" name="password"><br>
<input type="submit" value="Anmelden">
</form>
</body>
</html>
7.2 Modul 2: Server-Monitoring (SNMP)
Diese Seite (dashboard.php) zeigt die Serverinformationen an, die über die in Teil 4 aktivierte SNMP-Erweiterung und den in Teil 2 konfigurierten Dienst abgerufen werden.
Tabelle 2: Wichtige SNMP-OIDs für die Windows Server-Überwachung
| Metrik | OID | Beschreibung |
|---|---|---|
| CPU-Last | .1.3.6.1.2.1.25.3.3.1.2 | (HOST-RESOURCES-MIB) Durchschnittliche CPU-Auslastung der letzten Minute (pro CPU-Kern). Dies ist eine Tabelle; ein snmpwalk ist erforderlich, um alle Kerne zu erhalten.59 |
| Gesamter RAM | .1.3.6.1.2.1.25.2.3.1.5 | (hrStorageSize) Größe der Speichereinheiten. Muss mit hrStorageDescr (z. B. "Physical Memory") korreliert werden.63 |
| Genutzter RAM | .1.3.6.1.2.1.25.2.3.1.6 | (hrStorageUsed) Genutzte Speichereinheiten. Muss ebenfalls korreliert werden.63 |
| System Uptime | .1.3.6.1.2.1.25.1.1.0 | hrSystemUptime (in Timeticks). |
Datei: dashboard.php
<?php
// dashboard.php
session_start();
if (!isset($_SESSION['admin_user'])) {
header("Location: login.php");
exit;
}
// SNMP-Konfiguration
$community = 'public_ro';
$host = '127.0.0.1';
snmp_set_quick_print(true);
snmp_set_oid_output_format(SNMP_OID_OUTPUT_NUMERIC);
// CPU-Last (erster Kern, Beispiel)
$cpu_oid = '.1.3.6.1.2.1.25.3.3.1.2.1';
$cpu_load = @snmpget($host, $community, $cpu_oid, 1000000, 2);
// System Uptime
$uptime_oid = '.1.3.6.1.2.1.25.1.1.0';
$uptime_raw = @snmpget($host, $community, $uptime_oid);
$uptime = $uptime_raw ? ($uptime_raw / (100 * 60 * 60 * 24)) . " Tage" : "Fehler";
// RAM (statisches Beispiel mit Index 5)
$ram_total_oid = '.1.3.6.1.2.1.25.2.3.1.5.5';
$ram_used_oid = '.1.3.6.1.2.1.25.2.3.1.6.5';
$ram_alloc_units_oid = '.1.3.6.1.2.1.25.2.3.1.4.5';
$ram_total_raw = @snmpget($host, $community, $ram_total_oid);
$ram_used_raw = @snmpget($host, $community, $ram_used_oid);
$ram_units = @snmpget($host, $community, $ram_alloc_units_oid);
if ($ram_total_raw && $ram_used_raw && $ram_units) {
$ram_total_gb = ($ram_total_raw * $ram_units) / (1024 ** 3);
$ram_used_gb = ($ram_used_raw * $ram_units) / (1024 ** 3);
$ram_percent = ($ram_used_gb / $ram_total_gb) * 100;
}
?>
<h2>Admin Dashboard</h2>
<p>Angemeldet als: <?php echo htmlspecialchars($_SESSION['admin_user']); ?></p>
<h3>Server-Status (SNMP)</h3>
<p>CPU-Last (Kern 1): <?php echo $cpu_load ?: "Fehler bei Abfrage"; ?>%</p>
<p>System Uptime: <?php echo $uptime; ?></p>
<p>RAM-Auslastung:
<?php echo isset($ram_percent) ? number_format($ram_percent, 2) . "%" : "Fehler bei Abfrage"; ?>
</p>
<hr>
<p><a href="create_single_user.php">Einzelnen Benutzer erstellen</a></p>
<p><a href="bulk_create_users.php">Benutzer per CSV importieren</a></p>
7.3 Modul 3: Einzelne Benutzererstellung
Datei: create_single_user.php
<?php
// create_single_user.php
session_start();
if (!isset($_SESSION['admin_user'])) {
header("Location: login.php");
exit;
}
$output = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$ps_script = 'C:\\Web\\AdAdminPanel\\scripts\\powershell\\Create-ADUser.ps1';
if (empty($_POST['username']) || empty($_POST['password'])) {
$output = "Fehler: Benutzername und Passwort sind erforderlich.";
} else {
// Kritisch: Maskierung aller Shell-Argumente (Schutz vor Command Injection)
$username = escapeshellarg($_POST['username']);
$password = escapeshellarg($_POST['password']);
$givenname = escapeshellarg($_POST['givenname']);
$surname = escapeshellarg($_POST['surname']);
$oupath = escapeshellarg("OU=WebAppUsers,DC=yourdomain,DC=com");
$command = "powershell.exe -ExecutionPolicy ByPass -NoProfile -File $ps_script " .
"-Username $username -Password $password -GivenName $givenname " .
"-Surname $surname -OUPath $oupath";
// STDERR nach STDOUT umleiten (2>&1)
$output = shell_exec($command . " 2>&1");
}
}
?>
<h2>Neuen AD-Benutzer erstellen</h2>
<form method="post" action="create_single_user.php">
Benutzername (SamAccountName): <input type="text" name="username"><br>
Temporäres Passwort: <input type="text" name="password"><br>
Vorname: <input type="text" name="givenname"><br>
Nachname: <input type="text" name="surname"><br>
<input type="submit" value="Benutzer erstellen">
</form>
<?php if ($output): ?>
<h3>Ausgabe:</h3>
<pre><?php echo htmlspecialchars($output); ?></pre>
<?php endif; ?>
7.4 Modul 4: CSV-Massenimport
Datei: bulk_create_users.php
<?php
// bulk_create_users.php
session_start();
if (!isset($_SESSION['admin_user'])) {
header("Location: login.php");
exit;
}
$output = '';
if (isset($_FILES['user_csv'])) {
$upload_dir = 'C:\\Web\\AdAdminPanel\\storage\\uploads\\';
$temp_csv_path = $upload_dir . uniqid('users_') . '.csv';
if (move_uploaded_file($_FILES['user_csv']['tmp_name'], $temp_csv_path)) {
$ps_script = 'C:\\Web\\AdAdminPanel\\scripts\\powershell\\Bulk-Create-ADUsers.ps1';
$csv_path_arg = escapeshellarg($temp_csv_path);
$oupath_arg = escapeshellarg("OU=WebAppUsers,DC=yourdomain,DC=com");
$command = "powershell.exe -ExecutionPolicy ByPass -NoProfile -File $ps_script " .
"-CsvPath $csv_path_arg -OUPath $oupath_arg";
$output = shell_exec($command . " 2>&1");
// Temporäre CSV mit Klartext-Passwörtern löschen
unlink($temp_csv_path);
} else {
$output = "Fehler beim Hochladen der Datei.";
}
}
?>
<h2>AD-Benutzer per CSV-Massenimport erstellen</h2>
<p>Die CSV-Datei muss die Spaltenüberschriften <code>SamAccountName</code>, <code>GivenName</code>, <code>Surname</code> und <code>Password</code> enthalten.</p>
<form method="post" action="bulk_create_users.php" enctype="multipart/form-data">
CSV-Datei auswählen: <input type="file" name="user_csv" accept=".csv"><br>
<input type="submit" value="Import starten">
</form>
<?php if ($output): ?>
<h3>Import-Ergebnis:</h3>
<pre><?php echo htmlspecialchars($output); ?></pre>
<?php endif; ?>
Teil 8: Abschließendes Sicherheits-Audit und Risikobewertung
Die Lösung ist mächtig, aber sensibel, da sie eine Brücke zwischen Web und Active Directory bildet. Die folgenden Risiken und Gegenmaßnahmen sind zentral:
Risiko: Command Injection
Beschreibung:
Ein Angreifer könnte versuchen, über Formulare Befehle einzuschleusen, z.B.:
username; Remove-ADUser -Identity 'Administrator'
Gegenmaßnahme:
- Konsequente Verwendung von
escapeshellarg()für alle Parameter, die anpowershell.exeübergeben werden. - Dadurch werden Eingaben als einzelne, harmlose Zeichenkette behandelt und nicht als eigenständiger Befehl interpretiert.
Risiko: Eskalation von Berechtigungen
Beschreibung:
Eine Schwachstelle in der PHP-Anwendung könnte genutzt werden, um die Rechte des Webserverkontos zu missbrauchen.
Gegenmaßnahme:
- AppPool läuft als
svc_iis_php_admit minimal notwendigen Rechten. - AD-Delegierung beschränkt das Konto auf das Erstellen/Ändern von Benutzern in der OU
WebAppUsers. - Keine Mitgliedschaft in administrativen Gruppen, kein Zugriff auf andere OUs oder Systeme.
Risiko: Klartext-Passwörter
Beschreibung:
- Passwörter liegen im Klartext in Formularen und CSV-Dateien vor.
- Übergabe an PowerShell erfolgt im Klartext.
- Temporäre CSV-Dateien enthalten Klartext-Passwörter auf der Festplatte.
Gegenmaßnahmen:
- HTTPS erzwingen: Die gesamte Weboberfläche muss über TLS gesichert werden.
- Schnelle Konvertierung: PowerShell wandelt Klartext-Passwörter sofort in
SecureStringum. - Löschung der CSV-Dateien: Temporäre CSV-Dateien werden nach der Verarbeitung gelöscht (
unlink()). - Passwortwechsel erzwingen:
ChangePasswordAtLogon = $truezwingt Benutzer zur Passwortänderung bei der ersten Anmeldung.
Risiko: Fehlende Fehlerbehandlung
Beschreibung:
- PowerShell-Fehler (z.B. Kennwort-Komplexität) landen auf STDERR, das von
shell_exec()standardmäßig ignoriert wird.
Gegenmaßnahme:
- Anhängen von
2>&1an alle Befehle imshell_exec()-Kontext, damit Fehlermeldungen im$output-String landen und im Webinterface angezeigt werden können.
Ende des Dokuments