fleetdm / fleet

Open-source platform for IT, security, and infrastructure teams. (Linux, macOS, Chrome, Windows, cloud, data center)
https://fleetdm.com
Other
3.11k stars 430 forks source link

Geolocation via public IP address #4585

Closed edwardsb closed 2 years ago

edwardsb commented 2 years ago

Goal

As a Fleet admin I would like the ability to see what country my hosts are located in so that, in the event of an emergency or public safety concern, I can confirm whether or not these hosts are located in a dangerous location.

Figma

Geolocation via public IP address: https://www.figma.com/file/hdALBDsrti77QuDNSzLdkx/?node-id=5254%3A251782

How?

There are a couple way to solve this problem using public IP address which also has its drawbacks:

Via query: https://blog.fleetdm.com/locate-assets-with-osquery-7286c5f283b6

This solution would be the fastest solution, but put most of the burden on the Fleet administrator to mechanize the results via osquery logging destination or via live query APIs, beyond just viewing live query results in the UI.


Via Headers sent to server:

Its possible to capture the public IP address of a host calling some API via Headers

Once the public IP is obtained, we can include a piece of middleware in the request handler stack that does a GeoIP lookup of IP -> Location for example using MaxMind DB. We could then write that location to host details or possibly redis ( I suppose it depends on the access patterns and what we intend to do with those datapoints).

There are a few considerations we'd need to make with respect to doing the lookup on the server

With respect to obtaining the MaxMind DB:

Related resources:

https://github.com/maxmind/geoipupdate -- automatically update mmdb file https://github.com/oschwald/geoip2-golang -- go lib that offers memory mapped access (unless running on Google App Engine) to mmdb files -- which means low memory overhead

Relates to

https://github.com/fleetdm/fleet/issues/1418

What needs to be done

Once the Lat/Long is resolved, where do we store it and how do we surface it to API consumers?

tgauda commented 2 years ago

Customer created an extension to help solve this problem: https://code.penguinzmedia.group/foss/whereami-osqext

zwass commented 2 years ago

@edwardsb and I just discussed doing a first pass at this with the following assumptions:

1) Retrieve the host IP from the request IP (or X-forwarded-for). 2) Operator provides a path to the MaxMind DB via Fleet config. 3) Store the location info on the host row, updating when the host details are saved.

edwardsb commented 2 years ago

I have a first draft that might be acceptable. Rather than storing the location data in the host table, we are only storing public IP. When we render the host(s) response we pass the last recorded public IP through the geoip service to determine location information.

Since this data can be derived, it saves us from having to make hosts table even wider, and until we have a need to search on location, this solves the immediate need of location data on host details. Performance concern here is very small:

  1. maxmind db reader opens the file as a memory map which greatly reduces the memory overhead, rather than having to read the entire mmdb contents into memory
  2. Lookup(ip) is sub millisecond -- its super fast

relates to: https://github.com/fleetdm/fleet/pull/4652 todo: tests

noahtalerman commented 2 years ago

@edwardsb do you know if we have this turned on in dogfood? If no, can you please turn it on when you get the chance?

edwardsb commented 2 years ago

@edwardsb do you know if we have this turned on in dogfood? If no, can you please turn it on when you get the chance?

@noahtalerman we report public IP, but not location. In order to report location you need to supply a MaxMind database. Does Fleet have a MaxMind account?