# is a public web service for searching
[geolocation]( of IP addresses.
This is the source code of's web server and script for building
the IP database.

## Overview is the result of a web server research project that started in
2009 hosted at Google's [App Engine](,
using the Python API.
A year later it moved to its own server infrastructure built on the
[Cyclone]( web framework, backed by
[Twisted]( and [PyPy](

The current version is written in Go as the experiments progress with
[go-web]( and

### Install

List of prerequisites for building and running the server:

- Go compiler - for `freegeoip.go`
- libsqlite3-dev, gcc or llvm - for dependency `go-sqlite3`
- Python - for the `updatedb` script
- Redis - (optional) for API usage quotas
- The IP database

The following instructions are for Debian and Ubuntu servers.

Make sure Go is installed and both $GOROOT and $GOPATH are set, then run:

	apt-get install build-essential libsqlite3-dev pkg-config
	go get
	cd $GOPATH/src/
	go build

On recent OSX you might have to set the CC=clang before `go build` if
the sqlite3 package fails to compile.

Proceed to building the IP database before starting the server.

### Building the IP database

The IP database is composed of multiple files from multiple sources. It's a
combination of IP subnets, country codes, city names, etc.

There's a helper script under the `db` directory that automates the process
of building the database, and can be used regularly to update it as well.

It's a Python script called `updatedb` that creates `ipdb.sqlite`:

	$ cd db
	$ ./updatedb
	... will download files and process them to create ipdb.sqlite
	$ file ipdb.sqlite
	ipdb.sqlite: SQLite 3.x database

This service includes GeoLite data created by MaxMind, available from

## Running

The server looks for `freegeoip.conf` in the current directory, but an
alternative config can be specified using the `-config` command line option.

If the server is proxied by Nginx or another HTTP load balancer, edit the
configuration file and set `xheaders="true"` and it'll use X-Real-IP or
X-Forwarded-For HTTP headers (when available) as the client IP.

Run the server:

	./freegeoip [-config /path/to/freegeoip.conf]

Then point the browser to http://localhost:8080.

If the IP database is unavailable (e.g. file does not exist, bad permissions)
or redis is unreachable (if using redis as the quota backend), all queries
will result in HTTP 503 (Service Unavailable).

For listening on low ports as non-root user (e.g. www-data) on linux, set
file capabilities at least once before running it:

	/sbin/setcap 'cap_net_bind_service=+ep' /opt/freegeoip/freegeoip

### Running with upstart

This method requires [go-daemon]( for
changing runtime permissions and managing pid and log files.

On Ubuntu, use the following upstart script in `/etc/init/freegeoip.conf`
to start and stop the server:

	# freegeoip web service

	description "freegeoip web service"

	start on runlevel [2345]
	stop on runlevel [!2345]

	pre-start script
		/sbin/setcap 'cap_net_bind_service=+ep' /opt/freegeoip/freegeoip
	end script

	limit nofile 4096 4096
	exec /usr/bin/god -f -n -l /var/log/freegeoip.log -p /var/run/ -r /opt/freegeoip -u www-data -g www-data ./freegeoip

Then use `start freegeoip` and `stop freegeoip` to start and stop the server.

Also, use the following configuration file in `/etc/logrotate.d/freegeoip` for
log rotation:

		rotate 7
			reload freegeoip > /dev/null 2>&1

### Running with supervisord

Use [supervisor]( with the following config in


Then use `supervisorctl start freegeoip` and `supervisorctl stop freegeiop`
to start and stop the server.

## Usage

Point the browser to http://localhost:8080 and search for IPs or hostnames.

Use curl from the command line to query the API:

	$ curl -v http://localhost:8080/{format}/{ip_or_hostname}

It supports csv, json and xml as the output format. JSON supports callbacks
with the `callback` query argument. The client (self) IP is used if
`ip_or_hostname` is omitted in the query.


	$ curl -v http://localhost:8080/csv/
	$ curl -v http://localhost:8080/xml/
	$ curl -v http://localhost:8080/xml/
	$ curl -v http://localhost:8080/json/

If the server is listening on unix sockets, use `nc` to test:

	echo -ne 'GET /json/ HTTP/1.0\r\n\r\n' | nc -U /tmp/freegeoip.sock

## Credits

Thanks to (in no particular order):

- [Gleicon]( for all the drama.
- Google for the map, Go, and AngularJS.
- Twitter for Bootstrap.
- MaxMind for the current database.
- for both the IP and timezones database back in 2010 and 2011.

Imports 3 package(s) ΒΆ