If you follow my blog on a regularly basis, you probably already know that I’m a big fan of OSSEC. I’m using it to monitor all my personal systems (servers, labs, websites, etc). Being a day-to-day user, I have always new ideas to extend the product , by using 3rd party tools or by adding features. One of the missing feature (at least for me), is the lack of information when an alert is generated. Tracking the attackers source IP addresses is very nice. Example: OSSEC can trigger active-response scripts to blacklist them during a short period but how can we benefit of more “visibility” with those addresses. When you think how to give more visibility to IP addresses, you immediately think: Geolocation! I already posted an article about the power of geolocation (link) to map alerts onto a Google map (example: a brute-force attack). This is very interesting but required manual actions. As IP addresses are already known by OSSEC (saved in the variable “srcip“), why not let OSSEC do the job for us in real time?
The problem solved by the geolocation is the following: How to convert IP addresses in coordinates (longitude/latitude) first and then map them to a country and/or city? MaxMind has the solution. This company maintains a database of all the assigned IP addresses (Over 99.5% on a country level and 78% on a city level for the US within a 40 kilometer radius – source: Maxmind) with their mapping to geographic locations. Note that they provide two databases: IPv4 and IPv6. They propose API‘s for several languages like C. Good news OSSEC is written in C! So, I wrote a patch which perform a geolocation of the ‘srcip’ attackers to display the location of the IP address. Let’s go…
Step 1: Install the MaxMind GeoIP API
This is easy as any other open source tool/library. Download the source code and install it. It should not a problem on classic Linux flavors.
# wget http://www.maxmind.com/download/geoip/api/c/GeoIP-1.4.8.tar.gz # tar xzvf GeoIP-1.4.8.tar.gz # cd GeoIP-1.4.8 # ./configure # make # make install
By default, everything will be installed under /usr/local but you are free to change the multiple paths via the configure script. The API provides C include files and (dynamic/static) libraries, very common.
Step 2: Install or recompile OSSEC with GeoIP localization
If you have already an OSSEC running, you could simply apply my patch to the original source tree. Take care if you already performed personal changes! I created the patch from a standard 2.6 tarball. To enable the GeoIP feature, you have to enable it (like the MySQL support).
# wget http://www.ossec.net/files/ossec-hids-2.6.tar.gz # tar xzvf ossec-hids-2.6.tar.gz # wget https://blog.rootshell.be/wp-content/uploads/2012/06/ossec-geoip.patch # cd ossec-hids-2.6 # patch -p1 < ../ossec-geoip.patch # cd src # make setgeoip # cd .. # ./install.sh
Step 3: Install the MaxMing GeoIP DBs
MaxMind provides different versions of the databases. I’m using the GeoCityLite. This is the free version which provides precision up to the city. This is far enough for me. Databases are not provided with the API, they must be installed manually:
# cd /var/ossec/etc # wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz # gzip -d GeoLiteCity.dat.gz # wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCityv6-beta/GeoLiteCityv6.dat.gz # gzip -d -c - >GeoLiteCityv6.dat.gz
I suggest you to download both databases (v4 & v6) and don’t forget that databases are regularly updated! It’s interesting to setup a small cron to install new versions to keep a good accuracy in the results.
Step 4: Fix the OSSEC configuration files
Once the patch installed, new parameters are available to set the GeoIP environment. First, in the ossec.conf “global” section, define the path of your databases.
<global> <geoip_db_path>/etc/GeoLiteCity.dat</geoip_db_path> <geoip6_db_path>/etc/GeoLiteCityv6.dat</geoip6_db_path> </global>
In the “alerts” section, activate the GeoIP feature:
<alerts> <use_geoip>yes</use_geoip> </alerts>
Finally, in the internal_options.conf, enable (or disable) the display of GeoIP information in the notification emails:
# Maild GeoIP support (0=disabled, 1=enabled) maild.geoip=1
How does it work? The OSSEC process which performs the GeoIP lookups is “ossec-analysisd“. When an alert must be logged and if a “srcip” has been decoded, the IP address is passed to a new function GeoIPLookup() which calls the MaxMind API and returns a string with the geolocation data. The data is added to the alert text. The second component which has been patched is “ossec-maild” which parses the alerts and send emails also with the GeoIP data (if enabled).
During the configuration, don’t forget that “ossec-analysisd” runs chrooted (in the main OSSEC directory). Don’t forget to adapt the path to the GeoIP databases! (they must be defined relative to the chroot environment).
Here follow some examples of alerts with GeoIP data enabled:
** Alert 1338899194.500996: - apache,invalid_request, 2012 Jun 05 14:26:34 (xxx) x.x.x.x->/var/log/apache/error_log Rule: 30115 (level 5) -> 'Invalid URI (bad client request).' Src IP: 184.108.40.206 Src Location: RU,Moscow City,Moscow [Tue Jun 05 14:26:34 2012] [error] [client 220.127.116.11] [deleted] ** Alert 1338901319.507426: - syslog,postfix,spam, 2012 Jun 05 15:01:59 (xxx) x.x.x.x->/var/log/syslog Rule: 3303 (level 5) -> 'Sender domain is not found (450: Requested mail action not taken).' Src IP: 18.104.22.168 Src Location: NL,Zuid-Holland,Alphen Jun 5 15:01:43 xxx postfix/smtpd: NOQUEUE: reject: [deleted] Received From: (xxx) x.x.x.x->/var/log/apache/access_log Rule: 100106 fired (level 15) -> "PHP CGI-bin vulnerability attempt." Src Location: IL,Tel Aviv,Tel Aviv-yafo Portion of the log(s): 22.214.171.124 - - [05/Jun/2012:16:42:07 +0200] [deleted]
Note that GeoIP lookups will be successful only for alerts which have a valid “srcip” field! In all case, the returned location will be “(null)“! What about the impact on performances? I’m using this patch in production for a few days and I did not notice any performance degradation. The GeoIP lookup is performed only once and parsed later by ossec_maild. (I’ve an average of 2000 alerts logged per day).
My OSSEC server is compiled with the support for MySQL. I did not detect any incompatibility between MySQL and my patch. At this time, the geolocation data are not sent to the MySQL alert table. But this could be done easily: Storing the latitude/longitude could be helpful to map attacks in real time using a 3rd party tool.
My patch is available here. Feel free to download it, use it and maybe improve it. Comments and suggestions will be appreciated. Final disclaimer, I won’t be responsible of you break your current OSSEC setup…