How to check a bulk of ip for reverse dns?

15,906

Solution 1

xargs provides an optin --arg-file. With -L1 option to treat each line as argument, the simplest command we can make is as follows

$ xargs -L1 --arg-file=ip-addr.txt dig +short -x
google-public-dns-a.google.com.
resolver2.opendns.com.

If it's necessary to display the IP address next to the resolved domain, we can also do:

$ xargs -L1 --arg-file=ip-addr.txt sh -c 'printf "%s: " "$1"; dig +short -x "$1"' sh
8.8.8.8: google-public-dns-a.google.com.
208.67.220.220: resolver2.opendns.com.

Of course, xargs is an extra process. What if we wanted to only use shell and dig ? With bash version 4 and over, we can use mapfile or readarray to get lines of the text file into array, and then process items in a loop:

$ mapfile -t -d $'\n' < ip-addr.txt
$ for i in "${MAPFILE[@]}" ; do printf "%s:" "$i"; dig +short -x "$i"; done
8.8.8.8:google-public-dns-a.google.com.
208.67.220.220:resolver2.opendns.com.

If the IP addresses are few and don't require a long text file, POSIXly, we could use set to define values as positional parameters:

$ set -- 8.8.8.8 208.67.220.220
$ for i ; do printf "%s:" "$i"; dig +short -x "$i"; done
8.8.8.8:google-public-dns-a.google.com.
208.67.220.220:resolver2.opendns.com.

We can also use dig -x $IP_ADDRESS +short in a script like so:

#!/bin/bash
export LC_ALL=C
# without specifying 'in' part, bourne-like shells default
# to iterating over positional parameters
for item
do
     domain=$(dig -x "$item"  +short)
     # this logic can also be reversed with
     # [ "x$domain" = "x" ] && echo "empty" || echo "$domain"
     if [ -n "$domain"  ] ;
     then
         echo "$domain"
     else
         echo "$item" result is NULL
     fi
done

Demo of sample usage(all ip addresses given as space separeted):

$ ./reverse_dns_lookup.sh 8.8.8.8 74.125.193.94 151.101.193.69                 
google-public-dns-a.google.com.
ig-in-f94.1e100.net.
151.101.193.69 result is NULL

As you can see , in the last example our DNS server didn't find domain for the ip address we gave it. In such case we can use a different DNS server, for instance open_dns with dig @208.67.220.220 $IP_ADDRESS +short

In the demo above, the ip addresses are provided on command line, like ./reverse_dns_lookup.sh ADDRESS1 ADDRESS2 ADDRESS2 but you also can use a file for that, like so:

$ cat ip_addresses.txt |  xargs ./reverse_dns_lookup.sh                          <
google-public-dns-a.google.com.
resolver2.opendns.com.
192.30.253.112 result is NULL

Alternative script version:

Here's alternative version of the script that prints the AUTHORITY section from dig's output. This may be much better and more reliable than just +short version. NOTE: this uses 8.8.8.8 , which is Google's public DNS. Use a different server if you feel necessary.

#!/bin/bash
export LC_ALL=C
for item
do
 domain=$(dig @8.8.8.8  -x "$item" +noall +authority +answer)
 if [ -n "$domain"  ] ;
 then
     echo "$domain"
 else
     echo "$item" result is NULL
 fi
done

Demo:

$ cat ip_addresses.txt |  xargs ./reverse_dns_lookup.sh 

; <<>> DiG 9.10.3-P4-Ubuntu <<>> @8.8.8.8 -x 8.8.8.8 +noall +authority +answer
; (1 server found)
;; global options: +cmd
8.8.8.8.in-addr.arpa.   21390   IN  PTR google-public-dns-a.google.com.

; <<>> DiG 9.10.3-P4-Ubuntu <<>> @8.8.8.8 -x 208.67.220.220 +noall +authority +answer
; (1 server found)
;; global options: +cmd
220.220.67.208.in-addr.arpa. 6674 IN    PTR resolver2.opendns.com.

; <<>> DiG 9.10.3-P4-Ubuntu <<>> @8.8.8.8 -x 192.30.253.112 +noall +authority +answer
; (1 server found)
;; global options: +cmd
253.30.192.in-addr.arpa. 10 IN  SOA ns1.p16.dynect.net. ops.github.com. 6 3600 600 604800 60

Solution 2

Nmap

You can just

nmap -R -sL -Pn 1.2.3.0/24 | grep '('
  • -n/-R Never do DNS resolution/Always resolve [default: sometimes]
  • -sL List Scan - simply list targets to scan
  • -Pn Treat all hosts as online -- skip host discovery. Remove this to get just what respond to ping.

The grep leave just resolved reverse DNS and some useful lines.

Add --dns-servers x.x.x.x to use a specific DNS server like 1.1.1.1.

Solution 3

Inspired by the shell example shown in another answer I decided a Perl version suited me better so I created this file "batch_dns_by_ip.pl". You put a list of IP address in a text file that you will pipe into the program.

The code should look like this and you will want to make the file executable:

#!/usr/bin/perl
use strict;
my @domains;
my $address;
while (<>) {
  chomp;
  $address = $_;
  $address =~ s/ *//g;
  @domains = ();
  @domains = `dig -x "$address" +short`;
  chomp(@domains);
  if ( "$domains[0]" eq "" ) {
    $domains[0] = "NULL";
  }
  printf( "addr: %15s names: %s", $address, $domains[0] );
  if ( "$domains[1]" eq "" ) {
    print "\n";
  }
  else {
    printf( ", %s\n", $domains[1] );
  }
}

A run might look like this:

$ cat myips | ./batch_dns_by_ip.pl
addr:  216.58.219.238 names: lga25s41-in-f14.1e100.net., lga25s41-in-f238.1e100.net.
addr:  151.101.129.69 names: NULL
addr:         8.8.8.8 names: google-public-dns-a.google.com.
addr:     10.49.11.62 names: nyalbdnsvip01.miscny.nyenet., nyalbcwgbvip01-vlan401.miscny.nyenet.
addr:  69.172.201.153 names: NULL

I hope that helps!

Share:
15,906

Related videos on Youtube

Yen Deng
Author by

Yen Deng

Updated on September 18, 2022

Comments

  • Yen Deng
    Yen Deng over 1 year

    Is there a way to check to reverse DNS check for loads of IPs, I have a list of IP I want to check?

    I know you're are able to do these individually:

    host <ip-address>
    

    and

    dig -x <ip-address>
    

    Also, is there a way to export them?

  • Yen Deng
    Yen Deng over 7 years
    Sorry for my ignorance but where in the script do I define the list of the IPs?
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy over 7 years
    @YenDeng the IP addresses are given on command line. I'll add a little more info about that in a second.
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy over 7 years
    Try deleting that line, and write that line again. Somehow you got a control character added there. Just retype it, #! /bin/bash
  • Yen Deng
    Yen Deng over 7 years
    Some reason, it's not getting recognised. It says "No such file or directory"
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy over 7 years
    @YenDeng did you make the script executable ? chmod +x ./reverse_dns_lookup.sh
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy over 7 years
    Yen, i have to leave. Please leave me comment here if you have other questions. I will check back as soon as I return to the site. Thanks
  • Yen Deng
    Yen Deng over 7 years
    Yes I have made the file executable but somewhat it's not being nice to me :( Thank you for your time and let me know when you're back!
  • Admin
    Admin over 7 years
    @YenDeng You need to be in the folder where both ip_addresses.txt and ./reverse_dns_lookup‌​.sh resides. If you omit ./ before script name, it won't run, even if it is executable. Because it is not in your environment variable (PATH).
  • devius
    devius about 6 years
    This works, but note that the input file must have have each IP on its own separate line.