How to check a bulk of ip for reverse dns?
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
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 toSTDOUT
. If you don't want tocat
from file, you can directly pipe from another process likecommand | xargs ...
xargs -I % bash -c
# Take each line from left of pipe, use%
as placeholder, runbash
command that follows within single quotesdig
IP address that comes from placeholder%
byxargs
, assign to variablequery
. If result happens to benull
(zero length), assign string 'null' word toquery
variable, then print asIP: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.
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.