How to find the geolocation of an IP address in Elixir

Alex Loukissas
AgentRisk: Superhuman Wealth Management
3 min readAug 16, 2019

--

There are many reasons why one would like to find the geolocation of a client based on its IP address, such as content localization, detailed traffic analytics, regulatory compliance, account security, etc. In this article, we’ll show how to do this in Elixir using a free IP geolocation database.

Photo by Anastasia Dulgier on Unsplash

How does IP geolocation work?

In short, one can use an IP geolocation database that maps an IP address to a geolocation. In most cases, IP geolocation databases can provide an accuracy level down to ZIP code or city, worldwide. There are many such providers, both free and paid, with varying level of accuracy. While free IP geolocation databases aren’t as accurate as some of the high-end paid ones, they can be good enough to meet basic needs.

In this example, we’ll be using GeoLite2, which is the free tier of the paid GeoIP2 product by MaxMind. GeoLite2 offers a downloadable IP geolocation databases, both in binary and CSV formats. Note that there is no API version of GeoLite2, meaning you’ll need to consume the database file internally in your app (or expose it on your own API implementation).

Setting up GeoLite2 in Elixir

We’ll be using geolix to consume GeoLite2 in Elixir. The project’s docs pages are pretty complete, but we’ll highlight the main points here.

Configuration

The simplest way to configure geolix is using a static configuration. We’ll need to add two entries, one for the city database and one for the country one, as shown below:

Minimal configuration for geolix

Note that the source field can point to either a URL or a local file path. For simplicity, we used the former option here. The geolix library recognizes this automatically and seamlessly handles gzip’ed tarballs.

Integration

The simplest way to do a lookup is using Geolix.lookup/1, like so:

The lookup function can take optional arguments, including an option to return a plain map instead of a Geolix struct (useful if you want to expose this function as a RESTful API endpoint), as shown below:

You can also limit the results to only the city or the country database:

How we’re using IP geolocation information

Our main use case for IP geolocation information is to detect where our users log in and warn them if they’ve logged in from a new location for the first time. Since we care a lot about protecting our customer’s accounts, we treat this as a yellow flag and warn the user on such events. Other use cases in our vertical is for regulatory compliance — in our case, we are only able to serve customers in the United States.

Caveats

Probably the most common ways to get a client’s IP address is from the remote_ip field from the Plug.Conn struct. However, if your application server is behind e.g. a proxy or load balancer, you may not be getting the real IP address of the client. In this case, you’ll need to use the X-Forwarded-For header. This is the case for our deployment, where we’re using an Ingress on Google Kubernetes Engine. We will publish a follow-up post on how we did all that, which should be useful for others.

Thank you!

I really hope you found this post useful. If you did, hit that applause button to show your appreciation. Please let me know in the comments if you have any questions or suggestions.

Does building the future of automated wealth management and working on a super cutting-edge tech stack sound to solve really interesting problems sound interesting? Drop us a line at founders@agentrisk.com and let’s have a chat!

--

--