Bash: Reverse DNS Lookup of Active IP Addresses

17,065

You can use dig +noall +answer -x <IP> to look up an IP address.

To simply loop over a file that contains a list of IP addresses:

while read ip; do dig +noall +answer -x $ip; done < ips.txt

Or, pipe the output of your counting command. This time we get the count and the IP addresses separately and then print them on one line:

cat access.log | awk '{print $1}' | sort | 
uniq -c | sort -n | tail -n10 |
while read count ip; do printf "%d " $count; printf "%s " $ip; dig +noall +answer -x $ip; done

Example (sorry for the UUOC):

cat test | while read count ip; do printf "%d " $count; printf "%s " $ip; dig +noall +answer -x $ip; done
20 8.8.8.8 8.8.8.8.in-addr.arpa.    52767   IN  PTR google-public-dns-a.google.com.
22 8.8.4.4 4.4.8.8.in-addr.arpa.    61369   IN  PTR google-public-dns-b.google.com.

You can further pipe dig's output into awk to just get the host name:

cat test | while read count ip; do printf "%d " $count; printf "%s " $ip; echo $(dig +noall +answer -x $ip | awk '{ print $(NF) }'); done
20 8.8.8.8 google-public-dns-a.google.com.
22 8.8.4.4 google-public-dns-b.google.com.
Share:
17,065

Related videos on Youtube

GooDoo
Author by

GooDoo

Updated on September 18, 2022

Comments

  • GooDoo
    GooDoo over 1 year

    I have a one-line command that lists the top 10 most active IP addresses from a web server access log:

    cat access.log | awk '{print $1}' | sort | uniq -c | sort -n | tail -n10
    

    A sample result set (with only 3 entries for simplicity) would be:

    20 12.34.56.7
    22 3.67.89.201
    29 9.0.203.255
    

    As you can see, the count precedes the IP address, with the two separated by a blank space. There are actually blank spaces preceding the count too but I can't get them to show here.

    I like to do a reverse DNS lookup of the IP addresses so that it will look like this:

    20 12.34.56.7 (d12-34-56-7.abhsia.telus.net)
    22 3.67.89.201 (customer.vpls.net)
    29 9.0.203.255 (9-0-203-255.hlrn.qwest.net)
    

    How can I do this without resorting to a script (that is, sticking to a one-line command)? Any advice is much appreciated.

  • GooDoo
    GooDoo over 10 years
    Thanks for the prompt response! However, this time I get only the output from dig and I lost the count. The desired output would be: <count> <IP address> <reverse DNS lookup>
  • slhck
    slhck over 10 years
    That's quite easy to change since while splits the input based on whitespace, so you can read count and IP address separately. See my update. You can play with dig's options to change the output—I haven't used it really.
  • GooDoo
    GooDoo over 10 years
    Thanks! I've made some modifications and now it's what I'm looking for: cat access.log | awk '{print $1}' | sort | uniq -c | sort -n | sed "s/^[ \t]*//" | tail -n10 | while read count ip ; do echo "$count " "$ip" "( $(dig +noall +answer -x $ip | awk '{ print $(NF) }') )"; done Appreciate your kind help!
  • Brace_for_Impact
    Brace_for_Impact over 9 years
    for i in `cat input.txt` ; do dig +noall +answer -x $i ; done >> output.txt
  • sfussenegger
    sfussenegger about 9 years
    +1 but btw, using xargs ("xargs - build and execute command lines from standard input") would be an alternative to while loops cat file | xargs -n1 dig +noall +answer -x