DHCP-Cluster
Im letzten Artikel „DHCP-Server Installation“ wurde ein Stand-Alone DHCP-Server aufgesetzt und grob grundkonfiguriert. Jetzt soll die Erweiterung zu einem „Cluster“ erfolgen. Ich nenne das immer gerne in Anführungsstrichen, da es meines Erachtens kein echtes Cluster ist, sondern beide DHCP-Server eigenständig IP-Adressen vergeben (welche nur nach einer Weile auf den anderen DHCP-Server repliziert werden) und eigenständig Reservierungen anlegen lassen – hier gibt es dann eine Möglichkeit, wie diese auch sauber auf dem anderen Server angelegt werden.
Vom Ablauf her:
- Weiteren DHCP-Server installieren
- DHCP-Failover konfigurieren
- AD-Benutzer anlegen & berechtigen
- Erstellen des Skripts & der Aufgabe auf DHCP01
- Skript & Aufgabe auf DHCP02 übertragen
Also los geht’s:
1. Weiteren DHCP-Server installieren
Hier gehe ich jetzt nicht in die Details, da das exakt so abläuft, wie beim o.g. Artikel des Standalone-DHCP-Servers. Der weitere DHCP-Server heißt in der Demo-Umgebung entsprechend „DHCP02“
2. DHCP-Failover konfigurieren
Nun kann direkt der DHCP-Failover eingerichtet werden. Ich mache dies immer von 1. DHCP-Server aus:
- Dazu im DHCP-Manager einen Rechtsklick auf „IPv4“ machen und im Kontextmenü „Configure Failover“ auswählen
- Im Assistenten werden als erstes die Scopes ausgewählt, welche auf den 2. DHCP-Server repliziert werden sollen. In meinem Fall gibt es nur einen Scope.
- Danach wird der Partnerserver ausgewählt.
- Anschließend kann man folgende Einstellungen – sofern notwendig – anpassen:
- „Relationship Name“
- „Maximum Client Lead Time“
- „Mode“
- Load Balance
- Hot Standby
- „State Switchover Intervall“
- „Enable Message Authentication“
- Wenn angehakt, dann bei „Shared Secret“ etwas eintragen. Hier reicht eine lange Zeichenfolge aus Zahlen, Groß-/Kleinbuchstaben aus. Ich hatte schon mal den Fall, dass komplexe Sonderzeichen zu Problemen geführt haben.
- Mit Klick auf „Finish“ wird die Einrichtung vorgenommen.
Hier beide Modi im direkten Vergleich:
Auf die Frage, welche Einstellungen nun bei Punkt 4 vorzunehmen sind, kann ich nur folgende Aussage (übersetzt mit Google-Translator) zitieren, denn besser hätte ich es auch nicht beschreiben können:
Wenn DHCP1 von Client 1 aufgefordert wird, ihm eine Adresse zu leasen, wird Client 1 eine Adresse für 10 Stunden geleast (MCLT), anstatt eine Adresse für 8 Tage zu leasen. DHCP1 informiert dann DHCP2, dass Client 1 eine Adresse geleast hat. DHCP2 kann die Details von Client 1 zu seiner DHCP-Datenbank hinzufügen.
DHCP server – State Switchover Interval, Maximum Client Lead Time? What options do I need? – Microsoft Q&A
Während eines Ausfalls von DHCP1 wendet sich Client 1 an DHCP1, um ihm eine Adresse zu leasen. DHCP1 vermietet eine Adresse für 10 Stunden (basierend auf MCLT). Wenn Client 1 nach 10 Stunden versucht, DHCP1 zu kontaktieren. (Bei 50 % von MCLT sendet Client1 einen Unicast an DHCP1, um die Lease zu erneuern. DHCP1 antwortet nicht, da es ausgefallen ist. Bei 87 % von MCLT sendet der Client eine Sendung, um seine Lease zu erneuern.) Es schlägt fehl und senden Sie anschließend eine allgemeine Nachricht an einen beliebigen DHCP-Server, damit er antwortet. Dies wird von DHCP2 registriert, das erkennt, dass Client 1 eine Adresse hat, die von seinem ausgefallenen Partner unter Verwendung von MCLT bereitgestellt wurde. Dies veranlasst DHCP2, Client 1 die gleiche Adresse (192.168.1.44) für die vollen 8 Tage zu leasen und die Details zu seiner Datenbank hinzuzufügen, obwohl es noch nicht die Ausführung des gesamten Bereichs übernommen hat.
Es dauert tatsächlich 11 Stunden (Maximale Client-Vorlaufzeit – 10 Stunden + Auto State Switchover Interval – 1 Stunde), nachdem der Zustand „Kommunikation unterbrochen“ erreicht wurde, bevor DHCP2 die Ausführung des gesamten Bereichs übernimmt.
Leider werden aber neue Reservierungen, die man bspw. auf DHCP01 anlegt, nicht automatisch auch auf dem DHCP02 angelegt. Dazu kann man aber mit einfachen Mitteln eine Lösung bauen, das folgt in den nächsten Schritten
3. AD-Benutzer anlegen & berechtigen
Es wird ein Service-Account benötigt, welcher zentral verwaltet wird – also im AD – und der dann auf beiden DHCP-Servern berechtigt wird.
Dieser Service-Account wird auf beiden DHCP-Servern in der lokalen Gruppe „DHCP Administrators“ aufgenommen, sowie in der lokalen Gruppenrichtlinie (sofern nicht anderweitig in der AD geregelt) im Pfad „Computer Configuration > Windows Settings > Security Settings > Local Policies > User Rights Assignment“ die Policy „Log on as a batch job“ hinzugefügt werden.
4. Erstellen des Skripts & der Aufgabe auf DHCP01
Es wird nun im TaskScheduler eine Aufgabe erstellt. Hier einen sinnvollen Namen vergeben (bspw. „DHCP-Sync“), in den „Security Options“ den in Punkt 3 erstellten Benutzer „DEMOLABOR\SA-DHCP-Task“ hinzufügen, sowie die Option auf „Run whether user is logged on or not“ und „Run with highest privileges“ stellen.
Anschließen auf den Reiter „Triggers“ wechseln und mit „New“ einen neuen Trigger anlegen. Hierbei auf „by log“ umstellen und dieses aus dem Dropdown heraussuchen:
Microsoft-Windows-DHCP Server Events/Operational
Danach bei „User“ den in Punkt 3 erstellen Benutzer „DEMOLABOR\SA-DHCP-Task“ eintragen und auf den Reiter „XML“ wechseln. Den Haken bei „“ setzen und die Warnung mit „Yes“ bestätigen. Nun im freien großen Textfeld hinter „@UserID“ ein Ausrufezeichen setzen, sodass der logische Vergleich umgekehrt ist; siehe Vorher-Nachher-Vergleich:
<QueryList>
<Query Id="0" Path="Microsoft-Windows-Dhcp-Server/Operational">
<Select Path="Microsoft-Windows-Dhcp-Server/Operational">*[System[Security[@UserID='S-1-5-21-450352446-791334395-3255403168-2105']]]</Select>
</Query>
</QueryList>
<QueryList>
<Query Id="0" Path="Microsoft-Windows-Dhcp-Server/Operational">
<Select Path="Microsoft-Windows-Dhcp-Server/Operational">*[System[Security[@UserID!='S-1-5-21-450352446-791334395-3255403168-2105']]]</Select>
</Query>
</QueryList>
Danach bei beiden Dialogen auf den Button <OK> klicken und schon ist der Trigger angelegt.
Für den Reiter „Action“ muss vorher noch ein Skript auf der Festplatte erstellt werden. Direkt unter „C:\“ den Ordner „DHCP-Sync“ anlegen, darin die Datei „sync.ps1“, diese im Notepad bearbeiten und folgende Zeile einfügen:
Invoke-DhcpServerv4FailoverReplication -Force
Jetzt kann die Aktion festgelegt werden; dabei die Auswahl auf „Start a program“ belassen und folgendes eintragen:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
-command "C:\DHCPSync\sync.ps1"
Mit einem Klick auf <OK> wird die Aktion angelegt.
Jetzt wird im Reiter „Conditions“ bei „Power“ der erste Haken entfernt. Danach wird im Reiter „Settings“ Der Haken bei „Run task as soon as possible after a scheduled start is missed“ gesetzt und bei „Stop the task if it runs longer than:“ auf „1 minute“ gesetzt, sowie ganz unten im Dropdown auf „Queue a new instance“ gestellt.
Den Dialog mit einem Klick auf <OK> schließen und im Credential-Dialog das Kennwort des verwendeten Accounts hinterlegen.
5. Skript & Aufgabe auf DHCP02 übertragen
Auf DHCP01 die Aufgabe exportieren, nach DHCP02 übertragen und dort einfach importieren, dabei nochmal die Logindaten für den verwendeten ServiceAccount angeben.
Werden jetzt Änderungen an bspw. Reservierungen gemacht, wird das durch das Event festgestellt, daraufhin der Task angestoßen, welcher mit dem PowerShell-Befehl direkt eine sofortige Replizierung anstößt.
Hier noch der Inhalt des exportierten Tasks („DHCP-Sync.xml“).
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2023-01-31T21:19:07.1391795</Date>
<Author>DEMOLABOR\temp.admin</Author>
<Description>Starts the DHCP-Replication</Description>
<URI>\DHCP-Sync</URI>
</RegistrationInfo>
<Triggers>
<EventTrigger>
<Enabled>true</Enabled>
<Subscription><QueryList><Query Id="0" Path="Microsoft-Windows-Dhcp-Server/Operational"><Select Path="Microsoft-Windows-Dhcp-Server/Operational">*[System[Security[@UserID!='S-1-5-21-450352446-791334395-3255403168-2105']]]</Select></Query></QueryList></Subscription>
</EventTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>S-1-5-21-450352446-791334395-3255403168-2105</UserId>
<LogonType>S4U</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>Queue</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT1M</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command>
<Arguments>-command "C:\DHCPSync\sync.ps1"</Arguments>
</Exec>
</Actions>
</Task>
Achtung – kleine, aber wichtige Korrektur
Beim Task darf der Haken bei „Do not store password. The task will only have access to local computer resources“ nicht gesetzt sein, sonst läuft der Task nicht sauber durch!
Im Grunde stimmt das zwar, denn der Task führt nur ein lokales Skript aus, welches auf dem lokalen DHCP-Server die Replizierung anstößt. Aber durch den Haken scheint der darunter stehende Haken „Run with highest privileges“ quasi außer Kraft genommen zu sein.
Also: Haken raus, auf <OK> klicken und Logindaten bestätigen und schon klappt’s 😁👍
Leider funktioniert bei uns die Einstellung mit der manuellen XML nicht. Er triggert es nicht an. Wenn ich das über den normalen Weg über das Dropdown-Menü mache, läuft es. Dort kann ich natürlich keinen expliziten User angeben. Brauche ich denn unbedingt die Option mit dem User?
Du schreibst ja was von „…hinter „@UserID“ ein Ausrufezeichen setzen, sodass der logische Vergleich umgekehrt ist“ – Was macht das Ausrufezeichen bzw. was ist mit logischer Vergleich gemeint? Vielleicht hast du ja noch einen Tipp! Danke!
Hallo BK,
vielen Dank für deinen Kommentar.
Ohne das Ausrufezeichen würde der Task nur dann ausgeführt werden, wenn das Event explizit durch den hinterlegten Benutzer auftritt. Da der Task aber reagieren soll, wenn Änderungen am DHCP gemacht werden, die nicht durch diesen „Sync-User“ initiiert wurden, muss das Ausrufezeichen hin. Also aus der Logik „@UserID=’S-1-5-21-…-2105′“ wird dann die Logik „@UserID!=’S-1-5-21-…-2105′“. Zudem würde sich das sonst auch Loopen, wenn eben der „Sync-User“ das Event auslöst und der Task darauf reagiert und im Kontext des „Sync-User“ wieder etwas ausführt, worauf dann erneut der Task über das Event reagiert.
Ich hoffe, ich habe das etwas verständlicher erklären können. Falls nicht, können wir gerne mal einen kurzen Teams-Call machen und zusammen drüberschauen.
Viele Grüße und eine schöne Woche!
Ronny
Danke für die Anleitung. Man kann es auch noch etwas vereinfachen in dem man direkt -command „Invoke-DhcpServerv4FailoverReplication -Force“ bei den Argumenten einträgt und sich die ps1 spart. 🙂
Hallo EinLeser,
vielen Dank für deine Rückmeldung 😉
Ja, das stimmt; diese Variante habe ich auch in verschiedenen Blogs gesehen, allerdings habe ich bei PS/CMD-Tasks hin & wieder das Problem gehabt, dass eine direkte Befehlsübergabe bei Argumenten nicht funktioniert hat 🤷🏼♂️ Deswegen habe ich das über ein PS1-File umgesetzt, denn das funktionierte bei mir bisher immer.
Viele Grüße
Ronny 😉