Categorygithub.com/webklex/gogeoip
module
0.0.0-20200915151317-5e0ec4f4e715
Repository: https://github.com/webklex/gogeoip.git
Documentation: pkg.go.dev

# README

GoGeoIP Web API

GoGeoIP - a lightweight web api providing ip intelligence written in GO. This software provides an api to get as many information as possible for a given IP address or the current visitor. This includes network, system, location and user information. A Live Demo is available under gogeoip.com.

Releases Downloads Demo License Hits

geo_ip_web_gui

Table of Contents

Features

  • Serving over HTTPS (TLS) using your own certificates, or provisioned automatically using LetsEncrypt.org
  • HSTS ready to restrict your browser clients to always use HTTPS
  • Configurable read and write timeouts to avoid stale clients consuming server resources
  • Reverse proxy ready
  • Configurable CORS to restrict access to specific domains
  • Configurable api prefix to serve the API alongside other APIs on the same host
  • Optional round trip optimization by enabling TCP Fast Open
  • Integrated rate limit (quota) for your clients (per client IP) based on requests per time interval; several backends such as in-memory map (for single instance), or redis or memcache for distributed deployments are supported
  • Serve the default GeoLite2 City free database that is downloaded and updated automatically in background on a configurable schedule, or
  • Serve the commercial GeoIP2 City database from MaxMind, either as a local file that you provide and update periodically (so the server can reload it), or configured to be downloaded periodically using your API key
  • Serve the default PX8LITEBIN free database that is downloaded and updated automatically in background on a configurable schedule, or
  • Serve the commercial PX8BIN database from ip2location, either as a local file that you provide and update periodically (so the server can reload it), or configured to be downloaded periodically using your API token
  • Multiple languages are supported (en, ru, es, jp, fr, de)
  • Detect VPN anonymizer, open proxies, web proxies, Tor exits, data center, web hosting (DCH) range and search engine robots (SES).
  • Supports Linux, OS X, FreeBSD, and Windows
  • Setup wizard

Requirements

A Free MaxMind and / or ip2location License will be required and can be easily obtained:

  1. Sign up for a MaxMind account (no purchase required)
  2. Set your password and create a license key
  3. Sign up for a IP2Location account (no purchase required)
  4. Create access token

Installation

Download and unpack a fitting pre-compiled binary or build a binary yourself by by following the build instructions.

Continue by configuring your application:

geoip \
    -mm-user-id 100000 \
    -mm-license-key 0AAaAaaAa0A0AAaA \
    -i2l-token 0BBbBbbBb0B0BBbB \
    -http=:8080 \
    -gui gui \
    -save

Open a browser and navigate to http://localhost:8080/ to verify everything is working.

Please take a look at the available options for further details.

GUI

An example GUI can be found under webklex/gogeoip-gui. It is already included in the pre-compiled packages found under releases.

Server Options

To see all the available options, use the -help option:

geoip -help

You can configure the web server via command line flags, the config file conf/settings.config or by using the -setup flag:

geoip -setup

HTTP & HTTPS

CLIConfigTypeDefaultDescription
-httpHTTPstringlocalhost:8080Address in form of ip:port to listen
-httpsHTTPSstringAddress in form of ip:port to listen
-write-timeoutWRITE_TIMEOUTint15000000000Write timeout in nanoseconds for HTTP and HTTPS client connections
-read-timeoutREAD_TIMEOUTint30000000000Read timeout in nanoseconds for HTTP and HTTPS client connections
-tcp-fast-openTCP_FAST_OPENboolfalseEnable TCP fast open
-tcp-naggleTCP_NAGGLEboolfalseEnable TCP Nagle's algorithm
-http2HTTP2booltrueEnable HTTP/2 when TLS is enabled
-hstsHSTSstring
-keyKEYstringkey.pemX.509 key file for HTTPS server
-certCERTstringcert.pemX.509 certificate file for HTTPS server

Letsencrypt

CLIConfigTypeDefaultDescription
-letsencryptLETSENCRYPTboolfalseEnable automatic TLS using letsencrypt.org
-letsencrypt-emailLETSENCRYPT_EMAILstringOptional email to register with letsencrypt
-letsencrypt-hostsLETSENCRYPT_HOSTSstringComma separated list of hosts for the certificate
-letsencrypt-cert-dirLETSENCRYPT_CERT_DIRstringLetsencrypt cert dir

Middlewares & Extensions

CLIConfigTypeDefaultDescription
-use-x-forwarded-forUSE_X_FORWARDED_FORboolfalseUse the X-Forwarded-For header when available (e.g. behind proxy)
-cors-originCORS_ORIGINstring*Comma separated list of CORS origins endpoints
-api-prefixAPI_PREFIXstring/API endpoint prefix
-guiGUIstringWeb gui directory
Rate limiting & Quota management
CLIConfigTypeDefaultDescription
-quota-backendQUOTA_BACKENDstringredisBackend for rate limiter: map, redis, or memcache
-quota-burstQUOTA_BURSTint3Max requests per source IP per request burst
-quota-intervalQUOTA_INTERVALint3600000000000Quota expiration interval, per source IP querying the API in nanoseconds
-quota-maxQUOTA_MAXint1"Max requests per source IP per interval; set 0 to turn quotas off

MaxMind

CLIConfigTypeDefaultDescription
-mm-license-keyMM_LICENSE_KEYstringMaxMind License Key
-mm-user-idMM_USER_IDstringMaxMind User ID
-mm-product-idMM_PRODUCT_IDstringGeoLite2-CityMaxMind Product ID
-mm-retryMM_RETRY_INTERVALint7200000000000Max time to wait before retrying to download a MaxMind database
-mm-updateMM_UPDATE_INTERVALint86400000000000MaxMind database update check interval in nanoseconds
-mm-updates-hostMM_UPDATES_HOSTstringdownload.maxmind.comMaxMind Updates Host

ip2location

CLIConfigTypeDefaultDescription
-i2l-tokenI2L_TOKENstringip2location access token
-i2l-product-idI2L_PRODUCT_IDstringPX8LITEBINip2location Product ID
-i2l-retryI2L_RETRY_INTERVALint7200000000000Max time to wait before retrying to download a ip2location database
-i2l-updateI2L_UPDATE_INTERVALint86400000000000ip2location database update check interval in nanoseconds
-i2l-updates-hostI2L_UPDATES_HOSTstringwww.ip2location.comip2location Updates Host

Tor Project

CLIConfigTypeDefaultDescription
-tor-exit-checkTOR_EXITstring8.8.8.8MaxMind Product ID
-tor-retryTOR_RETRY_INTERVALint7200000000000Max time in nanoseconds to wait before retrying to download database
-tor-updateTOR_UPDATE_INTERVALint86400000000000Database update check interval in nanoseconds
-tor-updates-hostTOR_UPDATES_HOSTstringcheck.torproject.orgMaxMind Updates Host

Logging

CLIConfigTypeDefaultDescription
-logtostdoutLOGTOSTDOUTboolfalseLog to stdout instead of stderr
-log-fileLOG_FILEstringLog file location
-logtimestampLOGTIMESTAMPbooltruePrefix non-access logs with timestamp

Memcache

CLIConfigTypeDefaultDescription
-memcacheMEMCACHEstringlocalhost:11211Memcache address in form of host:port[,host:port] for quota
-memcache-timeoutMEMCACHE_TIMEOUTint1000000000Memcache read/write timeout in nanoseconds

Redis

CLIConfigTypeDefaultDescription
-redisREDISstringlocalhost:6379Redis address in form of host:port[,host:port] for quota
-redis-timeoutREDIS_TIMEOUTint1000000000Redis read/write timeout in nanoseconds

Additional

CLIConfigTypeDefaultDescription
-silentSILENTboolfalseDisable HTTP and HTTPS log request details
-configstringconf/settings.configConfig file path
-setupboolfalseRun the setup wizard
-saveboolfalseSave config
-versionboolfalseShow version and exit
-helpboolfalseShow help and exit

If you're using LetsEncrypt.org to provision your TLS certificates, you have to listen for HTTPS on port 443. Following is an example of the server listening on 2 different ports: http (80) and https (443):

geoip \
    -mm-user-id 100000 \
    -mm-license-key 0AAaAaaAa0A0AAaA \
    -i2l-token 0BBbBbbBb0B0BBbB \
    -http=:8080 \
    -https=:8443 \
    -hsts=max-age=31536000 \
    -letsencrypt \
    -letsencrypt-hosts=example.com \
    -gui gui \
    -save
$ cat conf/settings.config
{
    "MM_USER_ID": "100000",
    "MM_LICENSE_KEY": "0AAaAaaAa0A0AAaA",
    "HTTP": ":8080",
    "HTTPS": ":8443",
    "HSTS": "max-age=31536000",
    "LETSENCRYPT": true,
    "LETSENCRYPT_HOSTS": "example.com",
    ...

By default, HTTP/2 is enabled over HTTPS. You can disable by passing the -http2=false flag.

If the web server is running behind a reverse proxy or load balancer, you have to run it passing the -use-x-forwarded-for parameter and provide the X-Forwarded-For HTTP header in all requests. This is for the geoip web server be able to log the client IP, and to perform geolocation lookups when an IP is not provided to the API, e.g. /json/ (uses client IP) vs /json/1.2.3.4.

Databases

The current implementation uses the free GeoLite2 City database from MaxMind as well as the free IP2Proxy database from ip2location and the generic tor exit node list provided by the TorProject. If you have purchased the commercial database from MaxMind or ip2location, you can point the geoip web server or (Go API, for dev) to the URL containing the file, or local file, and the server will use it. In case of files on disk, you can replace the file with a newer version and the geoip web server will reload it automatically in background. If instead of a file you use a URL (the default), we periodically check the URL in background to see if there's a new database version available, then download the reload it automatically.

All responses from the geoip API contain the date that the database was downloaded in the X-Database-Date HTTP header.

API

The API is served by endpoints that encode the response in different formats. You can pass a different IP or hostname. For example, to lookup the geolocation of github.com the server resolves the name first, then uses the first IP address available, which might be IPv4 or IPv6:

curl :8080/json/{ip or hostname}?lang={language}[&user]

Same semantics are available for the /xml/{ip} and /csv/{ip} endpoints. JSON responses can be encoded as JSONP, by adding the callback parameter:

The used default language depends on the present Accept-Language header. You can define the used language by providing a lang parameter containing the two digit country code (en, ru, es, fr, de, jp).

Add the user parameter to the end to receive user device specific information. Please see the JSON example for output details.

Output

Network

NameValue typeJSONXMLCSVComment
IP addressstringipIP0
Number (ASN)integeras.numberAS.Number1
Organizationstringas.nameAS.Name2
ISP namestringispIsp3
DomainstringdomainDomain4
TLDs[]stringtldTld5
Is botboolbotBot6
Is tor userbooltorTor7
Is proxy userboolproxyProxy8
Proxy typestringproxy_typeProxyType9Available proxy types
Last seen in daysintegerlast_seenLastSeen10
Usage typestringusage_typeUsageType11Available usage types

Location

NameValue typeJSONXMLCSVComment
Region codestringregion_codeRegionCode12
Region namestringregion_nameRegionName13
City namestringcityCity14
Zip codestringzip_codeZipCode15
Time zonestringtime_zoneTimeZone16
LatitudefloatlatitudeLatitude17
LongitudefloatlongitudeLongitude18
Accuracy radiusintegeraccuracy_radiusAccuracyRadius19
Metro codeintegermetro_codeMetroCode20
Country codestringcountry.codeCountry.Code21
CIOCstringcountry.ciocCountry.CIOC22
CCN3stringcountry.ccn3Country.CCN323
Call codes[]stringcountry.call_codeCountry.CallCode24
International call prefixstringcountry.international_prefixCountry.InternationalPrefix25
Country capitalstringcountry.capitalCountry.Capital26
Country namestringcountry.nameCountry.Name27
Full country namestringcountry.full_nameCountry.FullName28
Country Area km²integercountry.areaCountry.Area29
Country borders[]stringcountry.bordersCountry.Borders30
Latitudefloatcountry.latitudeCountry.Latitude31
Longitudefloatcountry.longitudeCountry.Longitude32
Max. Latitudefloatcountry.max_latitudeCountry.MaxLatitude33
Max. Longitudefloatcountry.max_longitudeCountry.MaxLongitude34
Min. Latitudefloatcountry.min_latitudeCountry.MinLatitude35
Min. Longitudefloatcountry.min_longitudeCountry.MinLongitude36
Currencies[]{code,name}country.currencyCountry.Currency37
Continent codestringcountry.content.codeCountry.Continent.Code38
Continent namestringcountry.content.nameCountry.Continent.Name39
Continent sub regionstringcountry.content.sub_regionCountry.Continent.SubRegion40

System

NameValue typeJSONXMLCSVComment
Operating SystemstringosOS41
System architecturestringos_versionOSVersion42
BrowserstringbrowserBrowser43
Browser VersionstringversionVersion44
Device namestringdeviceDevice45
Is mobile userboolmobileMobile46
Is tablet userbooltabletTablet47
Is desktop userbooldesktopDesktop48

User

NameValue typeJSONXMLCSVComment
Languagestringlanguage.languageLanguage.Language49
Language regionstringlanguage.regionLanguage.Region50
Language tagstringlanguage.tagLanguage.Tag51

CSV

curl :8080/csv/208.13.138.36
208.13.138.36,209,"CenturyLink Communications, LLC",,,.us,0,0,0,,0,,NV,,Las Vegas,839,89129,America/Los_Angeles,-115.2821,36.2473,20,US,USA,840,1,011,Washington D.C.,United States,United States of America,9372610.0000,CAN/MEX,39.4433,-98.9573,71.4411,-66.8854,17.8315,-179.2311,USD/USN/USS,,
curl :8080/csv/208.13.138.36?user
208.13.138.36,209,"CenturyLink Communications, LLC",,,.us,0,0,0,,0,,NV,,Las Vegas,839,89129,America/Los_Angeles,-115.2821,36.2473,20,US,USA,840,1,011,Washington D.C.,United States,United States of America,9372610.0000,CAN/MEX,39.4433,-98.9573,71.4411,-66.8854,17.8315,-179.2311,USD/USN/USS,,,Linux,Ubuntu Chromium,79.0.3945.79,x86_64,,0,0,1,en,US,en-US

XML

curl :8080/xml/208.13.138.36
<Response>
    <Network>
        <IP>208.13.138.36</IP>
        <AS>
            <Number>209</Number>
            <Name>CenturyLink Communications, LLC</Name>
        </AS>
        <Isp/>
        <Domain/>
        <Tld>.us</Tld>
        <Bot>false</Bot>
        <Tor>false</Tor>
        <Proxy>false</Proxy>
        <ProxyType/>
        <LastSeen>0</LastSeen>
        <UsageType/>
    </Network>
    <Location>
        <RegionCode>NV</RegionCode>
        <RegionName/>
        <City>Las Vegas</City>
        <ZipCode>89129</ZipCode>
        <TimeZone>America/Los_Angeles</TimeZone>
        <Longitude>-115.2821</Longitude>
        <Latitude>36.2473</Latitude>
        <AccuracyRadius>20</AccuracyRadius>
        <MetroCode>839</MetroCode>
        <Country>
            <Code>US</Code>
            <CIOC>USA</CIOC>
            <CCN3>840</CCN3>
            <CallCode>1</CallCode>
            <InternationalPrefix>011</InternationalPrefix>
            <Capital>Washington D.C.</Capital>
            <Name>United States</Name>
            <FullName>United States of America</FullName>
            <Area>9.37261e+06</Area>
            <Borders>CAN</Borders>
            <Borders>MEX</Borders>
            <Latitude>39.443256</Latitude>
            <Longitude>-98.95734</Longitude>
            <MaxLatitude>71.441055</MaxLatitude>
            <MaxLongitude>-66.885414</MaxLongitude>
            <MinLatitude>17.831509</MinLatitude>
            <MinLongitude>-179.23108</MinLongitude>
            <Currency>
                <Code>USD</Code>
                <Name/>
            </Currency>
            <Currency>
                <Code>USN</Code>
                <Name/>
            </Currency>
            <Currency>
                <Code>USS</Code>
                <Name/>
            </Currency>
            <Continent>
                <Code/>
                <Name>North America</Name>
                <SubRegion/>
            </Continent>
        </Country>
    </Location>
</Response>
curl :8080/xml/208.13.138.36?user
<Response>
    <Network>
        <IP>208.13.138.36</IP>
        <AS>
            <Number>209</Number>
            <Name>CenturyLink Communications, LLC</Name>
        </AS>
        <Isp/>
        <Domain/>
        <Tld>.us</Tld>
        <Bot>false</Bot>
        <Tor>false</Tor>
        <Proxy>false</Proxy>
        <ProxyType/>
        <LastSeen>0</LastSeen>
        <UsageType/>
    </Network>
    <Location>
        <RegionCode>NV</RegionCode>
        <RegionName/>
        <City>Las Vegas</City>
        <ZipCode>89129</ZipCode>
        <TimeZone>America/Los_Angeles</TimeZone>
        <Longitude>-115.2821</Longitude>
        <Latitude>36.2473</Latitude>
        <AccuracyRadius>20</AccuracyRadius>
        <MetroCode>839</MetroCode>
        <Country>
            <Code>US</Code>
            <CIOC>USA</CIOC>
            <CCN3>840</CCN3>
            <CallCode>1</CallCode>
            <InternationalPrefix>011</InternationalPrefix>
            <Capital>Washington D.C.</Capital>
            <Name>United States</Name>
            <FullName>United States of America</FullName>
            <Area>9.37261e+06</Area>
            <Borders>CAN</Borders>
            <Borders>MEX</Borders>
            <Latitude>39.443256</Latitude>
            <Longitude>-98.95734</Longitude>
            <MaxLatitude>71.441055</MaxLatitude>
            <MaxLongitude>-66.885414</MaxLongitude>
            <MinLatitude>17.831509</MinLatitude>
            <MinLongitude>-179.23108</MinLongitude>
            <Currency>
                <Code>USD</Code>
                <Name/>
            </Currency>
            <Currency>
                <Code>USN</Code>
                <Name/>
            </Currency>
            <Currency>
                <Code>USS</Code>
                <Name/>
            </Currency>
            <Continent>
                <Code/>
                <Name>North America</Name>
                <SubRegion/>
            </Continent>
        </Country>
    </Location>
    <System>
        <OS>Linux</OS>
        <Browser>Ubuntu Chromium</Browser>
        <Version>79.0.3945.79</Version>
        <OSVersion>x86_64</OSVersion>
        <Device/>
        <Mobile>false</Mobile>
        <Tablet>false</Tablet>
        <Desktop>true</Desktop>
    </System>
    <User>
        <Language>
            <Language>en</Language>
            <Region>US</Region>
            <Tag>en-US</Tag>
        </Language>
    </User>
</Response>

JSON

curl :8080/json/208.13.138.36
{
  "network": {
    "ip": "208.13.138.36",
    "as": {
      "number": 209,
      "name": "CenturyLink Communications, LLC"
    },
    "isp": "",
    "domain": "",
    "tld": [".us"],
    "bot": false,
    "tor": false,
    "proxy": false,
    "proxy_type": "",
    "last_seen": 0,
    "usage_type": ""
  },
  "location": {
    "region_code": "NV",
    "region_name": "",
    "city": "Las Vegas",
    "zip_code": "89129",
    "time_zone": "America/Los_Angeles",
    "longitude": -115.2821,
    "latitude": 36.2473,
    "accuracy_radius": 20,
    "metro_code": 839,
    "country": {
      "code": "US",
      "cioc": "USA",
      "ccn3": "840",
      "call_code": ["1"],
      "international_prefix": "011",
      "capital": "Washington D.C.",
      "name": "United States",
      "full_name": "United States of America",
      "area": 9372610,
      "borders": ["CAN", "MEX"],
      "latitude": 39.443256,
      "longitude": -98.95734,
      "max_latitude": 71.441055,
      "max_longitude": -66.885414,
      "min_latitude": 17.831509,
      "min_longitude": -179.23108,
      "currency": [{
          "code": "USD",
          "name": ""
       }, {
          "code": "USN",
          "name": ""
       }, {
          "code": "USS",
          "name": ""
      }],
      "continent": {
        "code": "",
        "name": "North America",
        "sub_region": ""
      }
    }
  }
}
curl :8080/json/208.13.138.36?user
{
  "network": {
    "ip": "208.13.138.36",
    "as": {
      "number": 209,
      "name": "CenturyLink Communications, LLC"
    },
    "isp": "",
    "domain": "",
    "tld": [".us"],
    "bot": false,
    "tor": false,
    "proxy": false,
    "proxy_type": "",
    "last_seen": 0,
    "usage_type": ""
  },
  "location": {
    "region_code": "NV",
    "region_name": "",
    "city": "Las Vegas",
    "zip_code": "89129",
    "time_zone": "America/Los_Angeles",
    "longitude": -115.2821,
    "latitude": 36.2473,
    "accuracy_radius": 20,
    "metro_code": 839,
    "country": {
      "code": "US",
      "cioc": "USA",
      "ccn3": "840",
      "call_code": ["1"],
      "international_prefix": "011",
      "capital": "Washington D.C.",
      "name": "United States",
      "full_name": "United States of America",
      "area": 9372610,
      "borders": ["CAN", "MEX"],
      "latitude": 39.443256,
      "longitude": -98.95734,
      "max_latitude": 71.441055,
      "max_longitude": -66.885414,
      "min_latitude": 17.831509,
      "min_longitude": -179.23108,
      "currency": [{
          "code": "USD",
          "name": ""
       }, {
          "code": "USN",
          "name": ""
       }, {
          "code": "USS",
          "name": ""
      }],
      "continent": {
        "code": "",
        "name": "North America",
        "sub_region": ""
      }
    }
  },
  "system": {
    "os": "Linux",
    "browser": "Ubuntu Chromium",
    "version": "79.0.3945.79",
    "os_version": "x86_64",
    "device": "",
    "mobile": false,
    "tablet": false,
    "desktop": true
  },
  "user": {
    "language": {
      "language": "en",
      "region": "US",
      "tag": "en-US"
    }
  }
}

JSONP

curl :8080/json/208.13.138.36?callback=foobar
foobar({
 "network": {
   "ip": "208.13.138.36",
   "as": {
     "number": 209,
     "name": "CenturyLink Communications, LLC"
   },
   "isp": "",
   "domain": "",
   "tld": [".us"],
   "bot": false,
   "tor": false,
   "proxy": false,
   "proxy_type": "",
   "last_seen": 0,
   "usage_type": ""
 },
 "location": {
   "region_code": "NV",
   "region_name": "",
   "city": "Las Vegas",
   "zip_code": "89129",
   "time_zone": "America/Los_Angeles",
   "longitude": -115.2821,
   "latitude": 36.2473,
   "accuracy_radius": 20,
   "metro_code": 839,
   "country": {
     "code": "US",
     "cioc": "USA",
     "ccn3": "840",
     "call_code": ["1"],
     "international_prefix": "011",
     "capital": "Washington D.C.",
     "name": "United States",
     "full_name": "United States of America",
     "area": 9372610,
     "borders": ["CAN", "MEX"],
     "latitude": 39.443256,
     "longitude": -98.95734,
     "max_latitude": 71.441055,
     "max_longitude": -66.885414,
     "min_latitude": 17.831509,
     "min_longitude": -179.23108,
     "currency": [{
         "code": "USD",
         "name": ""
      }, {
         "code": "USN",
         "name": ""
      }, {
         "code": "USS",
         "name": ""
     }],
     "continent": {
       "code": "",
       "name": "North America",
       "sub_region": ""
     }
   }
 }
});

The callback parameter is ignored on all other endpoints.

Build

You can build your own binaries by calling build.sh

build.sh build_dir

Features & pull requests

Everyone can contribute to this project. Every pull request will be considered but it can also happen to be declined. To prevent unnecessary work, please consider to create a feature issue first, if you're planning to do bigger changes. Of course you can also create a new feature issue if you're just wishing a feature ;)

Off topic, rude or abusive issues will be deleted without any notice.

Support

If you encounter any problems or if you find a bug, please don't hesitate to create a new issue. However please be aware that it might take some time to get an answer.

If you need immediate or commercial support, feel free to send me a mail at [email protected].

Change log

Please see CHANGELOG for more information what has changed recently.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

# Packages

No description provided by the author