Mapping IP addresses

For the previous post I generated a map of IP addresses. This post is quickly going to go over how the data was collected and mapped.

Collecting data

First add an iptables rule to log all unwanted traffic. This rule should be in the input chain just above any DROP or REJECT rules:

iptables -A INPUT ! -s 192.168.0.0/16 \
         -j LOG --log-prefix "iptables: " \
         -m limit --limit 15/min \
         -m state --state NEW \
         -m comment --comment "Log rejected traffic"

Log messages are sent to the syslog daemon. To split them into a separate log file, create a file called /etc/rsyslog.d/iptables.conf with the following contents and restart rsyslog:

:msg, contains, "iptables: " -/var/log/iptables.log
& ~

Note: You may want to add a logrotate rule for /var/log/iptables.log.

Geolocation

freegeoip.net makes it very easy to get location data for IP addresses. The script below creates a file called locations.csv with location info for each IP address:

#!/bin/sh
for ip in $(grep -wE 'DPT=(443|80|22)' iptables.log | sed -r 's/^.* SRC=([^ ]+).*$/\1/' |sort -u)
do
  curl "http://freegeoip.net/csv/${ip}" >> locations.csv
done

Mapping data

The script below generates a csv file with latitude, longitude and a dummy value. This data can then be uploaded to OpenHeatMap to plot the locations:

#!/bin/sh
echo 'lat,long,value' > ip-address-point-data.csv
for ip in $(grep -wE 'DPT=(80|443|22)' iptables.log |  sed -r 's/^.* SRC=([^ ]+).*$/\1/')
do
  echo "$(grep  "$ip" locations.csv | cut  -d, -f 9-10 ),1";
done >> ip-address-point-data.csv

The end result should look something like the following:

Map showing the location of unwanted connections

Data by country

Instead of plotting point data, IP addresses can be grouped by country. The following script does this:

#!/bin/sh
for ip in $(grep -wE 'DPT=(80|443|22)' iptables.log |  sed -r 's/^.* SRC=([^ ]+).*$/\1/')
do
  echo "$(grep "$ip" locations.csv | cut  -d, -f 3)";
done | sort | uniq -c | awk 'BEGIN{print "country,value"} {print substr($0, index($0,$2))","$1}' > country-data.csv

# Remove "Republic of" prefix for OpenHeatMap
sed -i 's/^Republic of //' country-data.csv

After being passed through OpenHeatMap the end result is the following map:

Map showing the location of unwanted connections