GeoIP Service
A lightweight service for IP geolocation lookups that provides ASN (Autonomous System Number), country code, and network information.
Usage
As a Standalone Server
go run cmd/geoip-server/main.go
The server runs on port 8080 and exposes a POST endpoint at /geo
:
curl -X POST \
-H "Content-Type: application/json" \
-d '{"ip":"8.8.8.8"}' \
http://localhost:8080/geo
curl -X POST \
-H "Content-Type: application/json" \
-d '{"addresses": ["1.1.1.1", "8.8.8.8"]}' \
http://localhost:8080/geo
As a Library
import "0xacab.org/leap/geoip-service/pkg/geoip"
svc, err := geoip.NewService(&api.Config{
EnableRateLimit: true,
RateLimit: 100,
LogEnabled: true,
})
e.POST("/geo", svc.Handler())
Response Format
Example response for Google's and Cloudflare's DNS (1.1.1.1, 8.8.8.8):
{"geolocation":{"1.1.1.1":{"as_name":"Cloudflare, Inc.","asn":13335,"cc":"AU"},"8.8.8.8":{"as_name":"Google LLC","asn":15169,"cc":"US"}},"v":1}
Special cases:
Features
- IP geolocation lookup (ASN, country code, network name)
- Rate limiting support
- Configurable logging
- Echo middleware integration
Rate Limiting
The service supports rate limiting to prevent abuse. The rate limit is set to
1 request per second by default and can be configured using the --rate-limit
flag or the GEOIP_RATE_LIMIT
environment variable.
Be aware that this feature is using echo's rate limiter
middleware. From their
docs:
RateLimiter
provides a Rate Limiter middleware for limiting the amount of
requests to the server from a particular IP or id within a time period.
By default an in-memory store is used for keeping track of requests. The default
in-memory implementation is focused on correctness and may not be the best
option for a high number of concurrent requests or a large number of different
identifiers (>16k).
Architecture
The service has the following structure:
cmd/geoip-server/
: Contains the main binary entrypoint
internal/service/
: Core service implementation
pkg/api/
: Public API interfaces and types
pkg/geoip/
: Service initialization and configuration
Dependencies
Uses OONI's probe-engine/pkg/geoipx for GeoIP lookups, which provides a wrapper around MaxMind's GeoIP database.
In case this dependency stops being maintained, it should not be difficult to
move it to our own namespace; at any rate, it's going to be less cumbersome than
maintaining the legacy geolocation service.
Alternatively, bitmask-core can support external geolocation services, which at
least should facilitate testing and it means maintaining less infrastructure for
a small provider.
Configuration
type Config struct {
Port string
RateLimit float64
EnableRateLimit bool
LogEnabled bool
}
Configuration
The service can be configured using either command-line flags or environment variables:
--port | GEOIP_PORT | 8080 | Server port |
--rate-limit | GEOIP_RATE_LIMIT | 1 | Rate limit (requests/second) |
--enable-rate-limit | GEOIP_ENABLE_RATE_LIMIT | true | Enable rate limiting |
--log-enabled | GEOIP_LOG_ENABLED | true | Enable request logging |
Examples
Using flags:
./geoip-server --port=9090 --rate-limit=50 --enable-rate-limit=false
Using environment variables:
export GEOIP_PORT=9090
export GEOIP_RATE_LIMIT=50
export GEOIP_ENABLE_RATE_LIMIT=false
./geoip-server
License
GPLv3