Aktuell lerne ich, was so alles bei Microsoft seit Windows NT neues dazu gekommen ist. Es ist der Updatekurs für Server 2016. Aktuell sind die Neuerungen im DNS dran. Wer bind kennt, weiss, wo die Worte her kommen. Allerdings ist das Zonenkonzept komplett unbenutzbar.
Aufgabe
Erstellen Sie für eine existierende Domain Einträge, die von einem anderen Netz aus andere Adressen zurück liefern.
Diese Aufgabe ist eine klassische Split-Brain Situation und kommt in der Praxis immer dann vor, wenn interne Server nach extern über NAT sichtbar gemacht werden sollen. Bei IPv6 gäbe es das Problem nicht, da würde eine Firewallfreigabe reichen.
Zuerst schauen wir von einem externes Gerät auf die DNS Auflösung:
PS extern> nslookup www.adatum.com
Address: 172.16.10.10
Non-authoritative answer:
Name: www.adatum.com
Address: 172.16.0.10
Und nun ändern wir das auf dem DNS Server. Zuerst wird festgelegt, dass es einen neuen Scope (Bind sagt dazu View) überhaupt gibt.
PS dns> Add-DnsServerZoneScope -ZoneName adatum.com -Name Trey
Innerhalb dieses Scopes soll es einen anderen DNS-Eintrag geben als in der Originalzone.
PS dns> Add-DnsServerResourceRecordA -ZoneName adatum.com -Name www -IPv4Address 1.2.3.4 -ZoneScope Trey
Als nächstes wird ein IP-Netz als Auswahlkriterium festgelegt.
PS dns> Add-DnsServerClientSubnet -Name TreyNet -IPv4Subnet 172.16.10.0/24
Beides zusammen definiert nun das anzuwendende Abfrageregelwerk.
PS dns> Add-DnsServerQueryResolutionPolicy -Name SplitBrain -Action ALLOW -ClientSubnet "eq,TreyNet" -ZoneScope "Trey,1" -ZoneName adatum.com
Fragt man nun von extern den Namen erneut ab, klappt es wie gewünscht.
PS ext> Clear-DnsServerCache
Confirm
This will delete all the cached records on the server and might impact performance, do you want to continue?
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): y
PS ext> Clear-DnsClientCache
PS ext> nslookup www.adatum.com
Server: UnKnown
Address: 172.16.10.10
Non-authoritative answer:
Name: www.adatum.com
Address: 1.2.3.4
Prima! Übung beendet.
Was wirklich passiert
Fragt man von extern mal andere Namen der Zone ab, so gibt es ausschließlich Fehlermeldungen:
*** UnKnown can't find lon-srv3.adatum.com: Non-existent domain
Ganz offenbar hat Microsoft mehr gemacht, als diesen einen Record zu überschreiben. Aber was genau?
Zuerst einmal fällt auf, dass es keinerlei Möglichkeit gibt, die Einträge des Scopes in der graphischen Oberfläche zu sehen. Dort schaut für den Administrator alles aus wie immer.
Man kann klicken, wo auch immer man will. Die eingerichteten Scopes und Policies bleiben unsichtbar. Das wird die Fehlersuche oder gar den operativen Betrieb sicher deutlich erschweren.
Also gehen wir per Powershell auf die Suche:
PS dns> Get-DnsServerZoneScope -ZoneName adatum.com
ZoneScope FileName
--------- --------
Adatum.com
Trey
Man muss also die Zone kennen, für die man die Scopes abfragen kann. Eine generelle Liste aller Scopes muss man sich zusammen bauen.
PS dns> Get-DnsServerQueryResolutionPolicy
Überraschung! Die generelle Liste aller Policies ist leer. Auch hier muss man wieder konkret fragen.
PS dns> Get-DnsServerQueryResolutionPolicy -ZoneName adatum.com
Name ProcessingOrder IsEnabled Action
---- --------------- --------- ------
SplitBrain 1 True Allow
Und was steht nun in der Policy genau drin? Das ist leider nicht auf diese Weise herauszubekommen!
Aber man kann wenigstens seine Kriterien auflisten.
PS dns> Get-DnsServerClientSubnet
Name IPV4Subnet IPV6Subnet
---- ---------- ----------
TreyNet {172.16.10.0/24}
Nun steht der fehlersuchende Administrator belämmert da, weil er nicht heraus bekommt, was die Policy genau tut.
Aber man kann ja mal raten:
PS dns> Get-DnsServerResourceRecord -ZoneName adatum.com
HostName RecordType Type Timestamp TimeToLive RecordData
-------- ---------- ---- --------- ---------- ----------
@ A 1 5/17/2017 1:00:00 AM 00:10:00 172.16.0.10
@ NS 2 0 01:00:00 lon-dc1.adatum.com.
@ SOA 6 0 01:00:00 [46][lon-dc1.adatum.com.][hos...
_msdcs NS 2 0 01:00:00 lon-dc1.adatum.com.
_gc._tcp.Default-First... SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][3268][LON-DC1.Adatum...
_kerberos._tcp.Default... SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][88][LON-DC1.Adatum.c...
_ldap._tcp.Default-Fir... SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][389][LON-DC1.Adatum....
_gc._tcp SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][3268][LON-DC1.Adatum...
_kerberos._tcp SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][88][LON-DC1.Adatum.c...
_kpasswd._tcp SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][464][LON-DC1.Adatum....
_ldap._tcp SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][389][LON-DC1.Adatum....
_kerberos._udp SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][88][LON-DC1.Adatum.c...
_kpasswd._udp SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][464][LON-DC1.Adatum....
DomainDnsZones A 1 5/17/2017 1:00:00 AM 00:10:00 172.16.0.10
_ldap._tcp.Default-Fir... SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][389][LON-DC1.Adatum....
_ldap._tcp.DomainDnsZones SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][389][LON-DC1.Adatum....
ForestDnsZones A 1 5/17/2017 1:00:00 AM 00:10:00 172.16.0.10
_ldap._tcp.Default-Fir... SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][389][LON-DC1.Adatum....
_ldap._tcp.ForestDnsZones SRV 33 5/17/2017 1:00:00 AM 00:10:00 [0][100][389][LON-DC1.Adatum....
LON-CL1 A 1 5/17/2017 1:00:00 AM 00:20:00 172.16.0.40
LON-CL2 A 1 11/6/2016 2:00:00 AM 00:20:00 172.16.0.41
lon-dc1 A 1 0 01:00:00 172.16.0.10
LON-HOST1 A 1 11/6/2016 9:00:00 AM 00:20:00 172.16.0.161
LON-HOST2 A 1 11/6/2016 9:00:00 AM 00:20:00 172.16.0.162
LON-NVHOST3 A 1 11/6/2016 10:00:0... 00:20:00 172.16.0.163
LON-NVHOST4 A 1 11/6/2016 10:00:0... 00:20:00 172.16.0.164
LON-RTR A 1 11/6/2016 3:00:00 AM 00:20:00 172.16.0.200
LON-SVR1 A 1 5/17/2017 1:00:00 AM 00:20:00 172.16.0.11
LON-SVR2 A 1 5/17/2017 1:00:00 AM 00:20:00 172.16.0.12
LON-SVR3 A 1 11/6/2016 2:00:00 AM 00:20:00 172.16.0.13
www A 1 0 01:00:00 172.16.0.10
Das ist doch schon mal großartig! Die Zoneninhalte werden aufgelistet.
Dann kann man bestimmt auch die Zoneninhalte aus sich des anderen Scopes ausgeben, oder?
PS dns> Get-DnsServerResourceRecord -ZoneName adatum.com -ZoneScope Trey
HostName RecordType Type Timestamp TimeToLive RecordData
-------- ---------- ---- --------- ---------- ----------
@ NS 2 0 01:00:00 lon-dc1.adatum.com.
@ SOA 6 0 01:00:00 [2][lon-dc1.adatum.com.][host...
www A 1 0 01:00:00 1.2.3.4
Ach, schau an! Es gibt also pro Scope eine komplett neue Zone.
Probleme
Die Konsequenzen sind offensichtlich: Wenn sich an der originalen Zone etwas ändert, muss der Administrator per PowerShell die entsprechenden Einträge in dem anderen Scope der Zone manuell nachpflegen. Er hat dafür keinerlei graphische Unterstützung.
Es ist sehr wahrscheinlich, dass diese Konfiguration innerhalb kürzester Zeit zu massiven Problemen führt.
Selbst für den erfahrenen Admin wird es schwierig herauszubekommen, was genau schief läuft, weil die Debuggingmöglichkeiten extrem eingeschränkt sind. Es ist mir bspw. nicht gelungen, die Konfiguration der Policies auszulesen.
PS C:\Users\Administrator> Get-DnsServerQueryResolutionPolicy -ZoneName "adatum.com" | Format-List *
Action : Allow
AppliesOn : QueryProcessing
Condition : And
Content : {DnsServerPolicyContent}
Criteria : {DnsServerPolicyCriteria}
IsEnabled : True
Level : Zone
Name : SplitBrain
ProcessingOrder : 1
ZoneName : adatum.com
PSComputerName :
CimClass : root/Microsoft/Windows/DNS:DnsServerPolicy
CimInstanceProperties : {Action, AppliesOn, Condition, Content...}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties
Wie man sieht, gibt es keine nutzbaren Details, selbst wenn man in die Tiefe geht. Ich erspare mir die ergebnislosen Versuche, die Felder Content und Criteria weiter auseinander zu dröseln.
Lösung
Aber wie geht es nun richtig?
Das Queryprocessing wird durch die Policies beeinflusst. Leider gibt es in dem betreffenden Scope nur den manuellen Eintrag in der Zone und sonst keine weiteren Einträge. Man darf also nur dann in den Scope dieser Zone wechseln, wenn man genau weiß, das diese konkrete Anfrage vorliegt.
Zuerst einmal wird die alte Policy entfernt.
PS dns> Remove-DnsServerQueryResolutionPolicy -Name SplitBrain -ZoneName adatum.com
Soweit so einfach. Und dann wird ganz überspezifisch festgelegt, was passieren soll:
PS dns> Add-DnsServerQueryResolutionPolicy -name SplitHost -ZoneName adatum.com -Fqdn "eq,www.adatum.com" -Action ALLOW -ClientSubnet "eq,TreyNet" -ZoneScope "Trey,1"
Damit wird nur dann in diesen Scope dieser Zone geschaut, wenn auch der Record genau dieser Zone von genau dem betroffenen Subnetz angefragt wird.
Und dann sollen die restlichen Einträge in dem anderen Scope der gleichen Zone abgefragt werden.
PS dns> Add-DnsServerQueryResolutionPolicy -name AllowOthers -ZoneName adatum.com -Action ALLOW -ClientSubnet "eq,TreyNet" -ZoneScope "adatum.com,2"
Die Nummer 2 gibt an, dass diese Regel als zweite auszuführen ist.
Und nun klappt es von extern auch:
PS ext> nslookup www.adatum.com
Server: UnKnown
Address: 172.16.10.10
Non-authoritative answer:
Name: www.adatum.com
Address: 1.2.3.4
PS ext> nslookup lon-svr3.adatum.com
Server: UnKnown
Address: 172.16.10.10
Non-authoritative answer:
Name: lon-svr3.adatum.com
Address: 172.16.0.13
Aber bitte, Kinder! Nicht zuhause nachmachen!