IPFire Location: Lua Bindings for Fun and Profit

by Michael Tremer, April 25, Updated April 25

Do you like what you are reading? Subscribe to our newsletter and don't miss out on the latest...   Join Now

The IPFire Location database comes with a small and lightweight library that we call ''libloc''. It is written in C and implements the core functionality of IPFire Location. But what if you want to use it in another piece of software? We already have bindings for Python and Perl allowing the database being integrated seamlessly into applications written in those. And finally, another important addition is here: Lua!

Lua is a lightweight language that is being used wherever an easy way to script something is needed. That can either be small programs which are quickly implemented in Lua without learning too much programming, but it is also very commonly used to extend existing software by allowing to load small scripts into it. Those are for example Apache, nmap, PowerDNS, Knot DNS, Suricata, Snort and HAProxy, as well as plenty more...

A Plethora Of Possible Applications

Because there are so many possible applications for Location data, there is almost an infinite amount of ideas and opportunities around. For example:

  • Your web application could receive the location of a client in the request headers added by Apache or HAProxy. That allows blocking certain services for certain countries or networks on the internet. You can also apply rate-limiting features based on the user's location to protect against DoS attacks. Or you can send the origin of a connection to a third-party application in the HTTP request headers.
  • You could collect statistics about where your DNS queries are coming from with PowerDNS Recursor.
  • You can write a custom protocol parser for your IPS with Suricata and use Location information.

Basically anything that makes or accepts an IP connection can be enhanced using a very short script. Lua is incredibly lightweight and therefore fast, adding negligible overhead for most applications.

At this stage, we do not have all documentation ready about the new module. But there is a test case that has some examples and this snippet to get you started:

-- Load the location module
location = require("location")

-- Open the database
db = location.Database.open("/usr/share/location/database.db")

-- Perform a lookup
network = db:lookup("81.3.27.38")
print(network) # 81.3.0.0/18

-- Fetch an Autonomous System
as = db:get_as(204867)
print(as) # AS204867 - Lightning Wire Labs GmbH

If you have another application for this, get in touch and let me know!