Plotting IP addresses location on Googlemaps
Often we need to have visualization of some IP addresses geographic locations. For site visitor there are many solution available. But sometime we need to build our own tools to do other job for example: to visualize IP address blocked by firewall (e.g iptables).
1. Extract the IP address ( in this example, IP addresses blocked by iptables yesterday)
grep "`date -d yesterday +"%b %e"`" /var/log/iptables | grep -Eo 'SRC=([0-9]{1,3}\.){3}[0-9]{1,3}'Â | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | sort | uniq > /home/admin/ipadr.txt
2. Lookup GeoIP database (I am using Maxmind GeoIP) and generate xml data for Googlemaps
Install GeoIP API, get the source from : http://www.maxmind.com/app/city#api
I prefer C since it's known to be fast. This is my code to output a XML file for Googlemaps, compile accordingly.
The program is pretty straightforward. You can write your own program easily.
#include "GeoIP.h"
#include "GeoIPCity.h"
static const char * _mk_NA( const char * p ){
 return p ? p : "N/A";
}
int
main(int argc, char *argv[])
{
 FILE          *f;
 GeoIP         *gi;
 GeoIPRecord   *gir;
 int            generate = 0;
 char           host[50];
 const char    *time_zone = NULL;
 char         **ret;
 if (argc == 2)
   if (!strcmp(argv[1], "gen"))
     generate = 1;
 gi = GeoIP_open("/usr/local/share/GeoIP/GeoLiteCity.dat", GEOIP_INDEX_CACHE);
 if (gi == NULL) {
   fprintf(stderr, "Error opening database\n");
   exit(1);
 }
 f = fopen("/home/admin/ipadr.txt", "r");
 if (f == NULL) {
   fprintf(stderr, "Error opening ipadr.txt\n");
   exit(1);
 }
printf("<markers>\n");
 while (fscanf(f, "%s", host) != EOF) {
   gir = GeoIP_record_by_name(gi, (const char *) host);
   if (gir != NULL) {
     ret = GeoIP_range_by_ip(gi, (const char *) host);
     /*time_zone = GeoIP_time_zone_by_country_and_region(gir->country_code, gir->region);
*/
     printf("<marker\tlat=\"%f\"\tlng=\"%f\"/>\n",
       gir->latitude,
       gir->longitude
       );
     GeoIP_range_by_ip_delete(ret);
     GeoIPRecord_delete(gir);
   }
 }
   printf("</markers>");
 GeoIP_delete(gi);
 return 0;
}
/home/admin/geoip-lat.out > /var/www/html/ipt_ipadr/data.`date -d yesterday +"%B%d"`.xml
3. Write some html page to display the maps
Signup and request GoogleMaps API key
The code will look like this :
ABQIAAAASAeTS0YSp74Q4Ge8mtPOIhS61fQXMcOlVXVPArFAZTgGARl97hQIKz9c5fIKOWgD7pD65K8ZRXBb
Make a html page, for example :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>IP Address location blocked by FW</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=PUTYOURKEYHERE"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
function load() {
if (GBrowserIsCompatible()) {
   var map = new GMap2(document.getElementById("map"));
   map.addControl(new GLargeMapControl());
   map.addControl(new GMapTypeControl());
   GDownloadUrl("./location/of/your/data.xml", function(data) {
       var xml = GXml.parse(data);
       var markers = xml.documentElement.getElementsByTagName("marker");
       for (var i = 0; i < markers.length; i++) {
           var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
           parseFloat(markers[i].getAttribute("lng")));
           map.addOverlay(new GMarker(point));
}
});
}
}
//]]>
</script>
</head>
   <body onload="load()" onunload="GUnload()">
   <div id="map" style="width: 1650px; height: 900px"></div>
   </body>
</html>
4. Set up automatic job (cron) to process your data
For example: I want the map to be updated daily using day-1 blocked IP.
The script will look like this :
#!/bin/sh
grep "`date -d yesterday +"%b %e"`" /var/log/iptables | grep -Eo 'SRC=([0-9]{1,3}\.){3}[0-9]{1,3}'Â | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | sort | uniq > /home/admin/ipadr.txt
/home/admin/geoip-lat.out > /var/www/html/ipt_ipadr/data.`date -d yesterday +"%B%d"`.xml
if [ -f /var/www/html/ipt_ipadr/data.xml ]; then
 rm -f /var/www/html/ipt_ipadr/data.xml && ln -s /var/www/html/ipt_ipadr/data.`date -d yesterday +"%B%d"`.xml /var/www/html/ipt_ipadr/data.xml
else
 ln -s /var/www/html/ipt_ipadr/data.`date -d yesterday +"%B%d"`.xml /var/www/html/ipt_ipadr/data.xml
fi
The result will be like this :