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?
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It only takes a minute to sign up.
Sign up to join this communityIs 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?
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
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).
Here is a quick and dirty one liner: Contents of ip-addresses.txt:
$ cat ip-addresses.txt
1.2.3.4
1.1.1.1
222.222.222.222
23.12.34.56
8.8.8.8
208.67.222.220
Replace txt with your file that contains addresses, separated by newlines:
$ cat ip-addresses.txt | xargs -I % bash -c 'echo "%:$(dig -x % +short)"' >> dig-output.txt
If you append to dig-output.txt like above, contents of that file will be like below, if reverse DNS lookup is successfull, IP:NAME
, if not, IP:(NULL)
$ cat dig-output.txt
1.2.3.4:
1.1.1.1:
222.222.222.222:
23.12.34.56:a23-12-34-56.deploy.static.akamaitechnologies.com.
8.8.8.8:google-public-dns-a.google.com.
208.67.222.220:resolver3.opendns.com.
If IP addresses are coming from another process, you can directly pipe to xargs.
Edit: If you must have a word such as null (inspired by @Serg) in case of a lookup failure, you can use the command below:
$ cat ip-addresses.txt | xargs -I % bash -c '{ query=$(dig -x % +short); if [ -z $query ]; then query=null;fi; echo %:$query; }'
cat ip-addresses.txt
# Print IP addresses to STDOUT
. If you don't want to cat
from file, you can directly pipe from another process like command | xargs ...
xargs -I % bash -c
# Take each line from left of pipe, use %
as placeholder, run bash
command that follows within single quotesdig
IP address that comes from placeholder %
by xargs
, assign to variable query
. If result happens to be null
(zero length), assign string 'null' word to query
variable, then print as IP:result
Demo:
$ cat ip-addresses.txt | xargs -I % bash -c '{ query=$(dig -x % +short); if [ -z $query ]; then query=null;fi; echo %:$query; }'
1.2.3.4:null
1.1.1.1:null
222.222.222.222:null
23.12.34.56:a23-12-34-56.deploy.static.akamaitechnologies.com.
8.8.8.8:google-public-dns-a.google.com.
208.67.222.220:resolver3.opendns.com.
>> my-log-filename.txt
to the end of the command.
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.
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!