dap 1.0.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile.testing +14 -6
- data/Gemfile +2 -1
- data/Gemfile.lock +7 -5
- data/lib/dap/filter.rb +1 -0
- data/lib/dap/filter/geoip.rb +44 -16
- data/lib/dap/filter/geoip2.rb +286 -0
- data/lib/dap/utils/misc.rb +22 -0
- data/lib/dap/version.rb +1 -1
- data/spec/dap/utils/misc_spec.rb +12 -0
- data/test/filters.bats +67 -3
- data/test/test_data/geoip/GeoIPASNum.dat +0 -0
- data/test/test_data/geoip/GeoIPCity.dat +0 -0
- data/test/test_data/geoip/GeoIPOrg.dat +0 -0
- data/test/test_data/geoip2/GeoIP2-City-Test.mmdb +0 -0
- data/test/test_data/geoip2/GeoIP2-ISP-Test.mmdb +0 -0
- data/test/test_data/geoip2/GeoLite2-ASN-Test.mmdb +0 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0467108dd6edf2120b8de36390c3a338aadbfaf8'
|
4
|
+
data.tar.gz: 0a3a5c8f96087bd1c09af9534867e5b7f619d2b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 622ed2ba3f267ab350d7323f8fb70e44a196d4800fe85fd6e7d2e64add8abdee448d83cd6c2d1577f873c55cdb6dd32d256c09f2e40154b1e14fff66506e08e1
|
7
|
+
data.tar.gz: bf214ba2c71977e1f0d26d7dc35193ccf28fc9d0239fb900be3c539ddc6ee742046ddc92c556d7986a704a2c73613611aef1fe7da9cc399f95b2fe98364acdad
|
data/Dockerfile.testing
CHANGED
@@ -14,13 +14,21 @@ RUN /bin/bash -l -c "rvm use 2.4.5 && gem update --system && gem install bundler
|
|
14
14
|
ADD Gemfile* $TEST_DIR/
|
15
15
|
RUN /bin/bash -l -c "cd $TEST_DIR && rvm use 2.4.5 && bundle install"
|
16
16
|
|
17
|
-
# install maxmind data
|
17
|
+
# install maxmind legacy data
|
18
18
|
RUN mkdir /var/lib/geoip
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
COPY test/test_data/geoip/*.dat /var/lib/geoip/
|
20
|
+
# Note that these test files were copied from
|
21
|
+
# https://github.com/maxmind/geoip-api-php/raw/master/tests/data/GeoIPCity.dat
|
22
|
+
# https://github.com/maxmind/geoip-api-php/raw/master/tests/data/GeoIPASNum.dat
|
23
|
+
# https://github.com/maxmind/geoip-api-php/raw/master/tests/data/GeoIPOrg.dat
|
24
|
+
|
25
|
+
# install maxmind geoip2 data
|
26
|
+
RUN mkdir /var/lib/geoip2
|
27
|
+
COPY test/test_data/geoip2/*.mmdb /var/lib/geoip2/
|
28
|
+
# Note that these test files were copied from
|
29
|
+
# https://github.com/maxmind/MaxMind-DB/raw/f6ed981c23b0eb33d7c07568e2177236252afda6/test-data/GeoLite2-ASN-Test.mmdb
|
30
|
+
# https://github.com/maxmind/MaxMind-DB/raw/f6ed981c23b0eb33d7c07568e2177236252afda6/test-data/GeoIP2-City-Test.mmdb
|
31
|
+
# https://github.com/maxmind/MaxMind-DB/blob/f6ed981c23b0eb33d7c07568e2177236252afda6/test-data/GeoIP2-ISP-Test.mmdb
|
24
32
|
|
25
33
|
# install bats
|
26
34
|
RUN git clone https://github.com/sstephenson/bats.git && cd bats && ./install.sh /usr
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -21,14 +21,15 @@ GEM
|
|
21
21
|
gherkin (2.12.2)
|
22
22
|
multi_json (~> 1.3)
|
23
23
|
htmlentities (4.3.4)
|
24
|
-
|
24
|
+
maxmind-db (1.0.0)
|
25
|
+
mini_portile2 (2.4.0)
|
25
26
|
multi_json (1.11.2)
|
26
27
|
multi_test (0.1.2)
|
27
28
|
net-dns (0.9.0)
|
28
|
-
nokogiri (1.
|
29
|
-
mini_portile2 (~> 2.
|
29
|
+
nokogiri (1.10.3)
|
30
|
+
mini_portile2 (~> 2.4.0)
|
30
31
|
oj (3.7.9)
|
31
|
-
recog (2.
|
32
|
+
recog (2.3.0)
|
32
33
|
nokogiri
|
33
34
|
rspec (3.1.0)
|
34
35
|
rspec-core (~> 3.1.0)
|
@@ -52,9 +53,10 @@ DEPENDENCIES
|
|
52
53
|
cucumber (~> 1.3.16)
|
53
54
|
geoip-c
|
54
55
|
htmlentities
|
56
|
+
maxmind-db (~> 1.0.0)
|
55
57
|
net-dns
|
56
58
|
oj
|
57
|
-
recog (>= 2.
|
59
|
+
recog (>= 2.3.0)
|
58
60
|
rspec (~> 3.1.0)
|
59
61
|
|
60
62
|
BUNDLED WITH
|
data/lib/dap/filter.rb
CHANGED
data/lib/dap/filter/geoip.rb
CHANGED
@@ -16,26 +16,54 @@ module GeoIPLibrary
|
|
16
16
|
@@geo_orgs = nil
|
17
17
|
@@geo_asn = nil
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
GEOIP_CITY_DATABASE_PATH = ENV["GEOIP_CITY_DATABASE_PATH"]
|
20
|
+
GEOIP_ASN_DATABASE_PATH = ENV["GEOIP_ASN_DATABASE_PATH"]
|
21
|
+
GEOIP_ORG_DATABASE_PATH = ENV["GEOIP_ORG_DATABASE_PATH"]
|
22
|
+
|
23
|
+
if GEOIP_CITY_DATABASE_PATH
|
24
|
+
if ::File.exist?(GEOIP_CITY_DATABASE_PATH)
|
25
|
+
@@geo_city = GeoIP::City.new(GEOIP_CITY_DATABASE_PATH)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
GEOIP_DIRS.each do |d|
|
29
|
+
GEOIP_CITY.each do |f|
|
30
|
+
path = File.join(d, f)
|
31
|
+
if ::File.exist?(path)
|
32
|
+
@@geo_city = GeoIP::City.new(path)
|
33
|
+
break
|
34
|
+
end
|
25
35
|
end
|
26
36
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
37
|
+
end
|
38
|
+
|
39
|
+
if GEOIP_ORG_DATABASE_PATH
|
40
|
+
if ::File.exist?(GEOIP_ORG_DATABASE_PATH)
|
41
|
+
@@geo_orgs = GeoIP::Organization.new(GEOIP_ORG_DATABASE_PATH)
|
42
|
+
end
|
43
|
+
else
|
44
|
+
GEOIP_DIRS.each do |d|
|
45
|
+
GEOIP_ORGS.each do |f|
|
46
|
+
path = File.join(d, f)
|
47
|
+
if ::File.exist?( path )
|
48
|
+
@@geo_orgs = GeoIP::Organization.new(path)
|
49
|
+
break
|
50
|
+
end
|
32
51
|
end
|
33
52
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
53
|
+
end
|
54
|
+
|
55
|
+
if GEOIP_ASN_DATABASE_PATH
|
56
|
+
if ::File.exist?(GEOIP_ASN_DATABASE_PATH)
|
57
|
+
@@geo_asn = GeoIP::Organization.new(GEOIP_ASN_DATABASE_PATH)
|
58
|
+
end
|
59
|
+
else
|
60
|
+
GEOIP_DIRS.each do |d|
|
61
|
+
GEOIP_ASN.each do |f|
|
62
|
+
path = File.join(d, f)
|
63
|
+
if ::File.exist?(path)
|
64
|
+
@@geo_asn = GeoIP::Organization.new(path)
|
65
|
+
break
|
66
|
+
end
|
39
67
|
end
|
40
68
|
end
|
41
69
|
end
|
@@ -0,0 +1,286 @@
|
|
1
|
+
require 'maxmind/db'
|
2
|
+
|
3
|
+
module Dap
|
4
|
+
module Filter
|
5
|
+
|
6
|
+
require 'dap/utils/misc'
|
7
|
+
|
8
|
+
module GeoIP2Library
|
9
|
+
GEOIP2_DIRS = [
|
10
|
+
File.expand_path( File.join( File.dirname(__FILE__), "..", "..", "..", "data")),
|
11
|
+
"/var/lib/geoip",
|
12
|
+
"/var/lib/geoip2"
|
13
|
+
]
|
14
|
+
GEOIP2_CITY = %W{ GeoLite2-City.mmdb }
|
15
|
+
GEOIP2_ASN = %W{ GeoLite2-ASN.mmdb }
|
16
|
+
GEOIP2_ISP = %W{ GeoIP2-ISP.mmdb }
|
17
|
+
|
18
|
+
def self.find_db(db_file_names, db_dirs, env_path)
|
19
|
+
if env_path
|
20
|
+
if ::File.exist?(env_path)
|
21
|
+
return MaxMind::DB.new(env_path, mode: MaxMind::DB::MODE_MEMORY)
|
22
|
+
end
|
23
|
+
else
|
24
|
+
db_dirs.each do |d|
|
25
|
+
db_file_names.each do |f|
|
26
|
+
path = File.join(d, f)
|
27
|
+
if ::File.exist?(path)
|
28
|
+
return MaxMind::DB.new(path, mode: MaxMind::DB::MODE_MEMORY)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
@@geo_asn = find_db(GEOIP2_ASN, GEOIP2_DIRS, ENV["GEOIP2_ASN_DATABASE_PATH"])
|
37
|
+
@@geo_city = find_db(GEOIP2_CITY, GEOIP2_DIRS, ENV["GEOIP2_CITY_DATABASE_PATH"])
|
38
|
+
@@geo_isp = find_db(GEOIP2_ISP, GEOIP2_DIRS, ENV["GEOIP2_ISP_DATABASE_PATH"])
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
#
|
43
|
+
# Add GeoIP2 tags using the MaxMind GeoIP2::City
|
44
|
+
#
|
45
|
+
class FilterGeoIP2City
|
46
|
+
include BaseDecoder
|
47
|
+
include GeoIP2Library
|
48
|
+
|
49
|
+
GEOIP2_LANGUAGE = ENV["GEOIP2_LANGUAGE"] || "en"
|
50
|
+
LOCALE_SPECIFIC_NAMES = %w(city.names continent.names country.names registered_country.names represented_country.names)
|
51
|
+
DESIRED_GEOIP2_KEYS = %w(
|
52
|
+
city.geoname_id
|
53
|
+
continent.code continent.geoname_id
|
54
|
+
country.geoname_id country.iso_code country.is_in_european_union
|
55
|
+
location.accuracy_radius location.latitude location.longitude location.metro_code location.time_zone
|
56
|
+
postal.code
|
57
|
+
registered_country.geoname_id registered_country.iso_code registered_country.is_in_european_union
|
58
|
+
represented_country.geoname_id represented_country.iso_code represented_country.is_in_european_union represented_country.type
|
59
|
+
traits.is_anonymous_proxy traits.is_satellite_provider
|
60
|
+
)
|
61
|
+
|
62
|
+
attr_reader :locale_specific_names
|
63
|
+
def initialize(args={})
|
64
|
+
@locale_specific_names = LOCALE_SPECIFIC_NAMES.map { |lsn| "#{lsn}.#{GEOIP2_LANGUAGE}" }
|
65
|
+
super
|
66
|
+
end
|
67
|
+
|
68
|
+
def decode(ip)
|
69
|
+
unless @@geo_city
|
70
|
+
raise "No MaxMind GeoIP2::City data found"
|
71
|
+
end
|
72
|
+
return unless (geo_hash = @@geo_city.get(ip))
|
73
|
+
ret = defaults
|
74
|
+
|
75
|
+
if geo_hash.include?("subdivisions")
|
76
|
+
# handle countries that are divided into various subdivisions. generally 1, sometimes 2
|
77
|
+
subdivisions = geo_hash["subdivisions"]
|
78
|
+
geo_hash.delete("subdivisions")
|
79
|
+
ret["geoip2.city.subdivisions.length"] = subdivisions.size.to_s
|
80
|
+
subdivisions.each_index do |i|
|
81
|
+
subdivision = subdivisions[i]
|
82
|
+
subdivision.each_pair do |k,v|
|
83
|
+
if %w(geoname_id iso_code).include?(k)
|
84
|
+
ret["geoip2.city.subdivisions.#{i}.#{k}"] = v.to_s
|
85
|
+
elsif k == "names"
|
86
|
+
if v.include?(GEOIP2_LANGUAGE)
|
87
|
+
ret["geoip2.city.subdivisions.#{i}.name"] = subdivision["names"][GEOIP2_LANGUAGE]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
Dap::Utils::Misc.flatten_hash(geo_hash).each_pair do |k,v|
|
95
|
+
if DESIRED_GEOIP2_KEYS.include?(k)
|
96
|
+
# these keys we can just copy directly over
|
97
|
+
ret["geoip2.city.#{k}"] = v
|
98
|
+
elsif @locale_specific_names.include?(k)
|
99
|
+
# these keys we need to pick the locale-specific name and set the key accordingly
|
100
|
+
lsn_renamed = k.gsub(/\.names.#{GEOIP2_LANGUAGE}/, ".name")
|
101
|
+
ret["geoip2.city.#{lsn_renamed}"] = v
|
102
|
+
end
|
103
|
+
end
|
104
|
+
ret
|
105
|
+
end
|
106
|
+
|
107
|
+
def defaults()
|
108
|
+
ret = {}
|
109
|
+
default_int_suffixes = %w(geoname_id metro_code)
|
110
|
+
default_bool_suffixes = %w(is_in_european_union is_anonymous_proxy is_satellite_provider)
|
111
|
+
DESIRED_GEOIP2_KEYS.each do |k|
|
112
|
+
suffix = k.split(/\./)[-1]
|
113
|
+
if default_int_suffixes.include?(suffix)
|
114
|
+
ret["geoip2.city.#{k}"] = "0"
|
115
|
+
elsif default_bool_suffixes.include?(suffix)
|
116
|
+
ret["geoip2.city.#{k}"] = "false"
|
117
|
+
else
|
118
|
+
ret["geoip2.city.#{k}"] = ""
|
119
|
+
end
|
120
|
+
end
|
121
|
+
ret
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# Add GeoIP2 ASN and Org tags using the MaxMind GeoIP2::ASN database
|
127
|
+
#
|
128
|
+
class FilterGeoIP2Asn
|
129
|
+
include BaseDecoder
|
130
|
+
include GeoIP2Library
|
131
|
+
|
132
|
+
def decode(ip)
|
133
|
+
unless @@geo_asn
|
134
|
+
raise "No MaxMind GeoIP2::ASN data found"
|
135
|
+
end
|
136
|
+
geo_hash = @@geo_asn.get(ip)
|
137
|
+
return unless geo_hash
|
138
|
+
|
139
|
+
ret = {}
|
140
|
+
|
141
|
+
if geo_hash.include?("autonomous_system_number")
|
142
|
+
ret["geoip2.asn.asn"] = "AS#{geo_hash["autonomous_system_number"]}"
|
143
|
+
else
|
144
|
+
ret["geoip2.asn.asn"] = ""
|
145
|
+
end
|
146
|
+
|
147
|
+
if geo_hash.include?("autonomous_system_organization")
|
148
|
+
ret["geoip2.asn.asn_org"] = "#{geo_hash["autonomous_system_organization"]}"
|
149
|
+
else
|
150
|
+
ret["geoip2.asn.asn_org"] = ""
|
151
|
+
end
|
152
|
+
|
153
|
+
ret
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
#
|
158
|
+
# Add GeoIP2 ISP tags using the MaxMind GeoIP2::ISP database
|
159
|
+
#
|
160
|
+
class FilterGeoIP2Isp
|
161
|
+
include BaseDecoder
|
162
|
+
include GeoIP2Library
|
163
|
+
def decode(ip)
|
164
|
+
unless @@geo_isp
|
165
|
+
raise "No MaxMind GeoIP2::ISP data found"
|
166
|
+
end
|
167
|
+
geo_hash = @@geo_isp.get(ip)
|
168
|
+
return unless geo_hash
|
169
|
+
|
170
|
+
ret = {}
|
171
|
+
|
172
|
+
if geo_hash.include?("autonomous_system_number")
|
173
|
+
ret["geoip2.isp.asn"] = "AS#{geo_hash["autonomous_system_number"]}"
|
174
|
+
else
|
175
|
+
ret["geoip2.isp.asn"] = ""
|
176
|
+
end
|
177
|
+
|
178
|
+
if geo_hash.include?("autonomous_system_organization")
|
179
|
+
ret["geoip2.isp.asn_org"] = geo_hash["autonomous_system_organization"]
|
180
|
+
else
|
181
|
+
ret["geoip2.isp.asn_org"] = ""
|
182
|
+
end
|
183
|
+
|
184
|
+
if geo_hash.include?("isp")
|
185
|
+
ret["geoip2.isp.isp"] = geo_hash["isp"]
|
186
|
+
else
|
187
|
+
ret["geoip2.isp.isp"] = ""
|
188
|
+
end
|
189
|
+
|
190
|
+
if geo_hash.include?("organization")
|
191
|
+
ret["geoip2.isp.org"] = geo_hash["organization"]
|
192
|
+
else
|
193
|
+
ret["geoip2.isp.org"] = ""
|
194
|
+
end
|
195
|
+
|
196
|
+
ret
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
#
|
201
|
+
# Convert GeoIP2 data as closely as possible to the legacy GeoIP data as generated by geo_ip, geo_ip_asn and geo_ip_org
|
202
|
+
#
|
203
|
+
class FilterGeoIP2LegacyCompat
|
204
|
+
include Base
|
205
|
+
|
206
|
+
attr_accessor :base_field
|
207
|
+
|
208
|
+
def initialize(args)
|
209
|
+
super
|
210
|
+
fail "Expected 1 arguments to '#{self.name}' but got #{args.size}" unless args.size == 1
|
211
|
+
self.base_field = args.first
|
212
|
+
end
|
213
|
+
|
214
|
+
def process(doc)
|
215
|
+
# all of these values we just take directly and rename
|
216
|
+
remap = {
|
217
|
+
# geoip2 name -> geoip name
|
218
|
+
"city.country.iso_code": "country_code",
|
219
|
+
"city.country.name": "country.name",
|
220
|
+
"city.postal.code": "postal_code",
|
221
|
+
"city.location.latitude": "latitude",
|
222
|
+
"city.location.longitude": "longitude",
|
223
|
+
"city.city.name": "city",
|
224
|
+
"city.subdivisions.0.iso_code": "region",
|
225
|
+
"city.subdivisions.0.name": "region_name",
|
226
|
+
"asn.asn": "asn",
|
227
|
+
"isp.asn": "asn",
|
228
|
+
}
|
229
|
+
|
230
|
+
remap.each_pair do |geoip2,geoip|
|
231
|
+
geoip2_key = "#{self.base_field}.geoip2.#{geoip2}"
|
232
|
+
if doc.include?(geoip2_key)
|
233
|
+
doc["#{self.base_field}.#{geoip}"] = doc[geoip2_key]
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# these values all require special handling
|
238
|
+
|
239
|
+
# https://dev.maxmind.com/geoip/geoip2/whats-new-in-geoip2/#Custom_Country_Codes
|
240
|
+
# which basically says if traits.is_anonymous_proxy is true, previously the
|
241
|
+
# country_code would have had a special value of A1. Similarly, if
|
242
|
+
# traits.is_satellite_provider is true, previously the country_code would
|
243
|
+
# have a special value of A2.
|
244
|
+
anon_key = "#{self.base_field}.geoip2.city.traits.is_anonymous_proxy"
|
245
|
+
if doc.include?(anon_key)
|
246
|
+
anon_value = doc[anon_key]
|
247
|
+
if anon_value == "true"
|
248
|
+
doc["#{self.base_field}.country_code"] = "A1"
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
satellite_key = "#{self.base_field}.geoip2.city.traits.is_satellite_provider"
|
253
|
+
if doc.include?(satellite_key)
|
254
|
+
satellite_value = doc[satellite_key]
|
255
|
+
if satellite_value == "true"
|
256
|
+
doc["#{self.base_field}.country_code"] = "A1"
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# only set dma_code if location.metro_code was set and not empty or 0
|
261
|
+
metro_key = "#{self.base_field}.geoip2.city.location.metro_code}"
|
262
|
+
if doc.include?(metro_key)
|
263
|
+
metro_value = doc[metro_key]
|
264
|
+
if !metro_value.empty? && metro_value != "0"
|
265
|
+
doc["#{self.base_field}.dma_code"] = metro_value
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# get the org key from 3 possible fields in decreasing order of preference
|
270
|
+
asn_org_key = "#{self.base_field}.geoip2.asn.asn_org"
|
271
|
+
isp_asn_org_key = "#{self.base_field}.geoip2.isp.asn_org"
|
272
|
+
isp_org_key = "#{self.base_field}.geoip2.isp.asn_org"
|
273
|
+
[ isp_org_key, isp_asn_org_key, asn_org_key ].each do |k|
|
274
|
+
v = doc[k]
|
275
|
+
if v && !v.empty?
|
276
|
+
doc["#{self.base_field}.org"] = v
|
277
|
+
break
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
[ doc ]
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
end
|
286
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Dap
|
2
|
+
module Utils
|
3
|
+
module Misc
|
4
|
+
|
5
|
+
def self.flatten_hash(h)
|
6
|
+
ret = {}
|
7
|
+
h.each_pair do |k,v|
|
8
|
+
next unless k
|
9
|
+
if v.is_a?(Hash)
|
10
|
+
flatten_hash(v).each_pair do |fk,fv|
|
11
|
+
ret["#{k}.#{fk}"] = fv.to_s
|
12
|
+
end
|
13
|
+
else
|
14
|
+
ret[k.to_s] = v.to_s
|
15
|
+
end
|
16
|
+
end
|
17
|
+
ret
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/dap/version.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
describe Dap::Utils::Misc do
|
2
|
+
describe '.flatten_hash' do
|
3
|
+
context 'with mixed nested data' do
|
4
|
+
let(:test_hash) { {"foo0": "bar0", "foo1": {"bar1": "stuff", "more": 1}, "foo2": {"bar2": "stuff", "more": 1, "morestuff": {"foo1": "thing1"}}} }
|
5
|
+
let(:expected_flat) { {'foo0'=>'bar0', 'foo1.bar1'=>'stuff', 'foo1.more'=>'1', 'foo2.bar2'=>'stuff', 'foo2.more'=>'1', 'foo2.morestuff.foo1'=>'thing1'} }
|
6
|
+
let(:actual_flat) { Dap::Utils::Misc.flatten_hash(test_hash) }
|
7
|
+
it 'flattens properly' do
|
8
|
+
expect(actual_flat).to eq(expected_flat)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/test/filters.bats
CHANGED
@@ -109,11 +109,9 @@ load ./test_common
|
|
109
109
|
}
|
110
110
|
|
111
111
|
@test "recog_match" {
|
112
|
-
# currently differs from godap, need to figure out which is correct
|
113
|
-
skip
|
114
112
|
run bash -c "echo '9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6_9.2' | $DAP_EXECUTABLE lines + recog line=dns.versionbind + json | jq -Sc ."
|
115
113
|
assert_success
|
116
|
-
assert_output '{"line":"9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6_9.2","line.recog.os.cpe23":"cpe:/o:redhat:enterprise_linux:6","line.recog.os.family":"Linux","line.recog.os.product":"Enterprise Linux","line.recog.os.vendor":"Red Hat","line.recog.os.version":"6","line.recog.os.version.version":"9","line.recog.service.cpe23":"cpe:/a:isc:bind:9.8.2rc1","line.recog.service.family":"BIND","line.recog.service.product":"BIND","line.recog.service.vendor":"ISC","line.recog.service.version":"9.8.2rc1"}'
|
114
|
+
assert_output '{"line":"9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6_9.2","line.recog.fingerprint_db":"dns.versionbind","line.recog.matched":"ISC BIND: Red Hat Enterprise Linux","line.recog.os.cpe23":"cpe:/o:redhat:enterprise_linux:6","line.recog.os.family":"Linux","line.recog.os.product":"Enterprise Linux","line.recog.os.vendor":"Red Hat","line.recog.os.version":"6","line.recog.os.version.version":"9","line.recog.service.cpe23":"cpe:/a:isc:bind:9.8.2rc1","line.recog.service.family":"BIND","line.recog.service.product":"BIND","line.recog.service.protocol":"dns","line.recog.service.vendor":"ISC","line.recog.service.version":"9.8.2rc1"}'
|
117
115
|
}
|
118
116
|
|
119
117
|
@test "recog_nomatch" {
|
@@ -128,3 +126,69 @@ load ./test_common
|
|
128
126
|
run bash -c "echo 'test' | $DAP_EXECUTABLE lines + recog + json"
|
129
127
|
assert_failure
|
130
128
|
}
|
129
|
+
|
130
|
+
@test "geo_ip yields valid fields" {
|
131
|
+
run bash -c "echo 66.92.181.240 | GEOIP_CITY_DATABASE_PATH=./test/test_data/geoip/GeoIPCity.dat $DAP_EXECUTABLE lines + geo_ip line + json | jq -Sc ."
|
132
|
+
assert_success
|
133
|
+
assert_output '{"line":"66.92.181.240","line.area_code":"510","line.city":"Fremont","line.country_code":"US","line.country_code3":"USA","line.country_name":"United States","line.dma_code":"807","line.latitude":"37.50790023803711","line.longitude":"-121.95999908447266","line.postal_code":"94538","line.region":"CA","line.region_name":"California"}'
|
134
|
+
}
|
135
|
+
|
136
|
+
@test "geo_ip_org yields valid fields" {
|
137
|
+
run bash -c "echo 12.87.118.0 | GEOIP_ORG_DATABASE_PATH=./test/test_data/geoip/GeoIPOrg.dat $DAP_EXECUTABLE lines + geo_ip_org line + json | jq -Sc -r ."
|
138
|
+
assert_success
|
139
|
+
assert_output '{"line":"12.87.118.0","line.org":"AT&T Worldnet Services"}'
|
140
|
+
}
|
141
|
+
|
142
|
+
@test "geo_ip_asn" {
|
143
|
+
run bash -c "echo 12.87.118.0 | GEOIP_ASN_DATABASE_PATH=./test/test_data/geoip/GeoIPASNum.dat $DAP_EXECUTABLE lines + geo_ip_asn line + json | jq -Sc -r ."
|
144
|
+
assert_success
|
145
|
+
assert_output '{"line":"12.87.118.0","line.asn":"AS7018"}'
|
146
|
+
}
|
147
|
+
|
148
|
+
@test "geo_ip2_city" {
|
149
|
+
# test with default language
|
150
|
+
run bash -c "echo 81.2.69.142 | GEOIP2_CITY_DATABASE_PATH=test/test_data/geoip2/GeoIP2-City-Test.mmdb $DAP_EXECUTABLE lines + geo_ip2_city line + json | jq -Sc -r ."
|
151
|
+
assert_success
|
152
|
+
assert_output '{"line":"81.2.69.142","line.geoip2.city.city.geoname_id":"2643743","line.geoip2.city.city.name":"London","line.geoip2.city.continent.code":"EU","line.geoip2.city.continent.geoname_id":"6255148","line.geoip2.city.continent.name":"Europe","line.geoip2.city.country.geoname_id":"2635167","line.geoip2.city.country.is_in_european_union":"true","line.geoip2.city.country.iso_code":"GB","line.geoip2.city.country.name":"United Kingdom","line.geoip2.city.location.accuracy_radius":"10","line.geoip2.city.location.latitude":"51.5142","line.geoip2.city.location.longitude":"-0.0931","line.geoip2.city.location.metro_code":"0","line.geoip2.city.location.time_zone":"Europe/London","line.geoip2.city.postal.code":"","line.geoip2.city.registered_country.geoname_id":"6252001","line.geoip2.city.registered_country.is_in_european_union":"false","line.geoip2.city.registered_country.iso_code":"US","line.geoip2.city.registered_country.name":"United States","line.geoip2.city.represented_country.geoname_id":"0","line.geoip2.city.represented_country.is_in_european_union":"false","line.geoip2.city.represented_country.iso_code":"","line.geoip2.city.represented_country.type":"","line.geoip2.city.subdivisions.0.geoname_id":"6269131","line.geoip2.city.subdivisions.0.iso_code":"ENG","line.geoip2.city.subdivisions.0.name":"England","line.geoip2.city.subdivisions.length":"1","line.geoip2.city.traits.is_anonymous_proxy":"false","line.geoip2.city.traits.is_satellite_provider":"false"}'
|
153
|
+
|
154
|
+
# test with non-default language
|
155
|
+
run bash -c "echo 67.43.156.0 | GEOIP2_CITY_DATABASE_PATH=test/test_data/geoip2/GeoIP2-City-Test.mmdb GEOIP2_LANGUAGE=fr $DAP_EXECUTABLE lines + geo_ip2_city line + json | jq -Sc -r ."
|
156
|
+
assert_success
|
157
|
+
assert_output '{"line":"67.43.156.0","line.geoip2.city.city.geoname_id":"0","line.geoip2.city.continent.code":"AS","line.geoip2.city.continent.geoname_id":"6255147","line.geoip2.city.continent.name":"Asie","line.geoip2.city.country.geoname_id":"1252634","line.geoip2.city.country.is_in_european_union":"false","line.geoip2.city.country.iso_code":"BT","line.geoip2.city.country.name":"Bhutan","line.geoip2.city.location.accuracy_radius":"534","line.geoip2.city.location.latitude":"27.5","line.geoip2.city.location.longitude":"90.5","line.geoip2.city.location.metro_code":"0","line.geoip2.city.location.time_zone":"Asia/Thimphu","line.geoip2.city.postal.code":"","line.geoip2.city.registered_country.geoname_id":"798549","line.geoip2.city.registered_country.is_in_european_union":"true","line.geoip2.city.registered_country.iso_code":"RO","line.geoip2.city.registered_country.name":"Roumanie","line.geoip2.city.represented_country.geoname_id":"0","line.geoip2.city.represented_country.is_in_european_union":"false","line.geoip2.city.represented_country.iso_code":"","line.geoip2.city.represented_country.type":"","line.geoip2.city.traits.is_anonymous_proxy":"true","line.geoip2.city.traits.is_satellite_provider":"false"}'
|
158
|
+
|
159
|
+
# test IPv6
|
160
|
+
run bash -c "echo 2a02:d9c0:: | GEOIP2_CITY_DATABASE_PATH=test/test_data/geoip2/GeoIP2-City-Test.mmdb $DAP_EXECUTABLE lines + geo_ip2_city line + json | jq -Sc -r ."
|
161
|
+
assert_success
|
162
|
+
assert_output '{"line":"2a02:d9c0::","line.geoip2.city.city.geoname_id":"0","line.geoip2.city.continent.code":"AS","line.geoip2.city.continent.geoname_id":"6255147","line.geoip2.city.continent.name":"Asia","line.geoip2.city.country.geoname_id":"298795","line.geoip2.city.country.is_in_european_union":"false","line.geoip2.city.country.iso_code":"TR","line.geoip2.city.country.name":"Turkey","line.geoip2.city.location.accuracy_radius":"100","line.geoip2.city.location.latitude":"39.05901","line.geoip2.city.location.longitude":"34.91155","line.geoip2.city.location.metro_code":"0","line.geoip2.city.location.time_zone":"Europe/Istanbul","line.geoip2.city.postal.code":"","line.geoip2.city.registered_country.geoname_id":"298795","line.geoip2.city.registered_country.is_in_european_union":"false","line.geoip2.city.registered_country.iso_code":"TR","line.geoip2.city.registered_country.name":"Turkey","line.geoip2.city.represented_country.geoname_id":"0","line.geoip2.city.represented_country.is_in_european_union":"false","line.geoip2.city.represented_country.iso_code":"","line.geoip2.city.represented_country.type":"","line.geoip2.city.traits.is_anonymous_proxy":"false","line.geoip2.city.traits.is_satellite_provider":"false"}'
|
163
|
+
}
|
164
|
+
|
165
|
+
@test "geo_ip2_asn" {
|
166
|
+
run bash -c "echo 12.81.92.0 | GEOIP2_ASN_DATABASE_PATH=test/test_data/geoip2/GeoLite2-ASN-Test.mmdb $DAP_EXECUTABLE lines + geo_ip2_asn line + json | jq -Sc -r ."
|
167
|
+
assert_success
|
168
|
+
assert_output '{"line":"12.81.92.0","line.geoip2.asn.asn":"AS7018","line.geoip2.asn.asn_org":"AT&T Services"}'
|
169
|
+
|
170
|
+
# test IPv6
|
171
|
+
run bash -c "echo 2600:7000:: | GEOIP2_ASN_DATABASE_PATH=test/test_data/geoip2/GeoLite2-ASN-Test.mmdb $DAP_EXECUTABLE lines + geo_ip2_asn line + json | jq -Sc -r ."
|
172
|
+
assert_success
|
173
|
+
assert_output '{"line":"2600:7000::","line.geoip2.asn.asn":"AS6939","line.geoip2.asn.asn_org":"Hurricane Electric, Inc."}'
|
174
|
+
}
|
175
|
+
|
176
|
+
@test "geo_ip2_isp" {
|
177
|
+
run bash -c "echo -e '12.81.92.0\n2600:7000::' | GEOIP2_ISP_DATABASE_PATH=test/test_data/geoip2/GeoIP2-ISP-Test.mmdb $DAP_EXECUTABLE lines + geo_ip2_isp line + json | jq -Sc -r ."
|
178
|
+
assert_line --index 0 '{"line":"12.81.92.0","line.geoip2.isp.asn":"AS7018","line.geoip2.isp.asn_org":"","line.geoip2.isp.isp":"AT&T Services","line.geoip2.isp.org":"AT&T Services"}'
|
179
|
+
# test IPv6
|
180
|
+
assert_line --index 1 '{"line":"2600:7000::","line.geoip2.isp.asn":"AS6939","line.geoip2.isp.asn_org":"Hurricane Electric, Inc.","line.geoip2.isp.isp":"","line.geoip2.isp.org":""}'
|
181
|
+
}
|
182
|
+
|
183
|
+
@test "geo_ip2_legacy_compat" {
|
184
|
+
run bash -c "echo -e '81.2.69.142\n12.81.92.0\n2a02:d9c0::\n2a01:1000::' | GEOIP2_ASN_DATABASE_PATH=test/test_data/geoip2/GeoLite2-ASN-Test.mmdb GEOIP2_CITY_DATABASE_PATH=test/test_data/geoip2/GeoIP2-City-Test.mmdb GEOIP2_ISP_DATABASE_PATH=test/test_data/geoip2/GeoIP2-ISP-Test.mmdb $DAP_EXECUTABLE lines + geo_ip2_city line + geo_ip2_asn line + geo_ip2_isp line + geo_ip2_legacy_compat line + match_remove line.geoip2 + json | jq -Sc -r ."
|
185
|
+
assert_success
|
186
|
+
# this one only has city data, not ASN/org/ISP
|
187
|
+
assert_line --index 0 '{"line":"81.2.69.142","line.city":"London","line.country.name":"United Kingdom","line.country_code":"GB","line.latitude":"51.5142","line.longitude":"-0.0931","line.postal_code":"","line.region":"ENG","line.region_name":"England"}'
|
188
|
+
# this one has ASN/org data in the test databases but none in the city DB
|
189
|
+
assert_line --index 1 '{"line":"12.81.92.0","line.asn":"AS7018","line.org":"AT&T Services"}'
|
190
|
+
# exists only city
|
191
|
+
assert_line --index 2 '{"line":"2a02:d9c0::","line.country.name":"Turkey","line.country_code":"TR","line.latitude":"39.05901","line.longitude":"34.91155","line.postal_code":""}'
|
192
|
+
# exists in ISP
|
193
|
+
assert_line --index 3 '{"line":"2a01:1000::","line.asn":"AS5617","line.org":"Telekomunikacja Polska S.A."}'
|
194
|
+
}
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rapid7 Research
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-04-
|
11
|
+
date: 2019-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -183,6 +183,7 @@ files:
|
|
183
183
|
- lib/dap/filter.rb
|
184
184
|
- lib/dap/filter/base.rb
|
185
185
|
- lib/dap/filter/geoip.rb
|
186
|
+
- lib/dap/filter/geoip2.rb
|
186
187
|
- lib/dap/filter/gquic.rb
|
187
188
|
- lib/dap/filter/http.rb
|
188
189
|
- lib/dap/filter/ldap.rb
|
@@ -205,6 +206,7 @@ files:
|
|
205
206
|
- lib/dap/proto/mssql.rb
|
206
207
|
- lib/dap/proto/natpmp.rb
|
207
208
|
- lib/dap/proto/wdbrpc.rb
|
209
|
+
- lib/dap/utils/misc.rb
|
208
210
|
- lib/dap/utils/oui.rb
|
209
211
|
- lib/dap/version.rb
|
210
212
|
- samples/http_get_reply.ic12.bz2
|
@@ -231,10 +233,17 @@ files:
|
|
231
233
|
- spec/dap/input/json_spec.rb
|
232
234
|
- spec/dap/proto/ipmi_spec.rb
|
233
235
|
- spec/dap/proto/ldap_proto_spec.rb
|
236
|
+
- spec/dap/utils/misc_spec.rb
|
234
237
|
- spec/spec_helper.rb
|
235
238
|
- test/filters.bats
|
236
239
|
- test/inputs.bats
|
237
240
|
- test/test_common.bash
|
241
|
+
- test/test_data/geoip/GeoIPASNum.dat
|
242
|
+
- test/test_data/geoip/GeoIPCity.dat
|
243
|
+
- test/test_data/geoip/GeoIPOrg.dat
|
244
|
+
- test/test_data/geoip2/GeoIP2-City-Test.mmdb
|
245
|
+
- test/test_data/geoip2/GeoIP2-ISP-Test.mmdb
|
246
|
+
- test/test_data/geoip2/GeoLite2-ASN-Test.mmdb
|
238
247
|
- tools/geo-ip-summary.rb
|
239
248
|
- tools/ipmi-vulns.rb
|
240
249
|
- tools/json-summarize.rb
|
@@ -273,7 +282,14 @@ test_files:
|
|
273
282
|
- spec/dap/input/json_spec.rb
|
274
283
|
- spec/dap/proto/ipmi_spec.rb
|
275
284
|
- spec/dap/proto/ldap_proto_spec.rb
|
285
|
+
- spec/dap/utils/misc_spec.rb
|
276
286
|
- spec/spec_helper.rb
|
277
287
|
- test/filters.bats
|
278
288
|
- test/inputs.bats
|
279
289
|
- test/test_common.bash
|
290
|
+
- test/test_data/geoip/GeoIPASNum.dat
|
291
|
+
- test/test_data/geoip/GeoIPCity.dat
|
292
|
+
- test/test_data/geoip/GeoIPOrg.dat
|
293
|
+
- test/test_data/geoip2/GeoIP2-City-Test.mmdb
|
294
|
+
- test/test_data/geoip2/GeoIP2-ISP-Test.mmdb
|
295
|
+
- test/test_data/geoip2/GeoLite2-ASN-Test.mmdb
|