Simple IP Geolocation command written in Go.
Special thanks to MaxMind for its generosity providing free Gelocation database.
Without their free database available here, goip
does not work.
Set up Go environment (esp. GOPATH
environment variable), and do following:
$ go get github.com/cinsk/goip
By default, goip
will download free MaxMind geolocation database (zip format), unpack it, load it, then it will serve the requests. This may be helpful if you do not want to download the database manually, but it will take several minutes to become ready.
To speed up, try to download the zip file manually by visiting MaxMind, and select GeoLite2 City, CSV format, zipped link. Then unpack the zip file, and provide the directory name using -u
option:
$ wget -q 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-City-CSV.zip'
$ unzip GeoLite2-City-CSV.zip
Archive: GeoLite2-City-CSV.zip
inflating: GeoLite2-City-CSV_20171205/GeoLite2-City-Blocks-IPv4.csv
...
$ goip -d GeoLite2-City-CSV_20171205 ...
goip
will listen its standard output for the list of IP addresses, and print the information of the IP addresses. The information includes the name of city with the country code, and the number of occurrance (a.k.a. population), and the city's longitude and latitude. If the country or city name is not known, it will be printed as UNKNOWN, unless -U
option was given.
$ cat ip.lst
111.111.111.111
221.159.164.3
221.159.164.3
$ cat ip.lst | goip
name,pop,lat,lon,group
"KR: Boseong",2,34.7697,127.0809,1
"JP: Tokyo",1,35.685,139.7514,1
You can change the output format from csv to text (each line delimited by a tab character):
$ cat ip.lst | ./goip -t text
name pop lat lon group
KR: Boseong 2 34.7697 127.0809 0
JP: Tokyo 1 35.685 139.7514 0
All output is sorted by 'pop' field (the number of occurrence), descending order, limited to 1000 entries. Use -l xxx
to change the limit to xxx
. Use negative limit (e.g. -l -1
) for the unlimited output.
To change the order of fields, or number of fields, use -o FIELDS
options where FIELDS are list of fields separated by comma. Supported names are name, lat, lon, pop, and group:
$ cat ip.lst | goip -o name,pop
name,pop
"KR: Boseong",2
"JP: Tokyo",1
goip
supports simple clustering of entries, useful for clustering its output (via output field group). It uses simplified k-means clustering for grouping, 20 iteration at most. If you want to change the number of iteration to XXX, use -G XXX
option.
The group(cluster) id begins with zero, upto 5 by default. To change the number of groups, use -g NGROUP
option. Note that the output may contain less number of groups. If NGROUP is negative, grouping/clustering will be disabled.
If you provide a TCP listening address and port via -T address:port
, goip
will listen address:port
beside reading standard input. Note that even in this mode, goip
will still try to read from standard input. If you close the standard input, goip
will terminate instantly.
$ ./goip -T localhost:8888
server ready
You can use any TCP client such as nc(1)
or netcat(1)
to communicate with goip
server.
Unless special command which begins with .
or !
character, goip
assumes each line (delimited by \n
character) contains an IP addrese.
$ echo 221.159.164.3 | nc localhost 8888
KR:Boseong
[After 5 seconds...]
$ _
$ cat ip.lst
111.111.111.111
221.159.164.3
221.159.164.3
$ cat ip.lst | nc localhost 8888
JP:Tokyo
KR:Boseong
KR:Boseong
[After 5 seconds...]
$ _
The connection to the goip
server will be automatically closed after 5 seconds on idle. Or, you can request explicit disconnect via .quit
command:
$ echo -e '221.159.164.3\n.quit' | nc localhost 8888
KR:Boseong
$ _
Or, you can create a bash function like this:
geoip() {
local IFS=$'\n'
local args="$*"
echo -e "${args}\n.quit" | nc localhost 8888
}
And use like this:
$ geoip 1.1.1.1 2.2.2.2 3.3.3.3
AU:Research
FR:UNKNOWN
US:Fairfield
$ _
It also supports .stat
command that will give you the same statisticial output in batch mode, and .reset
to clear internal data for .stat
command.
Note that .stat
command is very expensive, and goip
does not handle more than 1 request at a time. If you're looking for a sturdy server for querying geolocation, consider to use other solution such as freegeoip.
Look at the article Visualize IP on World Map for goip
usecase.