Skip to content

Commit 8f17dae

Browse files
committed
Update to use GeoIP2 database.
The legacy databases we were using were discontinued (https://support.maxmind.com/geolite-legacy-discontinuation-notice/), so we need to use a different nginx plugin to integrate with the newer GeoLite2 databases. #440
1 parent 1f2ce6d commit 8f17dae

File tree

13 files changed

+96
-101
lines changed

13 files changed

+96
-101
lines changed

Taskfile.yml

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
# within the dependency chain. We use these stamp files so that the
1616
# checksumming approach properly invalidates the entire chain of dependencies
1717
# when build files change (whereas just using "deps" in go-task doesn't fully
18-
# work for multiple levels of dependencies). So, for example, if the libgeoip
19-
# dependency changes, rebuilding it properly cascades and triggers a rebuild
20-
# of openresty (1st level dependency) and luarocks (2nd level dependency).
18+
# work for multiple levels of dependencies). So, for example, if the
19+
# libmaxminddb dependency changes, rebuilding it properly cascades and
20+
# triggers a rebuild of openresty (1st level dependency) and luarocks (2nd
21+
# level dependency).
2122
# - For colorized output we use the "unbuffer" tool to force color output on
2223
# some commands, since Task doesn't easily support detecting colorized output
2324
# (as of the output changes in 2.0.3):
@@ -91,14 +92,14 @@ tasks:
9192
- ./build/work/stamp/deps/libfastjson
9293
method: checksum
9394

94-
deps:libgeoip:
95+
deps:libmaxminddb:
9596
cmds:
96-
- ./tasks/deps/libgeoip
97+
- ./tasks/deps/libmaxminddb
9798
sources:
98-
- ./tasks/deps/libgeoip
99+
- ./tasks/deps/libmaxminddb
99100
- ./tasks/helpers.sh
100101
generates:
101-
- ./build/work/stamp/deps/libgeoip
102+
- ./build/work/stamp/deps/libmaxminddb
102103
method: checksum
103104

104105
deps:luarocks:
@@ -136,11 +137,11 @@ tasks:
136137

137138
deps:openresty:
138139
deps:
139-
- deps:libgeoip
140+
- deps:libmaxminddb
140141
cmds:
141142
- ./tasks/deps/openresty
142143
sources:
143-
- ./build/work/stamp/deps/libgeoip
144+
- ./build/work/stamp/deps/libmaxminddb
144145
- ./tasks/deps/openresty
145146
- ./tasks/helpers.sh
146147
generates:
@@ -299,19 +300,6 @@ tasks:
299300
- ./build/work/stamp/app-deps/lua/cmsgpack
300301
method: checksum
301302

302-
app-deps:lua:iconv:
303-
deps:
304-
- deps:luarocks
305-
cmds:
306-
- ./tasks/app-deps/lua/iconv
307-
sources:
308-
- ./build/work/stamp/deps/luarocks
309-
- ./tasks/app-deps/lua/iconv
310-
- ./tasks/helpers.sh
311-
generates:
312-
- ./build/work/stamp/app-deps/lua/iconv
313-
method: checksum
314-
315303
app-deps:lua:icu-date:
316304
deps:
317305
- deps:luarocks
@@ -517,7 +505,6 @@ tasks:
517505
- task: app-deps:admin-ui:yarn
518506
- task: app-deps:lua:argparse
519507
- task: app-deps:lua:cmsgpack
520-
- task: app-deps:lua:iconv
521508
- task: app-deps:lua:icu-date
522509
- task: app-deps:lua:inspect
523510
- task: app-deps:lua:libcidr-ffi

scripts/rake/outdated_packages.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,15 @@ class OutdatedPackages
3636
"libfastjson" => {
3737
:git => "https://github.com/rsyslog/libfastjson.git",
3838
},
39-
"libgeoip" => {
40-
:git => "https://github.com/maxmind/geoip-api-c.git",
39+
"libmaxminddb" => {
40+
:git => "https://github.com/maxmind/libmaxminddb.git",
4141
},
4242
"lua_argparse" => {
4343
:luarock => "argparse",
4444
},
4545
"lua_cmsgpack" => {
4646
:luarock => "lua-cmsgpack",
4747
},
48-
"lua_iconv" => {
49-
:luarock => "lua-iconv",
50-
},
5148
"lua_icu_date" => {
5249
:git => "https://github.com/GUI/lua-icu-date.git",
5350
:git_ref => "master",
@@ -114,6 +111,9 @@ class OutdatedPackages
114111
:git => "https://github.com/emicklei/mora.git",
115112
:git_ref => "master",
116113
},
114+
"ngx_http_geoip2_module" => {
115+
:git => "https://github.com/leev/ngx_http_geoip2_module.git",
116+
},
117117
"nodejs" => {
118118
:git => "https://github.com/nodejs/node.git",
119119
:constraint => "~> 10.13",

src/api-umbrella/cli/setup.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,9 @@ local function ensure_geoip_db()
130130
-- If the city db path doesn't exist, copy it from the package installation
131131
-- location to the runtime location (this path will then be overwritten by
132132
-- the auto-updater so we don't touch the original packaged file).
133-
local city_db_path = path.join(config["db_dir"], "geoip/city-v6.dat")
133+
local city_db_path = path.join(config["db_dir"], "geoip/GeoLite2-City.mmdb")
134134
if not path.exists(city_db_path) then
135-
local default_city_db_path = path.join(config["_embedded_root_dir"], "var/db/geoip/city-v6.dat")
135+
local default_city_db_path = path.join(config["_embedded_root_dir"], "var/db/geoip/GeoLite2-City.mmdb")
136136
dir.makepath(path.dirname(city_db_path))
137137
file.copy(default_city_db_path, city_db_path)
138138
chmod(city_db_path, tonumber("0640", 8))

src/api-umbrella/proxy/hooks/init_preload_modules.lua

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ require "api-umbrella.utils.round"
5656
require "api-umbrella.utils.xpcall_error_handler"
5757
require "cjson"
5858
require "cmsgpack"
59-
require "iconv"
6059
require "icu-date"
6160
require "libcidr-ffi"
6261
require "lustache"

src/api-umbrella/proxy/log_utils.lua

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
local config = require "api-umbrella.proxy.models.file_config"
22
local escape_uri_non_ascii = require "api-umbrella.utils.escape_uri_non_ascii"
3-
local iconv = require "iconv"
43
local icu_date = require "icu-date"
54
local json_encode = require "api-umbrella.utils.json_encode"
65
local logger = require "resty.logger.socket"
@@ -232,34 +231,14 @@ function _M.cache_new_city_geocode(data)
232231
end
233232

234233
function _M.set_request_ip_geo_fields(data, ngx_var)
235-
-- The GeoIP module returns ISO-8859-1 encoded city names, but we need UTF-8
236-
-- for inserting into ElasticSearch.
237-
local geoip_city = ngx_var.geoip_city
238-
if geoip_city then
239-
local encoding_converter = iconv.new("utf-8//IGNORE", "iso-8859-1")
240-
local geoip_city_encoding_err
241-
geoip_city, geoip_city_encoding_err = encoding_converter:iconv(geoip_city)
242-
if geoip_city_encoding_err then
243-
ngx.log(ngx.ERR, "encoding error for geoip city: ", geoip_city_encoding_err, geoip_city)
244-
end
245-
end
246-
247-
-- The geoip database returns "00" for unknown regions sometimes:
248-
-- http://maxmind.com/download/geoip/kml/index.html Remove these and treat
249-
-- these as nil.
250-
local geoip_region = ngx_var.geoip_region
251-
if geoip_region == "00" then
252-
geoip_region = nil
253-
end
254-
255-
data["request_ip_city"] = geoip_city
256-
data["request_ip_country"] = ngx_var.geoip_city_country_code
257-
data["request_ip_region"] = geoip_region
234+
data["request_ip_city"] = ngx_var.geoip2_data_city_name
235+
data["request_ip_country"] = ngx_var.geoip2_data_country_code
236+
data["request_ip_region"] = ngx_var.geoip2_data_subdivision_code
258237

259-
local geoip_latitude = ngx_var.geoip_latitude
238+
local geoip_latitude = ngx_var.geoip2_data_latitude
260239
if geoip_latitude then
261240
data["request_ip_lat"] = tonumber(geoip_latitude)
262-
data["request_ip_lon"] = tonumber(ngx_var.geoip_longitude)
241+
data["request_ip_lon"] = tonumber(ngx_var.geoip2_data_longitude)
263242
end
264243
end
265244

tasks/app-deps/lua/iconv

Lines changed: 0 additions & 10 deletions
This file was deleted.

tasks/deps/geolitecity

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@ set +x
77
# If the file exists and was created within the past day, then skip doing
88
# anything else. This approach ensures that new files are downloaded, but only
99
# once per day.
10-
if [[ $(find "$STAGE_EMBEDDED_DIR/var/db/geoip/city-v6.dat" -mmin -1440) ]]; then
10+
if [[ $(find "$STAGE_EMBEDDED_DIR/var/db/geoip/GeoLite2-City.mmdb" -mmin -1440) ]]; then
1111
exit 0
1212
fi
1313

1414
set -x
1515

1616
task_working_dir
17-
curl --location --retry 3 --fail --remote-name https://geolite.maxmind.com/download/geoip/database/GeoLiteCityv6-beta/GeoLiteCityv6.dat.gz
18-
gunzip -c GeoLiteCityv6.dat.gz > GeoLiteCityv6.dat
19-
install -D -m 644 ./GeoLiteCityv6.dat "$STAGE_EMBEDDED_DIR/var/db/geoip/city-v6.dat"
17+
curl --location --retry 3 --fail --remote-name https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
18+
dir="GeoLite2-City"
19+
rm -rf "$dir"
20+
mkdir -p "$dir"
21+
tar -xf GeoLite2-City.tar.gz -C "$dir" --strip-components 1
22+
install -D -m 644 ./GeoLite2-City/GeoLite2-City.mmdb "$STAGE_EMBEDDED_DIR/var/db/geoip/GeoLite2-City.mmdb"
2023

2124
stamp

tasks/deps/libgeoip

Lines changed: 0 additions & 19 deletions
This file was deleted.

tasks/deps/libmaxminddb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
3+
libmaxminddb_version="1.3.2"
4+
libmaxminddb_hash="67a861965b30d045bf29a2126bcc05ed"
5+
6+
set -e -u -x
7+
source ./tasks/helpers.sh
8+
9+
task_working_dir
10+
download "https://github.com/maxmind/libmaxminddb/releases/download/$libmaxminddb_version/libmaxminddb-$libmaxminddb_version.tar.gz" "md5" "$libmaxminddb_hash"
11+
extract_download "libmaxminddb-$libmaxminddb_version.tar.gz"
12+
13+
cd "libmaxminddb-$libmaxminddb_version"
14+
./configure --prefix="$INSTALL_PREFIX_EMBEDDED"
15+
make -j"$NPROC"
16+
make install DESTDIR="$STAGE_DIR"
17+
find "$STAGE_EMBEDDED_DIR/bin/" -name "mmdblookup" -exec chrpath -d {} \;
18+
19+
stamp

tasks/deps/openresty

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/usr/bin/env bash
22

3+
ngx_http_geoip2_module_version="3.2"
4+
ngx_http_geoip2_module_hash="2e60d26460d178068f7a4e9a4e64990a"
35
openresty_version="1.13.6.2"
46
openresty_hash="d95bc4bbe15e4b045a0593b4ecc0db38"
57
openssl_version="1.0.2q"
@@ -21,6 +23,9 @@ extract_download "openssl-$openssl_version.tar.gz"
2123
download "https://openresty.org/download/openresty-$openresty_version.tar.gz" "md5" "$openresty_hash"
2224
extract_download "openresty-$openresty_version.tar.gz"
2325

26+
download "https://github.com/leev/ngx_http_geoip2_module/archive/$ngx_http_geoip2_module_version.tar.gz" "md5" "$ngx_http_geoip2_module_hash"
27+
extract_download "$ngx_http_geoip2_module_version.tar.gz"
28+
2429
cd "openresty-$openresty_version"
2530
patch -p1 < "$SOURCE_DIR/build/patches/openresty-opm.patch"
2631
patch -p1 < "$SOURCE_DIR/build/patches/openresty-cli.patch"
@@ -36,12 +41,12 @@ patch -p1 < "$SOURCE_DIR/build/patches/openresty-cli.patch"
3641
--with-pcre-opt=-g \
3742
--with-pcre-conf-opt=--enable-unicode-properties \
3843
--with-pcre-jit \
39-
--with-http_geoip_module \
4044
--with-http_gunzip_module \
4145
--with-http_gzip_static_module \
4246
--with-http_realip_module \
4347
--with-http_ssl_module \
44-
--with-http_stub_status_module
48+
--with-http_stub_status_module \
49+
--add-module="../ngx_http_geoip2_module-$ngx_http_geoip2_module_version"
4550
make -j"$NPROC"
4651
make install DESTDIR="$STAGE_DIR"
4752
chrpath -d "$STAGE_EMBEDDED_DIR/openresty/nginx/sbin/nginx"

templates/etc/nginx/router.conf.mustache

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,13 @@ http {
7171
resolver_timeout 12s;
7272
{{/dns_resolver._nameservers_nginx}}
7373

74-
geoip_city {{db_dir}}/geoip/city-v6.dat;
74+
geoip2 {{db_dir}}/geoip/GeoLite2-City.mmdb {
75+
$geoip2_data_country_code country iso_code;
76+
$geoip2_data_subdivision_code subdivisions 0 iso_code;
77+
$geoip2_data_city_name city names en;
78+
$geoip2_data_latitude location latitude;
79+
$geoip2_data_longitude location longitude;
80+
}
7581

7682
geo $banned_ip {
7783
default 0;

test/processes/test_rpaths.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def test_binary_rpaths
3838
"/embedded/openresty/nginx/sbin/nginx",
3939
"/embedded/libexec/trafficserver/ssl_cert_loader.so",
4040
# LuaRock
41-
"/embedded/apps/core/shared/vendor/lua/lib/lua/5.1/iconv.so",
41+
"/embedded/apps/core/shared/vendor/lua/lib/lua/5.1/yaml.so",
4242
# Rubygem
4343
"/oj/oj.so",
4444
].each do |expected_path_end|

test/proxy/logging/test_ip_geocoding.rb

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,32 @@ def test_country_city_no_region
8080
:ip => "104.250.168.24",
8181
:country => "MC",
8282
:region => nil,
83-
:city => "Monte-carlo",
83+
:city => "Monte Carlo",
8484
:lat => 43.7333,
8585
:lon => 7.4167,
8686
})
8787
end
8888

8989
def test_country_no_region_city
90+
response = Typhoeus.get("http://127.0.0.1:9080/api/hello", log_http_options.deep_merge({
91+
:headers => {
92+
"X-Forwarded-For" => "1.1.1.1",
93+
},
94+
}))
95+
assert_response_code(200, response)
96+
97+
record = wait_for_log(response)[:hit_source]
98+
assert_geocode(record, {
99+
:ip => "1.1.1.1",
100+
:country => "AU",
101+
:region => nil,
102+
:city => nil,
103+
:lat => -33.494,
104+
:lon => 143.2104,
105+
})
106+
end
107+
108+
def test_no_country_region_city
90109
response = Typhoeus.get("http://127.0.0.1:9080/api/hello", log_http_options.deep_merge({
91110
:headers => {
92111
"X-Forwarded-For" => "67.43.156.1",
@@ -97,11 +116,11 @@ def test_country_no_region_city
97116
record = wait_for_log(response)[:hit_source]
98117
assert_geocode(record, {
99118
:ip => "67.43.156.1",
100-
:country => "A1",
119+
:country => nil,
101120
:region => nil,
102121
:city => nil,
103-
:lat => 0.0,
104-
:lon => 0.0,
122+
:lat => nil,
123+
:lon => nil,
105124
})
106125
end
107126

@@ -118,7 +137,7 @@ def test_city_accent_chars
118137
:ip => "184.148.224.214",
119138
:country => "CA",
120139
:region => "QC",
121-
:city => "Trois-rivières",
140+
:city => "Trois-Rivières",
122141
:lat => 46.316,
123142
:lon => -72.6833,
124143
})
@@ -128,12 +147,19 @@ def test_city_accent_chars
128147

129148
def assert_geocode(record, options)
130149
assert_geocode_log(record, options)
131-
assert_geocode_cache(record, options)
150+
if !options.fetch(:lat).nil? || !options.fetch(:lon).nil?
151+
assert_geocode_cache(record, options)
152+
end
132153
end
133154

134155
def assert_geocode_log(record, options)
135156
assert_equal(options.fetch(:ip), record.fetch("request_ip"))
136-
assert_equal(options.fetch(:country), record.fetch("request_ip_country"))
157+
if(options.fetch(:country).nil?)
158+
assert_nil(record["request_ip_country"])
159+
refute(record.key?("request_ip_country"))
160+
else
161+
assert_equal(options.fetch(:country), record.fetch("request_ip_country"))
162+
end
137163
if(options.fetch(:region).nil?)
138164
assert_nil(record["request_ip_region"])
139165
refute(record.key?("request_ip_region"))

0 commit comments

Comments
 (0)