Showing posts with label nslookup. Show all posts
Showing posts with label nslookup. Show all posts

17 January, 2016

Search host name based on IP from Forward Lookup zone - DNS

There are times when the need calls for very ugly but practical workarounds. This time, we want to know the DNS name of a host, we only know the IP address and we don't have reverse lookup zones.

In this case, we can list all the A records from the forward lookup zone and search for the IP address we know.


Use WMI

If you have admin rights on the DNS server, you can use WMI:
gwmi -Namespace root/microsoftDNS -q "select * from MicrosoftDNS_AType where recorddata='10.1.1.123'" | select Ownername,recordData


Use dnscmd

However, if you don't have any sort of permissions, you can try to use dnscmd to enumerate all records from the given zone and then use powershell to search for the IP, then do some text parsing to get a proper output:



A bit of explanation:
  • $zoneContent = dnscmd $dnsserver /enumrecords $dnsDomain . /continue
    Get the full list of records from the given zone
  • if($item -match "$ip"){...
    Go through each line in the output and if the given line contains the IP you are looking for, start processing the data
  • if($item -match "^  "){
    If the line starts with spaces, that means it will have an IP which belongs to a host with multiple IPs, so we will need to list the previous line as well
  • $aging = $($tmp=$zoneContent[$k-1] -match "aging:(?<number>[^\]]+)"; $matches.number)
    $timestamp = (Get-Date ("1601/01/01 00:00")).addhours($aging)
    Calculate the time stamp of the record from the Aging number (which is the number of hours from 1st Jan 1601
  • New-Object -TypeName psobject -Property @{"IP"=$ip; Host=($zoneContent[$k-1].split(" ")[0]); timestamp=$timestamp}
    Put the data into an object and throw it to the std out
The sample script in full:








 $ip = "10.1.1.122"  
 $dnsServer = "c3podc1"  
 $dnsDomain = "tatooine.com"  
   
 $zoneContent = dnscmd $dnsserver /enumrecords $dnsDomain . /continue  
 $k = 0  
   
 Foreach($item in $zoneContent){  
    if($item -match "$ip"){  
       # if the host has 2 IPs and we searched for the 2nd one, we will need the previous line from the output  
       if($item -match "^ "){  
          $aging = $($tmp=$zoneContent[$k-1] -match "aging:(?<number>[^\]]+)"; $matches.number)  
          $timestamp = (Get-Date ("1601/01/01 00:00")).addhours($aging)  
          New-Object -TypeName psobject -Property @{"IP"=$ip; Host=($zoneContent[$k-1].split(" ")[0]); timestamp=$timestamp}  
            
          $aging = $($tmp=$item -match "aging:(?<number>[^\]]+)"; $matches.number)  
          $timestamp = (Get-Date ("1601/01/01 00:00")).addhours($aging)  
          New-Object -TypeName psobject -Property @{"IP"=$ip; Host=($zoneContent[$k-1].split(" ")[0]); timestamp=$timestamp}  
       }  
       else{  
          $aging = $($tmp=$item -match "aging:(?<number>[^\]]+)"; $matches.number)  
          $timestamp = (Get-Date ("1601/01/01 00:00")).addhours($aging)  
          New-Object -TypeName psobject -Property @{"IP"=$ip; Host=($item.split(" ")[0]); timestamp=$timestamp}  
       }  
    }  
    $k++  
 }  
   

06 April, 2015

Verify forward and reverse DNS records - OS

DNS is a fairly simple and usually reliable service - when it works. People don't really think about it unless there are weird issues with an application and they spent 2 days troubleshooting it and just because they want to make sure they looked at everything, they check DNS and it turns out that those weird issues are in fact caused by e.g. missing reverse records.

These issues manifest in applications behaving strangely often providing uselessly generic errors messages or even worse, some misleading ones. After a very tedious issue over a weekend which required repeated checkouts across a globally distributed AD integrated DNS zone, I thought I wouldn't do this manually all the time with excel magic but via a script.

Steps needed to be made:
  • Take a list of server names (ideally FQDNs)
  • Perform a forward lookup to get the IP address(es) of each server
  • Take those IPs and perform a reverse lookup on them
  • Mark each host and IP with error if either the forward or reverse lookups fail or the reverse lookup provides a different hostname than the server name provided

Forward lookup (filtering on IPv4 only):
[array]$IPAddresses = [System.Net.Dns]::GetHostAddresses($obj.ComputerName) | ?{$_.AddressFamily -eq "InterNetwork"} | %{$_.IPAddressToString}


Reverse lookup:
$tmpreverse = [System.Net.Dns]::GetHostByAddress($_).HostName

Output:






The full script (simplified version):

 $hostlist = @($input)  
   
 # running through the list of hosts  
 $hostlist | %{  
      $obj = "" | Select ComputerName,Ping,IPNumber,ForwardLookup,ReverseLookup,Result  
      $obj.ComputerName = $_  
   
      # ping each host  
      if(Test-Connection $_ -quiet){  
           $obj.Ping = "OK"  
     $obj.Result = "OK"  
      }  
      else{  
           $obj.Ping = "Error"  
     $obj.Result = "Error"  
      }  
        
      # lookup IP addresses of the given host  
      [array]$IPAddresses = [System.Net.Dns]::GetHostAddresses($obj.ComputerName) | ?{$_.AddressFamily -eq "InterNetwork"} | %{$_.IPAddressToString}  
   
      # caputer count of IPs  
      $obj.IPNumber = ($IPAddresses | measure).count  
        
      # if there were IPs returned from DNS, go through each IP  
   if($IPAddresses){  
     $obj.ForwardLookup = "OK"  
   
        $IPAddresses | %{  
             $tmpreverse = $null  
                  
                # perform reverse lookup on the given IP  
             $tmpreverse = [System.Net.Dns]::GetHostByAddress($_).HostName  
             if($tmpreverse){  
                  
                     # if the returned host name is the same as the name being processed from the input, the result is OK  
                  if($tmpreverse -ieq $obj.ComputerName){  
                       $obj.ReverseLookup += "$_ : OK `n"  
                  }  
                  else{  
                       $obj.ReverseLookup += "$_ different hostname: $tmpreverse `n"  
                       $obj.Result = "Error"  
                  }  
             }  
             else{  
                  $obj.ReverseLookup = "No host found"  
                  $obj.Result = "Error"  
             }  
     }  
      }  
      else{  
           $obj.ForwardLookup = "No IP found"  
           $obj.Result = "Error"  
      }  
        
      # return the output object  
      $obj  
 }  


t