logstash-filter-geoip 6.0.5-java → 7.0.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/logstash/filters/geoip.rb +40 -13
- data/logstash-filter-geoip.gemspec +1 -1
- data/spec/filters/geoip_offline_spec.rb +297 -0
- data/spec/filters/geoip_online_spec.rb +65 -0
- data/spec/filters/geoip_spec.rb +21 -277
- data/spec/filters/test_helper.rb +22 -0
- data/vendor/jar-dependencies/org/logstash/filters/logstash-filter-geoip/6.0.0/logstash-filter-geoip-6.0.0.jar +0 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1863a093cb2b2c2cf3acc200ce48ff5c2103e0a998b419165b5dc910ae9a8afb
|
4
|
+
data.tar.gz: 3b75fd3ce00d85a101b32f56e0a1a408be32d8c4e8381fa2df7b0abe3073e7d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa881996b64bdbb97765c1e257c850f70bc552f087127fda76d659d94a3c34a9bd80ea07d9dc7a5339d759834a345492c60f3b5c6ad96fbc07910239ff8fc218
|
7
|
+
data.tar.gz: 86063b89d552fd7b07d8add64bf4dfd644dff79fd978074bc09eca979ec7d86275e0672479a1401d1153cc5fbef2958dd692ee244b63c26ca720aaabf06ac05f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 7.0.0
|
2
|
+
- Changed the plugin to use EULA GeoIP2 Database with auto-update [#176](https://github.com/logstash-plugins/logstash-filter-geoip/pull/176)
|
3
|
+
Available in Logstash 7.13+ Elastic license
|
4
|
+
|
1
5
|
## 6.0.5
|
2
6
|
- Fix database download task. Upgrade project to java 11 [#175](https://github.com/logstash-plugins/logstash-filter-geoip/pull/175)
|
3
7
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "logstash/filters/base"
|
3
3
|
require "logstash/namespace"
|
4
|
-
|
5
4
|
require "logstash-filter-geoip_jars"
|
6
5
|
|
6
|
+
|
7
7
|
# The GeoIP filter adds information about the geographical location of IP addresses,
|
8
8
|
# based on data from the Maxmind GeoLite2 database.
|
9
9
|
#
|
@@ -90,18 +90,8 @@ class LogStash::Filters::GeoIP < LogStash::Filters::Base
|
|
90
90
|
|
91
91
|
public
|
92
92
|
def register
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
if @database.nil? || !File.exists?(@database)
|
97
|
-
raise "You must specify 'database => ...' in your geoip filter (I looked for '#{@database}')"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
@logger.info("Using geoip database", :path => @database)
|
102
|
-
|
103
|
-
@geoipfilter = org.logstash.filters.GeoIPFilter.new(@source, @target, @fields, @database, @cache_size)
|
104
|
-
end # def register
|
93
|
+
setup_filter(select_database_path)
|
94
|
+
end
|
105
95
|
|
106
96
|
public
|
107
97
|
def filter(event)
|
@@ -118,4 +108,41 @@ class LogStash::Filters::GeoIP < LogStash::Filters::Base
|
|
118
108
|
@tag_on_failure.each{|tag| event.tag(tag)}
|
119
109
|
end
|
120
110
|
|
111
|
+
def setup_filter(database_path)
|
112
|
+
@database = database_path
|
113
|
+
@logger.info("Using geoip database", :path => @database)
|
114
|
+
@geoipfilter = org.logstash.filters.GeoIPFilter.new(@source, @target, @fields, @database, @cache_size)
|
115
|
+
end
|
116
|
+
|
117
|
+
def terminate_filter
|
118
|
+
@logger.info("geoip plugin is terminating")
|
119
|
+
pipeline_id = execution_context.pipeline_id
|
120
|
+
execution_context.agent.stop_pipeline(pipeline_id)
|
121
|
+
end
|
122
|
+
|
123
|
+
def close
|
124
|
+
@database_manager.close unless @database_manager.nil?
|
125
|
+
end
|
126
|
+
|
127
|
+
def select_database_path
|
128
|
+
vendor_path = ::File.expand_path("../../../vendor/", ::File.dirname(__FILE__))
|
129
|
+
|
130
|
+
if load_database_manager?
|
131
|
+
@database_manager = LogStash::Filters::Geoip::DatabaseManager.new(self, @database, @default_database_type, vendor_path)
|
132
|
+
@database_manager.database_path
|
133
|
+
else
|
134
|
+
@database.nil? ? ::File.join(vendor_path, "GeoLite2-#{@default_database_type}.mmdb") : @database
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def load_database_manager?
|
139
|
+
begin
|
140
|
+
require_relative "#{LogStash::Environment::LOGSTASH_HOME}/x-pack/lib/filters/geoip/database_manager"
|
141
|
+
true
|
142
|
+
rescue LoadError => e
|
143
|
+
@logger.info("DatabaseManager is not in classpath", :version => LOGSTASH_VERSION, :exception => e)
|
144
|
+
false
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
121
148
|
end # class LogStash::Filters::GeoIP
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-filter-geoip'
|
4
|
-
s.version = '
|
4
|
+
s.version = '7.0.0'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Adds geographical information about an IP address"
|
7
7
|
s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
|
@@ -0,0 +1,297 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/devutils/rspec/spec_helper"
|
3
|
+
require "insist"
|
4
|
+
require "logstash/filters/geoip"
|
5
|
+
|
6
|
+
CITYDB = ::Dir.glob(::File.expand_path("../../vendor/", ::File.dirname(__FILE__))+"/GeoLite2-City.mmdb").first
|
7
|
+
ASNDB = ::Dir.glob(::File.expand_path("../../vendor/", ::File.dirname(__FILE__))+"/GeoLite2-ASN.mmdb").first
|
8
|
+
|
9
|
+
describe LogStash::Filters::GeoIP do
|
10
|
+
describe "defaults" do
|
11
|
+
config <<-CONFIG
|
12
|
+
filter {
|
13
|
+
geoip {
|
14
|
+
source => "ip"
|
15
|
+
database => "#{CITYDB}"
|
16
|
+
}
|
17
|
+
}
|
18
|
+
CONFIG
|
19
|
+
|
20
|
+
sample("ip" => "8.8.8.8") do
|
21
|
+
insist { subject }.include?("geoip")
|
22
|
+
|
23
|
+
expected_fields = %w(ip country_code2 country_code3 country_name
|
24
|
+
continent_code latitude longitude location)
|
25
|
+
expected_fields.each do |f|
|
26
|
+
insist { subject.get("geoip") }.include?(f)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
sample("ip" => "127.0.0.1") do
|
31
|
+
# assume geoip fails on localhost lookups
|
32
|
+
expect(subject.get("geoip")).to eq({})
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "normal operations" do
|
37
|
+
config <<-CONFIG
|
38
|
+
filter {
|
39
|
+
geoip {
|
40
|
+
source => "ip"
|
41
|
+
database => "#{CITYDB}"
|
42
|
+
target => src_ip
|
43
|
+
add_tag => "done"
|
44
|
+
}
|
45
|
+
}
|
46
|
+
CONFIG
|
47
|
+
|
48
|
+
context "when specifying the target" do
|
49
|
+
|
50
|
+
sample("ip" => "8.8.8.8") do
|
51
|
+
expect(subject).to include("src_ip")
|
52
|
+
|
53
|
+
expected_fields = %w(ip country_code2 country_code3 country_name
|
54
|
+
continent_code latitude longitude location)
|
55
|
+
expected_fields.each do |f|
|
56
|
+
expect(subject.get("src_ip")).to include(f)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
sample("ip" => "127.0.0.1") do
|
61
|
+
# assume geoip fails on localhost lookups
|
62
|
+
expect(subject.get("src_ip")).to eq({})
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when specifying add_tag" do
|
67
|
+
sample("ip" => "8.8.8.8") do
|
68
|
+
expect(subject.get("tags")).to include("done")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "source is derived from target" do
|
74
|
+
subject(:event) { LogStash::Event.new("target" => { "ip" => "173.9.34.107" } ) }
|
75
|
+
let(:plugin) {
|
76
|
+
LogStash::Filters::GeoIP.new(
|
77
|
+
"source" => "[target][ip]",
|
78
|
+
"target" => "target",
|
79
|
+
"fields" => [ "city_name", "region_name" ],
|
80
|
+
"add_tag" => "done", "database" => CITYDB
|
81
|
+
)
|
82
|
+
}
|
83
|
+
|
84
|
+
before do
|
85
|
+
plugin.register
|
86
|
+
plugin.filter(event)
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when source field 'ip' is a subfield of 'target'" do
|
90
|
+
|
91
|
+
it "should preserve value in [target][ip]" do
|
92
|
+
expect(event.get("[target][ip]")).to eq("173.9.34.107")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should set other subfields of 'target' properly" do
|
96
|
+
expect(event.get("target").to_hash.keys.sort).to eq(["city_name", "ip", "region_name"])
|
97
|
+
expect(event.get("[target][city_name]")).to eq("Malden")
|
98
|
+
expect(event.get("[target][region_name]")).to eq("Massachusetts")
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "correct encodings with default db" do
|
106
|
+
config <<-CONFIG
|
107
|
+
filter {
|
108
|
+
geoip {
|
109
|
+
source => "ip"
|
110
|
+
database => "#{CITYDB}"
|
111
|
+
}
|
112
|
+
}
|
113
|
+
CONFIG
|
114
|
+
expected_fields = %w(ip country_code2 country_code3 country_name
|
115
|
+
continent_code region_name city_name postal_code
|
116
|
+
dma_code timezone)
|
117
|
+
|
118
|
+
sample("ip" => "1.1.1.1") do
|
119
|
+
checked = 0
|
120
|
+
expected_fields.each do |f|
|
121
|
+
next unless subject.get("geoip")[f]
|
122
|
+
checked += 1
|
123
|
+
insist { subject.get("geoip")[f].encoding } == Encoding::UTF_8
|
124
|
+
end
|
125
|
+
insist { checked } > 0
|
126
|
+
end
|
127
|
+
|
128
|
+
sample("ip" => "189.2.0.0") do
|
129
|
+
checked = 0
|
130
|
+
expected_fields.each do |f|
|
131
|
+
next unless subject.get("geoip")[f]
|
132
|
+
checked += 1
|
133
|
+
insist { subject.get("geoip")[f].encoding } == Encoding::UTF_8
|
134
|
+
end
|
135
|
+
insist { checked } > 0
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "location field" do
|
141
|
+
shared_examples_for "an event with a [geoip][location] field" do
|
142
|
+
subject(:event) { LogStash::Event.new("message" => "8.8.8.8") }
|
143
|
+
let(:plugin) { LogStash::Filters::GeoIP.new("source" => "message", "fields" => fields, "database" => CITYDB) }
|
144
|
+
|
145
|
+
before do
|
146
|
+
plugin.register
|
147
|
+
plugin.filter(event)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should have a location field" do
|
151
|
+
expect(event.get("[geoip][location]")).not_to(be_nil)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context "when latitude field is excluded" do
|
156
|
+
let(:fields) { ["country_name", "location", "longitude"] }
|
157
|
+
it_behaves_like "an event with a [geoip][location] field"
|
158
|
+
end
|
159
|
+
|
160
|
+
context "when longitude field is excluded" do
|
161
|
+
let(:fields) { ["country_name", "location", "latitude"] }
|
162
|
+
it_behaves_like "an event with a [geoip][location] field"
|
163
|
+
end
|
164
|
+
|
165
|
+
context "when both latitude and longitude field are excluded" do
|
166
|
+
let(:fields) { ["country_name", "location"] }
|
167
|
+
it_behaves_like "an event with a [geoip][location] field"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "an invalid IP" do
|
172
|
+
config <<-CONFIG
|
173
|
+
filter {
|
174
|
+
geoip {
|
175
|
+
source => "ip"
|
176
|
+
database => "#{CITYDB}"
|
177
|
+
}
|
178
|
+
}
|
179
|
+
CONFIG
|
180
|
+
describe "should not raise an error" do
|
181
|
+
sample("ip" => "-") do
|
182
|
+
expect{ subject }.to_not raise_error
|
183
|
+
end
|
184
|
+
|
185
|
+
sample("ip" => "~") do
|
186
|
+
expect{ subject }.to_not raise_error
|
187
|
+
end
|
188
|
+
|
189
|
+
sample("ip" => "") do
|
190
|
+
expect{ subject }.to_not raise_error
|
191
|
+
end
|
192
|
+
|
193
|
+
sample("ip" => " ") do
|
194
|
+
expect{ subject }.to_not raise_error
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "filter method outcomes" do
|
199
|
+
let(:plugin) { LogStash::Filters::GeoIP.new("source" => "message", "add_tag" => "done", "database" => CITYDB) }
|
200
|
+
let(:event) { LogStash::Event.new("message" => ipstring) }
|
201
|
+
|
202
|
+
before do
|
203
|
+
plugin.register
|
204
|
+
plugin.filter(event)
|
205
|
+
end
|
206
|
+
|
207
|
+
context "when the bad IP is N/A" do
|
208
|
+
# regression test for issue https://github.com/logstash-plugins/logstash-filter-geoip/issues/50
|
209
|
+
let(:ipstring) { "N/A" }
|
210
|
+
|
211
|
+
it "should set the target field to an empty hash" do
|
212
|
+
expect(event.get("geoip")).to eq({})
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should add failure tags" do
|
216
|
+
expect(event.get("tags")).to include("_geoip_lookup_failure")
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context "when the bad IP is two ip comma separated" do
|
221
|
+
# regression test for issue https://github.com/logstash-plugins/logstash-filter-geoip/issues/51
|
222
|
+
let(:ipstring) { "123.45.67.89,61.160.232.222" }
|
223
|
+
|
224
|
+
it "should set the target field to an empty hash" do
|
225
|
+
expect(event.get("geoip")).to eq({})
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context "when a IP is not found in the DB" do
|
230
|
+
let(:ipstring) { "0.0.0.0" }
|
231
|
+
|
232
|
+
it "should set the target field to an empty hash" do
|
233
|
+
expect(event.get("geoip")).to eq({})
|
234
|
+
expect(event.get("tags")).to include("_geoip_lookup_failure")
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context "when IP is IPv6 format for localhost" do
|
239
|
+
let(:ipstring) { "::1" }
|
240
|
+
|
241
|
+
it "should set the target field to an empty hash" do
|
242
|
+
expect(event.get("geoip")).to eq({})
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context "when IP is valid IPv6 format" do
|
247
|
+
let(:ipstring) { "2607:f0d0:1002:51::4" }
|
248
|
+
|
249
|
+
it "should set the target fields properly" do
|
250
|
+
expect(event.get("geoip")).not_to be_empty
|
251
|
+
expect(event.get("geoip")["ip"]).to eq("2607:f0d0:1002:51:0:0:0:4")
|
252
|
+
expect(event.get("geoip").to_hash.keys.sort).to eq(
|
253
|
+
["continent_code", "country_code2", "country_code3", "country_name", "ip", "latitude", "location", "longitude", "timezone"]
|
254
|
+
)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
|
262
|
+
describe "an invalid database" do
|
263
|
+
config <<-CONFIG
|
264
|
+
filter {
|
265
|
+
geoip {
|
266
|
+
source => "ip"
|
267
|
+
database => "./Gemfile"
|
268
|
+
}
|
269
|
+
}
|
270
|
+
CONFIG
|
271
|
+
|
272
|
+
context "should return the correct sourcefield in the logging message" do
|
273
|
+
sample("ip" => "8.8.8.8") do
|
274
|
+
expect { subject }.to raise_error(java.lang.IllegalArgumentException, "The database provided is invalid or corrupted.")
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
describe "GeoIP2-ASN database" do
|
280
|
+
config <<-CONFIG
|
281
|
+
filter {
|
282
|
+
geoip {
|
283
|
+
source => "ip"
|
284
|
+
database => "#{ASNDB}"
|
285
|
+
default_database_type => "ASN"
|
286
|
+
}
|
287
|
+
}
|
288
|
+
CONFIG
|
289
|
+
|
290
|
+
sample("ip" => "8.8.8.8") do
|
291
|
+
expect(subject.get("geoip")).not_to be_empty
|
292
|
+
expect(subject.get("geoip")["asn"]).to eq(15169)
|
293
|
+
expect(subject.get("geoip")["as_org"]).to eq("Google LLC")
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/devutils/rspec/spec_helper"
|
3
|
+
require "insist"
|
4
|
+
require "logstash/filters/geoip"
|
5
|
+
require_relative 'test_helper'
|
6
|
+
|
7
|
+
describe LogStash::Filters::GeoIP do
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
::File.delete(METADATA_PATH) if ::File.exist?(METADATA_PATH)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "config without database path in LS >= 7.13", :aggregate_failures do
|
14
|
+
before(:each) do
|
15
|
+
dir_path = Stud::Temporary.directory
|
16
|
+
File.open(dir_path + '/uuid', 'w') { |f| f.write(SecureRandom.uuid) }
|
17
|
+
allow(LogStash::SETTINGS).to receive(:get).and_call_original
|
18
|
+
allow(LogStash::SETTINGS).to receive(:get).with("path.data").and_return(dir_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:plugin) { LogStash::Filters::GeoIP.new("source" => "[target][ip]") }
|
22
|
+
|
23
|
+
context "restart the plugin" do
|
24
|
+
let(:event) { LogStash::Event.new("target" => { "ip" => "173.9.34.107" }) }
|
25
|
+
let(:event2) { LogStash::Event.new("target" => { "ip" => "55.159.212.43" }) }
|
26
|
+
|
27
|
+
it "should use the same database" do
|
28
|
+
unless plugin.load_database_manager?
|
29
|
+
logstash_path = ENV['LOGSTASH_PATH'] || '/usr/share/logstash' # docker logstash home
|
30
|
+
stub_const('LogStash::Environment::LOGSTASH_HOME', logstash_path)
|
31
|
+
end
|
32
|
+
|
33
|
+
plugin.register
|
34
|
+
plugin.filter(event)
|
35
|
+
plugin.close
|
36
|
+
first_database_name = get_metadata_database_name
|
37
|
+
plugin.register
|
38
|
+
plugin.filter(event2)
|
39
|
+
plugin.close
|
40
|
+
second_database_name = get_metadata_database_name
|
41
|
+
|
42
|
+
expect(first_database_name).not_to be_nil
|
43
|
+
expect(first_database_name).to eq(second_database_name)
|
44
|
+
expect(::File.exist?(get_file_path(first_database_name))).to be_truthy
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end if MAJOR >= 8 || (MAJOR == 7 && MINOR >= 13)
|
48
|
+
|
49
|
+
describe "config without database path in LS < 7.13" do
|
50
|
+
context "should run in offline mode" do
|
51
|
+
config <<-CONFIG
|
52
|
+
filter {
|
53
|
+
geoip {
|
54
|
+
source => "ip"
|
55
|
+
}
|
56
|
+
}
|
57
|
+
CONFIG
|
58
|
+
|
59
|
+
sample("ip" => "173.9.34.107") do
|
60
|
+
insist { subject.get("geoip") }.include?("ip")
|
61
|
+
expect(::File.exist?(METADATA_PATH)).to be_falsey
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end if MAJOR < 7 || (MAJOR == 7 && MINOR <= 12)
|
65
|
+
end
|
data/spec/filters/geoip_spec.rb
CHANGED
@@ -1,298 +1,42 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "logstash/devutils/rspec/spec_helper"
|
3
|
-
require "insist"
|
4
3
|
require "logstash/filters/geoip"
|
5
|
-
|
6
|
-
CITYDB = ::Dir.glob(::File.expand_path("../../vendor/", ::File.dirname(__FILE__))+"/GeoLite2-City.mmdb").first
|
4
|
+
require_relative 'test_helper'
|
7
5
|
|
8
6
|
describe LogStash::Filters::GeoIP do
|
9
7
|
|
10
|
-
describe "
|
11
|
-
|
12
|
-
filter {
|
13
|
-
geoip {
|
14
|
-
source => "ip"
|
15
|
-
#database => "#{CITYDB}"
|
16
|
-
}
|
17
|
-
}
|
18
|
-
CONFIG
|
19
|
-
|
20
|
-
sample("ip" => "8.8.8.8") do
|
21
|
-
insist { subject }.include?("geoip")
|
22
|
-
|
23
|
-
expected_fields = %w(ip country_code2 country_code3 country_name
|
24
|
-
continent_code latitude longitude location)
|
25
|
-
expected_fields.each do |f|
|
26
|
-
insist { subject.get("geoip") }.include?(f)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
sample("ip" => "127.0.0.1") do
|
31
|
-
# assume geoip fails on localhost lookups
|
32
|
-
expect(subject.get("geoip")).to eq({})
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe "normal operations" do
|
37
|
-
config <<-CONFIG
|
38
|
-
filter {
|
39
|
-
geoip {
|
40
|
-
source => "ip"
|
41
|
-
# database => "#{CITYDB}"
|
42
|
-
target => src_ip
|
43
|
-
add_tag => "done"
|
44
|
-
}
|
45
|
-
}
|
46
|
-
CONFIG
|
47
|
-
|
48
|
-
context "when specifying the target" do
|
49
|
-
|
50
|
-
sample("ip" => "8.8.8.8") do
|
51
|
-
expect(subject).to include("src_ip")
|
52
|
-
|
53
|
-
expected_fields = %w(ip country_code2 country_code3 country_name
|
54
|
-
continent_code latitude longitude location)
|
55
|
-
expected_fields.each do |f|
|
56
|
-
expect(subject.get("src_ip")).to include(f)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
sample("ip" => "127.0.0.1") do
|
61
|
-
# assume geoip fails on localhost lookups
|
62
|
-
expect(subject.get("src_ip")).to eq({})
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
context "when specifying add_tag" do
|
67
|
-
sample("ip" => "8.8.8.8") do
|
68
|
-
expect(subject.get("tags")).to include("done")
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
describe "source is derived from target" do
|
74
|
-
subject(:event) { LogStash::Event.new("target" => { "ip" => "173.9.34.107" } ) }
|
75
|
-
let(:plugin) {
|
76
|
-
LogStash::Filters::GeoIP.new(
|
77
|
-
"source" => "[target][ip]",
|
78
|
-
"target" => "target",
|
79
|
-
"fields" => [ "city_name", "region_name" ],
|
80
|
-
"add_tag" => "done", "database" => CITYDB
|
81
|
-
)
|
82
|
-
}
|
83
|
-
|
84
|
-
before do
|
85
|
-
plugin.register
|
86
|
-
plugin.filter(event)
|
87
|
-
end
|
88
|
-
|
89
|
-
context "when source field 'ip' is a subfield of 'target'" do
|
90
|
-
|
91
|
-
it "should preserve value in [target][ip]" do
|
92
|
-
expect(event.get("[target][ip]")).to eq("173.9.34.107")
|
93
|
-
end
|
94
|
-
|
95
|
-
it "should set other subfields of 'target' properly" do
|
96
|
-
expect(event.get("target").to_hash.keys.sort).to eq(["city_name", "ip", "region_name"])
|
97
|
-
expect(event.get("[target][city_name]")).to eq("Malden")
|
98
|
-
expect(event.get("[target][region_name]")).to eq("Massachusetts")
|
99
|
-
end
|
8
|
+
describe "database path", :aggregate_failures do
|
9
|
+
let(:plugin) { LogStash::Filters::GeoIP.new("source" => "[target][ip]", "database" => DEFAULT_ASN_DB_PATH) }
|
100
10
|
|
11
|
+
before :each do
|
12
|
+
logstash_path = ENV['LOGSTASH_PATH'] || '/usr/share/logstash' # docker logstash home
|
13
|
+
stub_const('LogStash::Environment::LOGSTASH_HOME', logstash_path)
|
101
14
|
end
|
102
15
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
config <<-CONFIG
|
107
|
-
filter {
|
108
|
-
geoip {
|
109
|
-
source => "ip"
|
110
|
-
}
|
111
|
-
}
|
112
|
-
CONFIG
|
113
|
-
expected_fields = %w(ip country_code2 country_code3 country_name
|
114
|
-
continent_code region_name city_name postal_code
|
115
|
-
dma_code timezone)
|
116
|
-
|
117
|
-
sample("ip" => "1.1.1.1") do
|
118
|
-
checked = 0
|
119
|
-
expected_fields.each do |f|
|
120
|
-
next unless subject.get("geoip")[f]
|
121
|
-
checked += 1
|
122
|
-
insist { subject.get("geoip")[f].encoding } == Encoding::UTF_8
|
16
|
+
context "select_database_path with static path" do
|
17
|
+
it "should be the assigned path" do
|
18
|
+
expect(plugin.select_database_path).to eql(DEFAULT_ASN_DB_PATH)
|
123
19
|
end
|
124
|
-
insist { checked } > 0
|
125
20
|
end
|
126
21
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
next unless subject.get("geoip")[f]
|
131
|
-
checked += 1
|
132
|
-
insist { subject.get("geoip")[f].encoding } == Encoding::UTF_8
|
22
|
+
describe "> 7.13" do
|
23
|
+
it "load_database_manager? should be true" do
|
24
|
+
expect(plugin.load_database_manager?).to be_truthy
|
133
25
|
end
|
134
|
-
|
135
|
-
end
|
136
|
-
|
137
|
-
end
|
26
|
+
end if MAJOR >= 8 || (MAJOR == 7 && MINOR >= 13)
|
138
27
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
let(:plugin) { LogStash::Filters::GeoIP.new("source" => "message", "fields" => ["country_name", "location", "longitude"]) }
|
143
|
-
|
144
|
-
before do
|
145
|
-
plugin.register
|
146
|
-
plugin.filter(event)
|
147
|
-
end
|
148
|
-
|
149
|
-
it "should have a location field" do
|
150
|
-
expect(event.get("[geoip][location]")).not_to(be_nil)
|
28
|
+
describe "<= 7.12" do
|
29
|
+
it "load_database_manager? should be false" do
|
30
|
+
expect(plugin.load_database_manager?).to be_falsey
|
151
31
|
end
|
152
|
-
end
|
153
32
|
|
154
|
-
|
155
|
-
|
156
|
-
it_behaves_like "an event with a [geoip][location] field"
|
157
|
-
end
|
33
|
+
describe "select_database_path without path setting" do
|
34
|
+
let(:plugin) { LogStash::Filters::GeoIP.new("source" => "[target][ip]") }
|
158
35
|
|
159
|
-
|
160
|
-
|
161
|
-
it_behaves_like "an event with a [geoip][location] field"
|
162
|
-
end
|
163
|
-
|
164
|
-
context "when both latitude and longitude field are excluded" do
|
165
|
-
let(:fields) { ["country_name", "location"] }
|
166
|
-
it_behaves_like "an event with a [geoip][location] field"
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
describe "an invalid IP" do
|
171
|
-
config <<-CONFIG
|
172
|
-
filter {
|
173
|
-
geoip {
|
174
|
-
source => "ip"
|
175
|
-
database => "#{CITYDB}"
|
176
|
-
}
|
177
|
-
}
|
178
|
-
CONFIG
|
179
|
-
describe "should not raise an error" do
|
180
|
-
sample("ip" => "-") do
|
181
|
-
expect{ subject }.to_not raise_error
|
182
|
-
end
|
183
|
-
|
184
|
-
sample("ip" => "~") do
|
185
|
-
expect{ subject }.to_not raise_error
|
186
|
-
end
|
187
|
-
|
188
|
-
sample("ip" => "") do
|
189
|
-
expect{ subject }.to_not raise_error
|
190
|
-
end
|
191
|
-
|
192
|
-
sample("ip" => " ") do
|
193
|
-
expect{ subject }.to_not raise_error
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
describe "filter method outcomes" do
|
198
|
-
let(:plugin) { LogStash::Filters::GeoIP.new("source" => "message", "add_tag" => "done", "database" => CITYDB) }
|
199
|
-
let(:event) { LogStash::Event.new("message" => ipstring) }
|
200
|
-
|
201
|
-
before do
|
202
|
-
plugin.register
|
203
|
-
plugin.filter(event)
|
204
|
-
end
|
205
|
-
|
206
|
-
context "when the bad IP is N/A" do
|
207
|
-
# regression test for issue https://github.com/logstash-plugins/logstash-filter-geoip/issues/50
|
208
|
-
let(:ipstring) { "N/A" }
|
209
|
-
|
210
|
-
it "should set the target field to an empty hash" do
|
211
|
-
expect(event.get("geoip")).to eq({})
|
212
|
-
end
|
213
|
-
|
214
|
-
it "should add failure tags" do
|
215
|
-
expect(event.get("tags")).to include("_geoip_lookup_failure")
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
context "when the bad IP is two ip comma separated" do
|
220
|
-
# regression test for issue https://github.com/logstash-plugins/logstash-filter-geoip/issues/51
|
221
|
-
let(:ipstring) { "123.45.67.89,61.160.232.222" }
|
222
|
-
|
223
|
-
it "should set the target field to an empty hash" do
|
224
|
-
expect(event.get("geoip")).to eq({})
|
36
|
+
it "should be default" do
|
37
|
+
expect(plugin.select_database_path).to eql(DEFAULT_CITY_DB_PATH)
|
225
38
|
end
|
226
39
|
end
|
227
|
-
|
228
|
-
context "when a IP is not found in the DB" do
|
229
|
-
let(:ipstring) { "0.0.0.0" }
|
230
|
-
|
231
|
-
it "should set the target field to an empty hash" do
|
232
|
-
expect(event.get("geoip")).to eq({})
|
233
|
-
expect(event.get("tags")).to include("_geoip_lookup_failure")
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
context "when IP is IPv6 format for localhost" do
|
238
|
-
let(:ipstring) { "::1" }
|
239
|
-
|
240
|
-
it "should set the target field to an empty hash" do
|
241
|
-
expect(event.get("geoip")).to eq({})
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
context "when IP is valid IPv6 format" do
|
246
|
-
let(:ipstring) { "2607:f0d0:1002:51::4" }
|
247
|
-
|
248
|
-
it "should set the target fields properly" do
|
249
|
-
expect(event.get("geoip")).not_to be_empty
|
250
|
-
expect(event.get("geoip")["ip"]).to eq("2607:f0d0:1002:51:0:0:0:4")
|
251
|
-
expect(event.get("geoip").to_hash.keys.sort).to eq(
|
252
|
-
["continent_code", "country_code2", "country_code3", "country_name", "ip", "latitude", "location", "longitude", "timezone"]
|
253
|
-
)
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
end
|
258
|
-
|
259
|
-
end
|
260
|
-
|
261
|
-
describe "an invalid database" do
|
262
|
-
config <<-CONFIG
|
263
|
-
filter {
|
264
|
-
geoip {
|
265
|
-
source => "ip"
|
266
|
-
database => "./Gemfile"
|
267
|
-
}
|
268
|
-
}
|
269
|
-
CONFIG
|
270
|
-
|
271
|
-
context "should return the correct sourcefield in the logging message" do
|
272
|
-
sample("ip" => "8.8.8.8") do
|
273
|
-
expect { subject }.to raise_error(java.lang.IllegalArgumentException, "The database provided is invalid or corrupted.")
|
274
|
-
end
|
275
|
-
end
|
40
|
+
end if MAJOR < 7 || (MAJOR == 7 && MINOR <= 12)
|
276
41
|
end
|
277
|
-
|
278
|
-
describe "GeoIP2-ASN database" do
|
279
|
-
config <<-CONFIG
|
280
|
-
filter {
|
281
|
-
geoip {
|
282
|
-
source => "ip"
|
283
|
-
# database => "" # use the bundled ASN
|
284
|
-
default_database_type => "ASN"
|
285
|
-
}
|
286
|
-
}
|
287
|
-
CONFIG
|
288
|
-
|
289
|
-
sample("ip" => "8.8.8.8") do
|
290
|
-
expect(subject.get("geoip")).not_to be_empty
|
291
|
-
expect(subject.get("geoip")["asn"]).to eq(15169)
|
292
|
-
expect(subject.get("geoip")["as_org"]).to eq("Google LLC")
|
293
|
-
end
|
294
|
-
|
295
|
-
|
296
|
-
end
|
297
|
-
|
298
42
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "logstash-core/logstash-core"
|
2
|
+
require "digest"
|
3
|
+
|
4
|
+
def get_vendor_path
|
5
|
+
::File.expand_path("../../vendor/", ::File.dirname(__FILE__))
|
6
|
+
end
|
7
|
+
|
8
|
+
def get_file_path(filename)
|
9
|
+
::File.join(get_vendor_path, filename)
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_metadata_database_name
|
13
|
+
::File.exist?(METADATA_PATH) ? ::File.read(METADATA_PATH).split(",").last[0..-2] : nil
|
14
|
+
end
|
15
|
+
|
16
|
+
METADATA_PATH = get_file_path("metadata.csv")
|
17
|
+
DEFAULT_CITY_DB_PATH = get_file_path("GeoLite2-City.mmdb")
|
18
|
+
DEFAULT_ASN_DB_PATH = get_file_path("GeoLite2-ASN.mmdb")
|
19
|
+
|
20
|
+
major, minor = LOGSTASH_VERSION.split(".")
|
21
|
+
MAJOR = major.to_i
|
22
|
+
MINOR = minor.to_i
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-filter-geoip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 7.0.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,7 +92,10 @@ files:
|
|
92
92
|
- lib/logstash/filters/geoip/patch.rb
|
93
93
|
- logstash-filter-geoip.gemspec
|
94
94
|
- maxmind-db-NOTICE.txt
|
95
|
+
- spec/filters/geoip_offline_spec.rb
|
96
|
+
- spec/filters/geoip_online_spec.rb
|
95
97
|
- spec/filters/geoip_spec.rb
|
98
|
+
- spec/filters/test_helper.rb
|
96
99
|
- vendor/GeoLite2-ASN.mmdb
|
97
100
|
- vendor/GeoLite2-City.mmdb
|
98
101
|
- vendor/jar-dependencies/com/maxmind/db/maxmind-db/1.2.2/maxmind-db-1.2.2.jar
|
@@ -126,4 +129,7 @@ signing_key:
|
|
126
129
|
specification_version: 4
|
127
130
|
summary: Adds geographical information about an IP address
|
128
131
|
test_files:
|
132
|
+
- spec/filters/geoip_offline_spec.rb
|
133
|
+
- spec/filters/geoip_online_spec.rb
|
129
134
|
- spec/filters/geoip_spec.rb
|
135
|
+
- spec/filters/test_helper.rb
|