Showing posts with label dns. Show all posts
Showing posts with label dns. Show all posts

Sunday, August 20, 2023

Splitting AD integrated reverse DNS zones

If you have an environment with a reverse dns zone that was created with broad network range, you may decided at a later point in time that you want to split the zone. The reasons for this might be: ease of management in terms of loading the zone in the dns management console, easier to find records, requring differences in record age and scavenging control, etc. For a zone that is AD integrated, it will be in one of 3 partitions (domain partion, domaindns partition, or forestdns partition). You can adjust the code to the appropriate distinguishedname of the zone. Distinguishednames can be retrieved using get-dnsserverzone and reading the distinguishedname property on the returned object.

When it comes to splitting the zone, there's a few things to remember with AD integrated DNS. All records are objects under a zone object. Making changes in the dns management console doesn't mean objects in AD will automatically be deleted or migrated for you. You can end up in situations where hidden old records still exist in ldap, but don't show up in the dns management console. This code example below will help guide you in extracting the records you want and putting them in a new ldap dns zone object, along with preserving the data, timestamps, and permissions on the objects.

This example below is splitting of all 10.1.x.x records from a 10.x.x.x reverse zone. Before running your modified code, create your new reverse dns zone, then stop the dns server on the domain controller that you are making this change on.


get-adobject -searchbase "DC=10.in-addr.arpa,CN=MicrosoftDNS,DC=DomainDnsZones,DC=Contoso,DC=Com" -ldapfilter "(objectclass=dnsnode)" | 
    where {$_.name -match "\.1$"} | 
    move-adobject -targetpath "DC=1.10.in-addr.arpa,CN=MicrosoftDNS,DC=DomainDnsZones,DC=Contoso,DC=Com"
 

get-adobject -searchbase "DC=1.10.in-addr.arpa,CN=MicrosoftDNS,DC=DomainDnsZones,DC=Contoso,DC=Com" -ldapfilter "(objectclass=dnsnode)" | 
  where {$_.name -match "\.1$"} | %{

               $newname = $_.name.replace(".1","")
               $_ | rename-adobject -newname $newname
              
  }
Once this completes, start the dns server service to force rereading of ldap information. Dns zone reload is not sufficient. Other domain controllers should not require restart of dns service as they pick up the changes as it replicates. Test this in a lab environment first and run at your own risk.

Wednesday, July 18, 2018

Browser video problem, media_error_unknown, ssl_error_rx_record_too_long

My wife recent brought her macbook to me with a problem that suddenly popped up. Pretty much every website that had embedded video in it, other than youtube, was suddenly not working. The media player plugins were showing various errors, one of which was media_error_unknown. I opened chrome's developer tools for a better look at the errors. There were a few that indicated there might be a plugin or extension that was causing problems with some of the content. I tried disabling a few extensions like ad blockers and other security related plugins to see if that helped, but it didn't. I found some suggestions that pointed to proxies, but no proxy was configured. Avast was doing some web filtering, but turning that off didn't help either. Checked a few other browsers besides chrome and all had the same issue. When opening the media's link directly, it gave a browser "site is insecure" type of ssl error page. Lastly I thought dns would be a good place to check as our home wifi pushes out cleanbrowsing.org's dns servers. Usually these filtering companies redirect blocked ssl to some other ssl site that would have an invalid cert. So after switching her dns to static with google's 8.8.8.8, everything was up and running again. So likely it was a mistaken classification of a content delivery network that cause this problem for news web sites and other normal content sites.

Thursday, September 21, 2017

Reverse CNAME lookup with dns cmdlets

In case you ever get the request to find any alias that points to a server (or list of servers), you can use the DNS commandlets to build a list of results on a zone by zone basis to further dig through.  This command will give you a rough list with 3 attributes:

Hostname = name of the dns record
ShortAlias = non-fqdn of the DNS record data (where the CNAME points to)
Alias = full DNS record data

I put the short name in there just in case the information provided to you is a short server name.

$zone = "contoso.com"
$recs = get-DnsServerResourceRecord -zonename $zone -rrtype cname |
    select @{name="shortalias"; expr={
        $_.recorddata.hostnamealias -replace "\..*",""}}, @{name="alias";
        expr={$_.recorddata.hostnamealias}},hostname

This will give you the full list of cname data for the zone in an array of objects.  If what you are searching for is an array, just run it through a loop in one of two ways [example of matching short names against an array of names to search for]

foreach ($name in $list) {  $recs | where {$_.shortalias -match $name} }

or

foreach ($entry in $recs) { if ($list -contains $entry.shortalias) { $entry } }

Its not super clean, but it will display the records.  You can modify the loops to collect the data in an array.  You could even run an extra outer loop to hit multiple zones.  The $list can just be a copy and paste into powershell from excel or whatever the list comes in.

$list = "
".split("`n")

Make sure when you paste, you don't end up with the " on a new line at the end like it shows above.  If you do that, the first loop example will dump out the whole $recs array on the last entry in $list.

If you don't have access to the Dns cmdlets, but you have rights to pull the zone with dnscmd, you can do something like this:

dnscmd /zoneprint | where {$_ -match "CNAME"} | 
  % {$resline = $_ -split "\s+"; ($resline[0], $resline[3]) }

You'll have to do something with the two values at the end, which are record name and record data.

Tuesday, December 27, 2016

Fixing dns record permissions for dynamic dns

In case you have dns records that need to be changed from static to dynamic, or the machine/clusters that will be updating them have changed, you can modify the dns record permissions to allow updates.  Doing this through the gui is fine for a few records, but if you need something a bit more simple and automated, you can try this script.  It takes both the computer name (doesn't have to match the dns record, just needs to be a computer object), and the dns record (fqdn) that you are updating.  This script will work for AD dns only, and would be limited to the current domain, and likely any forest wide partitions.  If you check my article on managing other domains in powershell, you can probably get edits to other domains working on this with a few modifications and extra parameters.



param (
  $computername,
  $dnsrecord
)

$script:computernameSam = $computername + "$"

try {
  import-module activedirectory
} catch {
  write-error "This script requires the AD powershell module"
  exit
}
while ( (test-path -path Ad:) -ne $true  )
{
  start-sleep -seconds 2
}

#Standard ACL for a dynamic dns entry
  #ActiveDirectoryRights : CreateChild, DeleteChild, ListChildren, ReadProperty, DeleteTree, ExtendedRight, Delete,
  #                        GenericWrite, WriteDacl, WriteOwner
  #InheritanceType       : None
  #ObjectType            : 00000000-0000-0000-0000-000000000000
  #InheritedObjectType   : 00000000-0000-0000-0000-000000000000
  #ObjectFlags           : None
  #AccessControlType     : Allow
  #IdentityReference     : Domain\machine$
  #IsInherited           : False
  #InheritanceFlags      : None
  #PropagationFlags      : None
# 

function get-partition {
  param ( $record )
  #need to split off everything after first name to find longest zone match
  #using get-dnsserverzone ($name)
  
  $dnsrecordparts = $record.split(".")
  
  for ($i = 1; $i -lt $dnsrecordparts.length; $i++) {
    $zonenameTest = $dnsrecordparts[$i..($dnsrecordparts.length -1)] -join "."
    $zoneObj = get-dnsserverzone $zonenameTest -ea 0
    if ($zoneObj -ne $null) {
    write-output -inputobject $zoneobj
    $i = $dnsrecordparts.length + 1
    }
  }
  
}

function get-dnsobject {
  param ($record)
  $zoneObject = get-partition -record $record
  if ($zoneObject -ne $null) {
    $zonename = $zoneObject.zonename
    $record -match "(.*)(\.$zonename)"
    $dnsRecordDN = "dc=" + $matches[1] + "," + $zoneobject.distinguishedname
     try {
       get-adobject  $dnsRecordDN
    } catch { Throw "Unable to find dns record for this machine"}
  } else { throw "DNS zone not found"}
}

try {
  try {
    $guid = [guid]'00000000-0000-0000-0000-000000000000'
    $adcomputer = get-adcomputer $computername -property objectsid
    $sid = $adcomputer.objectsid
    $ctrl = [System.Security.AccessControl.AccessControlType]::Allow
    $rights = 983423
    $intype =[System.DirectoryServices.ActiveDirectorySecurityInheritance]::None
    $rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($sid,$rights,$ctrl,$guid)
  } catch { throw "Unable to get computer account SID" }

  try {
    #find record
    $dnsDN = get-dnsObject -record $dnsrecord
  } catch { throw $_ }
  
  try {
    $acl = get-acl ad:"$($dnsDN.distinguishedname)"
    $acl.setowner([system.security.principal.ntaccount]"$script:computernameSam")
    $acl.AddAccessRule($rule)
    Set-Acl -acl $acl -path ad:"$($dnsDN.distinguishedname)"
  } catch { throw $_ }

} catch { $_}

Wednesday, December 21, 2016

DNS - limited forwarding delegated subdomain (in AD integrated zone)

If you find yourself in need to creating subdomains off of an existing AD integrated zone, which forward externally, you may encounter the problem that not all AD dns servers can access an external set of servers. To limit the domain controllers that do dns forwarding, while still allowing all dc's to know how to resolve records, you can combine delegated subdomains and conditional forwarders (non-AD integrated).

Example:

-Organization has AD integrated zone Contoso.com on all AD domain controllers.
-Organization is outsourcing dns for subdomain hosting.contoso.com to external domain name servers
-Only 2 out of 50 domain controllers can access external dns for name resolution.  All others do general forwarding to these 2 domain controllers.

Problem:
1) If we create a delegation in contoso.com directly to the external dns servers, recursion is not available and name resolution is not going to happen.
2) if we create AD integrated conditional forwarding for the subdomain, all servers will try to forward to external dns and will be unable to do so, causing queries to fail

Solution:
-Create a subdomain delegation in contoso.com using only the name servers of the 2 internal domain controllers that have access to forward dns queries to external servers
-Create non-AD integrated conditional forwarders for hosting.contoso.com on these same 2 servers, which use the dns server IP's of the external dns provider
-On the external provider, set up a dns zone for hosting.contoso.com

Wednesday, March 12, 2014

Parsing DNS Debug logs (microsoft)

I have played around a few times with methods of parsing the ugly data lines that come with Microsoft DNS Server's DNS debug log. Due to the differences in types of queries, there is no fixed number of "columns" defined by spaces. Since this is the delimiter, it causes issues in parsing. Besides that, there is the messed up hostnames in the query values that replace the periods with a parenthesis and length of chars in the following value. As logs can get quite large, trying to parse these with powershell can have mixed results. Sometimes it works ok, other times you watch the process grow to several GB of memory utilization and nothing is happening. So, to find a better way, I thought I would dust off the old Unix Shells by Example book and use some gnuwin32 versions of grep, awk and sed to take care of this file. In order to get down to the raw information that I care about, I'm looking at queries received by the server, the source IP, type of record being searched, and the hostname being looked up. To get this I came up with this to transform to csv output:


&nbsp&nbsp&nbspgrep.exe Rcv c:\temp\dns.log |grep " Q " | gawk -v OFS="," "{print $8,$14,$15}"| sed -n "s/([0-9]*)/./gp"|sed -n "s/\,\./,/gp"|sed -n "s/\.$//gp"

The $8,$14,$15 numbers represent text columns and you may need to adjust this based on output. Also the number of columns may be inconsistent as the data that shows up between the brackets is not always consistent in the log. You can use notepad++ to do a regex find/replace using \[.*\] to clear this out first. Once columns are aligned this output can be dumped to the script, but if you try to put a redirector to dump to text, it will do it, however it seems grep will give you an infinite loop of errors.  So to work around that, you can split this up into two commands.

First use grep:
&nbsp&nbsp&nbspgrep.exe Rcv c:\temp\dns.log |grep " Q " > temp.txt

Then:
&nbsp&nbsp&nbspgawk -v OFS="," "{print $8,$14,$15}" temp.txt | sed -n "s/([0-9]*)/./gp" | sed -n "s/\,\./,/gp" | sed -n "s/\.$//gp" >output.csv


If you want to add the name of the dns server, you can put an extra sed command right before the output rediection
&nbsp&nbsp&nbspsed -n "s/^/%computername%,/gp"
if you run it locally, otherwise put in text or some other defined variable there


Additionally you can play with the output, such as looking for source IP's
&nbsp&nbsp&nbspawk -v FS="," "{print $1}" output.csv|sort |uniq -c
To get a list of unique client IP's and number of queries


Don't try to run this in powershell. Run in cmd or as a bat file, collect the csv and then you can import to powershell to play around with grouping or whatever you might want to do to see client behavior or records being queried.  If your file is large (I was testing with 200MB), you still won't want to try import-csv in powershell or your machine will grind to a halt.

You can use powershell to try to convert your source IP addresses to hostnames with reverse dns. Copy the text, dump to a variable, split by new-line, run through a foreach loop with: [net.dns]::GetHostByAddress($_).hostname

Additional reference and tools:
1) Gnuwin32 utilities, *nix tools for windows:  http://gnuwin32.sourceforge.net
2) Parsing logs other DNS logs  http://isc.sans.edu/diary/A+Poor+Man%27s+DNS+Anomaly+Detection+Script/13918
3) Reasons why this can be important: https://media.defcon.org/DEF%20CON%2021/DEF%20CON%2021%20video%20and%20slides/DEF%20CON%2021%20Hacking%20Conference%20Presentation%20By%20Robert%20Stucke%20-%20DNS%20May%20Be%20Hazardous%20to%20Your%20Health%20-%20Video%20and%20Slides.m4vhttps://www.youtube.com/watch?v=yQqWzHKDnTI

Monday, October 24, 2011

Migrating a lot of zones from Microsoft DNS to BIND

In my last post, I gave some solutions to migrating zones from Microsoft DNS to BIND dns zones. If you have a lot of zones, you may be wondering if there is an easy way to run these steps on all of them to migrate the whole configuration. Well with dnscmd and some basic scripting, that is just adding a few more minutes of work.

When you want to see all of your zones:

dnscmd [dnsserver] /enumzones

will list out every zone on the server. The format needs some work though, and you will need to ignore the header and footer output for the command. The rest comes out in the format of Zone Type Partition Options, with no standardization to the whitespacing between them. Since the zone happens to be what we need, we can easily extract that and use it for follow on commands.

If we want to export our zone's to files, we can try this in powershell:

$zones = dnscmd $dnsserver /enumzones
for ($i = 7; $i -lt ($zones.length -3); $i++) {
$zonename = $zones[$i].substring(1)
$zonename = $zonename.substring(0,$zonename.indexof(" "))
$file = $zonename[$i] + ".txt"
dnscmd $dnsserver /exportzone $zonename $file
}

This will go through all the output, strip out the zone names and export them all to a text file named after the zone name. You could use this same method as a way to backup records if you have issues with them being deleted, or zones going missing. Here I started at the 7th line of output, which should bypass all of the headers and ignore the first zone, which will likely be the "." zone. You can check where you want to start by looking at the lines of the $zone array before doing a loop. We end 3 lines short of the end of the output to skip the footer information.

Alternatively if you were to go with the secondary zone on BIND method, you could use dnscmd to set up the allow zone transfer and provide the BINDS server's IP. While doing this and the above example, you could even throw in extra output to file using the zone name to build all of the BIND config file's entries for the new zones (primary or secondary).

In any case, to use dnscmd to set an IP for zone transfers:

dnscmd [dnsservername] /zoneresetsecondaries /Securelist [secondary dns server ip]

If you are running this on a lot of zones and you don't want to do this to all of them, find another method. This will reset the existing settings on the zone.

These examples are just a few ways to do this. There may be some existing powershell cmdlets available that will accomplish some of these tasks. For obtaining a list of zones, and better filtering/handling of them, you could also take a look at doing this with: Get-wmiobject -namespace root\microsoftdns -class microsoftdns_zone -computer [remote dns server name].

Migrating Windows DNS to Linux BIND

Recently I have encountered several people who were trying to do DNS migrations between operating systems for various reasons. I thought it would be nice to put together a good tutorial on this. If you search around you will find other answers, most of which tell you to pull the DNS text file from a windows machine and copy it over to Linux. That works if you have a non-active directory integrated DNS zone and the file is already there. I wouldn't suggest trying to convert an AD integrated zone that is used in production to a primary non-AD integrate zone just to do a migration. There are two good ways to get a zone file that BIND can use.

1) Export the zone from windows.
dnscmd [dns server name] /exportzone [zone name] [file name]
This command will export all the zone records into a text file and put it in the %windir%\system32\dns folder.

2) On your Linux machine, create secondary zones for your Windows zones. On the Windows machine, allow zone transfer to the Linux machine. Once the transfer is done, you will have a text copy of the zone file that you can modify and reuse as a master zone.

Example Linux machine 10.1.3.2 and windows machine 10.1.3.10






In both cases, you will need to do some editing to the zone file. You need to update the SOA information and the NS record


Change these values to the name of your BIND server. Place the zone file where BIND can read it, and update your named.conf or related include file to host the zone as a master. Reload BIND and you will be hosting DNS there.

There are always more considerations to a migration than this. You need to consider what IP addresses the clients use for nameservers. If they were pointing to the server you are migrating away from, you may want to do a IP address swap on your servers as a last step of the transfer. Besides clients, you need to be concerned with domain name registration services pointing to the appropriate servers that manage your registered domain names, as well as any DNS forwarders being used. If you are using dynamic dns and you have a lot of registrations from DHCP clients, migrating them as-is would cause their records to now become static.  So you want to look at cleaning up your zone file of this type of entry prior to migration if you want to continue with dynamic dns in the BIND server.  Another big concern is for Active Directory environments. It is not recommended to go away from Microsoft DNS when using active directory due to the large number of records that are required to make that function properly. Failing to keep up with all of the manual changes can greatly impact your AD environment. One method to help avoid some of the headache would be to use both, and leave the _msdcs zone on your windows system. This will require some delegations to be put in place on the BIND server.

Wednesday, May 18, 2011

Windows 2008R2 failing to update DDNS records

If you are running an environment with dynamic DNS, record scavenging, and 2008R2 servers; you may notice records disappearing from time to time. There is a bug in 2008 that causes systems to fail to maintain their records if you make changes to the DNS server IP's that the system uses. If you run ipconfig /registerdns, it forces the system to update and all is well. If you want to get around having this problem with a more permanent solution, Microsoft released this patch recently (kb 2520155).

Tuesday, August 10, 2010

Finding the distinguishedName of an AD integrated DNS zone

As a precursor to some work I want to do for standard users to be able to create DNS records in AD integrated zones, I threw together some started code to find the actual location of a DNS zone. If you read my previous post looking at DNS without the DNS protocol, I mentioned the various places zones can be located. When you have more than one domain in a forest, this increases the number of possible places to look. This sample code is a basic starter for looking at anything outside of specialized application partitions, to find a specified zone inside the current forest.
#get-dnspartition
#
#Searches different paritions for the distinguished name of a dns zone
#V1.0  Aug 2010.  Checks the forest dns, domain dns and legacy domain dns locations for the existence of a zone
#and returns the distinguished name of all results.
#
# Future work possibilities.  Looking for application partitions.  Working with reverse zones in a way that does
# more of a wildcard search to get a better match when the network ID is unknown or scope of the reverse zone is unknown.  
#Search capability for subzones that are in the same parent zone
# object.  In AD these just show up as part of the record's Name attribute..recordname.subzone

#note, some partitions may not allow authenticated users read access to view the base cn=microsoftDNS containers
#but opening the parent container and doing a subtree search for the zone bypasses this restriction.


$zonename = $args[0]

$forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$mytopleveldomain = $forest.schema.name
$mytopleveldomain = $mytopleveldomain.substring($mytopleveldomain.indexof("DC="))
 
$Arrmyresults = @()

function search-dns-partition($partion, $domainDN, $zonename) {
 $de = new-object DirectoryServices.DirectoryEntry("LDAP://" + $partition + $domaindn)
 $ds = new-object DirectoryServices.DirectorySearcher($de)
 $ds.filter = "(&(objectclass=dnszone)(name=" + $zonename + "))"
 $fu = $ds.findone()
 if ($fu -ne $null) { 
  return $fu.properties.distinguishedname 
 } else { return $null }
}

function dns-to-dn ([string]$dnsname) {
  #may 09
  
  #this is a helper function which will convert a dns name to a distinguished name dc= 
  #type of result by breaking off each piece of the dns name to become a DC entry
  
  $domainDNnamearr = $dnsname.split(".")
  $domainDNname = ""
    
  foreach ($component in $domainDNnamearr) {
     $domainDNname = $domainDNname + "DC=" + $component + ","
  }
  $domainDNnamearr = $null
     
  #remove trailing , off
  $domainDNname = $domainDNname.substring(0,$domainDNname.length -1)
  return $domainDNname

}

#check domain and domain legacy partitions
foreach ($dom in $forest.domains) {
 foreach ($partition in ("cn=System,", "dc=domaindnszones,")) {
  $domainDNval = dns-to-dn $dom.name
  $myresult = search-dns-partition $partition $domainDnVal $zonename
  if ($myresult -ne $null) {
   $Arrmyresults += $myresult
  }
 } 
}

#Check forest partition
$myresult = search-dns-partition "dc=forestdnszones" $mytopleveldomain $zonename
if ($myresult -ne $null) {
 $Arrmyresults += $myresult
}

return $arrmyresults

Friday, July 30, 2010

Dynamic DNS without the [DNS]

I have been poking around at Microsoft name resolution system investigations that became a side project of computer account security research. I was looking at the ability of computer systems to use the DNS protocol to register names other than their own to see if any additional records could be created for a specific host name. The findings there are that hosts can register names other than their own, but if there is a record already present for the name they are trying to register, and that computer account (or user account) doesn't have rights to update, then it fails. This is good from a security perspective, but shows some limitations for usability and advance configurations provided from a level closer to the user or machine.

In the process, I took a deeper look at Active Directory integrated DNS zones to see how everything is represented. First off, DNS zones can be found in several different locations inside of Active directory. This is based on their replication scopes. For those not too familiar with AD and AD DNS, briefly, the advantages of Active Directory DNS is that it is made highly available through the fact that it is stored in the Active directory database, and all changes are replicated as part of standard AD replication. This allows records to be updated with small updates instead of larger zone file transfers that work on a scheduled timeout period. Additionally, in secure dynamic updates, updates are authenticated through Kerberos and the records are owned by the updater.

Back to replication... There are 4 options for Dns zone replication scopes in AD. This is Legacy, Domain, Forest, and application partition. Here is some information about each:

1) Legacy. This zone will be stored in the standard domain partition, under the Cn=Microsoft DNS,CN=System organizational unit in the dc=yourdomain,dc=com partition. A zone will appear as a container icon, and is of the class dnsZone. The problem with this type of zone is although it is only available in the scope of its own domain, it is part of the domain's system contain and will replicate as part of the global catalog to other domains. So you waste space and replication traffic sending information to other domain controllers that cannot use this information.

2) Domain. This zone is stored in a separate partition DC=DomainDnsZones,dc=yourdomain,dc=com. This partition is only available on domain controllers that are running the DNS service. So, replication is limited to only where the records are needed, and it only stays in that one domain.

3) Forest. This zone is stored in a separate partition DC=ForestDnsZones,dc=yourdomain,dc=com. This partition will replicate to all dns servers in the forest. It is only hosted on domain controllers with dns installed.

4) Application. If you create your own custom application partitions, you can use them to store DNS. Also you can chose where the application partitions replicate. For DNS, this may be useful if you want specific zones only located in DC's in a certain city, but it requires more manual work to manage it.

If you look inside adsiedit at the dnsZone containers in these partitions, you will see dnsNode objects for records. The object will be named DC=. Example, if you have the zone mycompany.com. The record www.mycompany.com will have the name DC=www. Inside each of these objects is a dnsRecord attribute. This is multivalued, so if www.mycompany.com had several records for 3 different host machines, you will see 3 dnsRecord values. The dnsRecord itself is all in hex. The type of Record (A, CNAME, SRV, etc) is all within the hex, along with the values, timestamps, ttl, etc. (Hopefully I will get back on track to decoding these on of these days)

The interesting point to all of this is that we are looking at the records in LDAP. Typically records are generated through the DNS service using authentication from a workstation. The DHCPClient service registers the hostnames of the machine, and uses the computer account to own the record. When you look at the permissions of the dnsZone object's in LDAP, authenticated users has Create All Child Objects rights. This gives any user or computer the ability to go and create their own records outside of the whole DNS protcol, and built in methods. So, if you needed to create additional dnsRecords on a dnsNode object that you own, you can do that. If you want to dynamically create CNAME, SRV or other records, you can. If you want to dynamically create a DNS record that can't be scavenged, no problems.

Someday I hope to work out a basic tool or script for some of this, but presently I'm still too lazy to finish up my nbtns powershell library for doing all of the netbios name and WINS protocol functions through powershell.

The DNS tunneling possibilities to this are interesting, if you have AD DNS exposed to the outside world.

Tuesday, July 13, 2010

How to validate client dns settings for a few thousand systems

Over the last year or so, I have been working on correcting and ensuring correct DNS settings on clients. Inconsistency of documentation between build and support teams, or mistyped entries can prove to be a large scale problem as well as outages waiting to happen. To create a centralized store of DNS client settings is always a challenge, especially when not everyone is in close communication, and you want automation involved. So being an Active Directory guy, I thought of ways to involve AD in this. There is always GPO settings, however these are not permanent, and GPO's can't differentiate between NIC cards that should and shouldn't be touched. So, to get around this problem, I wanted something that was location specific and smart enough to be able to tell what a valid internal IP address was. Having SCOM and SCCM as the tools to help implement this, I came up with a set of scripts for various OS's to parse reports, set client settings, and provide monitoring of client settings to track any deviation from the published standards. The trick to this was stashing DNS client setting information in AD. Since the settings were site specific, tying the information to the site object seemed like a natural choice. From here you can either extend the schema to include an attribute for this, or use one that is available but not in use. The best path seemed to be using one not in use, and what appears to be perfect is the location attribute. Since it is a text field, and is editable in the AD Sites MMC, it is easy to manage. Once that is in place, vbscript's are easy to produce to check the client machine's site, pull out domain specific information out of the location field, compare the approved settings against all "valid IP" NIC's for any problems. Different issues provide different results to the scripts for responsible teams to resolve. There are always some exceptions to the rule that are hard to code for, so not getting to overzealous in the configuration scripts, and providing an exception capability to monitoring scripts is a must.