New version of contrib/reverse-dns

This commit is contained in:
Simon Kelley
2015-03-04 20:32:26 +00:00
parent 9003b50b13
commit 4c960fa90a
3 changed files with 125 additions and 57 deletions

View File

@@ -1,18 +1,18 @@
Hi.
The script reads stdin and replaces all IP addresses with names before
outputting it again. IPs from private networks are reverse looked up
via dns. Other IP adresses are searched for in the dnsmasq query log.
This gives names (CNAMEs if I understand DNS correctly) that are closer
to the name the client originally asked for then the names obtained by
reverse lookup. Just run
To translate my routers netstat-nat output into names that actually talk
to me I have started writing to simple shell scripts. They require
netstat -n -4 | ./reverse_replace.sh
to see what it does. It needs
log-queries
log-facility=/var/log/dnsmasq.log
to be set. With
netstat-nat -n -4 | reverse_replace.sh
I get retranslated output.
Sincerely,
Joachim
in the dnsmasq configuration.
The script runs on debian (with ash installed) and on busybox.

View File

@@ -1,29 +0,0 @@
#!/bin/bash
# $Id: reverse_dns.sh 4 2015-02-17 20:14:59Z jo $
#
# Usage: reverse_dns.sh IP
# Uses the dnsmasq query log to lookup the name
# that was last queried to return the given IP.
#
IP=$1
qmIP=`echo $IP | sed 's#\.#\\.#g'`
LOG=/var/log/dnsmasq.log
IP_regex='^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'
if ! [[ $IP =~ $IP_regex ]]; then
echo -n $IP
exit
fi
NAME=`tac $LOG | \
grep " is $IP" | head -1 | \
sed "s#.* \([^ ]*\) is $qmIP.*#\1#" `
if [ -z "$NAME" ]; then
echo -n $IP
else
echo -n $NAME
fi

View File

@@ -1,28 +1,125 @@
#!/bin/bash
# $Id: reverse_replace.sh 4 2015-02-17 20:14:59Z jo $
#!/bin/ash
# $Id: reverse_replace.sh 18 2015-03-01 16:12:35Z jo $
#
# Usage e.g.: netstat -n -4 | reverse_replace.sh
# Parses stdin for IP4 addresses and replaces them
# with names retrieved by reverse_dns.sh
# with names retrieved by parsing the dnsmasq log.
# This currently only gives CNAMEs. But these
# usually tell ou more than the mones from reverse
# lookups.
#
# This has been tested on debian and asuswrt. Plese
# report successful tests on other platforms.
#
# Author: Joachim Zobel <jz-2014@heute-morgen.de>
# License: Consider this MIT style licensed. You can
# do as you ike, but you must not remove my name.
#
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
DNS=$DIR/reverse_dns.sh
LOG=/var/log/dnsmasq.log
MAX_LINES=15000
# sed regex
# sed regex do match IPs
IP_regex='[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
# private IP ranges
IP_private='\(^127\.\)\|\(^192\.168\.\)\|\(^10\.\)\|\(^172\.1[6-9]\.\)\|\(^172\.2[0-9]\.\)\|\(^172\.3[0-1]\.\)'
#######################################################################
# Find Commands
HOST=nslookup
if type host > /dev/null 2>&1; then
# echo "No need for nslookup, host is there"
HOST=host
fi
#######################################################################
# Functions
# Use shell variables for an (IP) lookup table
create_lookup_table()
{
# Parse log into lookup table
local CMDS="$( tail -"$MAX_LINES" "$LOG" | \
grep " is $IP_regex" | \
sed "s#.* \([^ ]*\) is \($IP_regex\).*#set_val \2 \1;#" )"
local IFS='
'
for CMD in $CMDS
do
eval $CMD
done
}
set_val()
{
local _IP=$(echo $1 | tr . _)
local KEY="__IP__$_IP"
eval "$KEY"=$2
}
get_val()
{
local _IP=$(echo $1 | tr . _)
local KEY="__IP__$_IP"
eval echo -n '${'"$KEY"'}'
}
dns_lookup()
{
local IP=$1
local RTN="$($HOST $IP | \
sed 's#\s\+#\n#g' | \
grep -v '^$' | \
tail -1 | tr -d '\n' | \
sed 's#\.$##')"
if echo $RTN | grep -q NXDOMAIN; then
echo -n $IP
else
echo -n "$RTN"
fi
}
reverse_dns()
{
local IP=$1
# Skip if it is not an IP
if ! echo $IP | grep -q "^$IP_regex$"; then
echo -n $IP
return
fi
# Do a dns lookup, if it is a local IP
if echo $IP | grep -q $IP_private; then
dns_lookup $IP
return
fi
local NAME="$(get_val $IP)"
if [ -z "$NAME" ]; then
echo -n $IP
else
echo -n $NAME
fi
}
#######################################################################
# Main
create_lookup_table
while read LINE; do
if grep --quiet $IP_regex <<< "$LINE"; then
IPs=`sed "s#.*\b\($IP_regex\)\b.*#\1 #g" <<< "$LINE"`
IPs=($IPs)
for IP in "${IPs[@]}"
for IP in $(echo "$LINE" | \
sed "s#\b\($IP_regex\)\b#\n\1\n#g" | \
grep $IP_regex)
do
NAME=`$DNS $IP`
# echo "$NAME is $IP";
LINE="${LINE/$IP/$NAME}"
NAME=`reverse_dns $IP `
# echo "$NAME $IP"
LINE=`echo "$LINE" | sed "s#$IP#$NAME#" `
done
fi
echo $LINE
done < /dev/stdin
done