logstash-filter-geoip 7.2.7-java → 7.2.11-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/docs/index.asciidoc +63 -23
- data/logstash-filter-geoip.gemspec +1 -1
- data/spec/filters/geoip_ecs_spec.rb +96 -16
- data/spec/filters/geoip_offline_spec.rb +53 -263
- data/vendor/jar-dependencies/org/logstash/filters/logstash-filter-geoip/6.0.0/logstash-filter-geoip-6.0.0.jar +0 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e1f0799be232e80ed3db8f0d31b4131c921d549183d2f47678af3fd9cdfd21f
|
4
|
+
data.tar.gz: e656dd5cd6440d13af48a7193f26962c4236267fcf2afd9bc0a9f4f8e8c5e3e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eadc947645031bd5539ac42e910da0c1230d2137936eec668f23da4e6de6e55b5ceaa2a6eb1cf0b7699a43d61c03c1e6df95b51681e61d3983471070d1cac9aa
|
7
|
+
data.tar.gz: 9a5ee36471512f5724ebc7013d3d21bce6d64db50ac6874f8c45d2e8a8facbad14a428e4ea2857cbeb20d438e363dbcdad79a6133b851c98c575a82da0e91a1f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 7.2.11
|
2
|
+
- Improved compatibility with the Elastic Common Schema [#206](https://github.com/logstash-plugins/logstash-filter-geoip/pull/206)
|
3
|
+
- Added support for ECS's composite `region_iso_code` (`US-WA`), which _replaces_ the non-ECS `region_code` (`WA`) as a default field with City databases. To get the stand-alone `region_code` in ECS mode, you must include it in the `fields` directive.
|
4
|
+
- [DOC] Improve ECS-related documentation
|
5
|
+
|
6
|
+
## 7.2.10
|
7
|
+
- [DOC] Air-gapped environment requires both ASN and City databases [#204](https://github.com/logstash-plugins/logstash-filter-geoip/pull/204)
|
8
|
+
|
9
|
+
## 7.2.9
|
10
|
+
- Fix: red CI in Logstash 8.0 [#201](https://github.com/logstash-plugins/logstash-filter-geoip/pull/201)
|
11
|
+
- Update Log4j dependency to 2.17.1
|
12
|
+
|
13
|
+
## 7.2.8
|
14
|
+
- Update Log4j dependency to 2.17.0
|
15
|
+
|
1
16
|
## 7.2.7
|
2
17
|
- Ensure java 8 compatibility [#197](https://github.com/logstash-plugins/logstash-filter-geoip/pull/197)
|
3
18
|
|
data/docs/index.asciidoc
CHANGED
@@ -86,10 +86,10 @@ a secure proxy. You can then specify the proxy endpoint URL in the
|
|
86
86
|
If you work in air-gapped environment and can't update your databases from the Elastic endpoint,
|
87
87
|
You can then download databases from MaxMind and bootstrap the service.
|
88
88
|
|
89
|
-
. Download
|
89
|
+
. Download both `GeoLite2-ASN.mmdb` and `GeoLite2-City.mmdb` database files from the
|
90
90
|
http://dev.maxmind.com/geoip/geoip2/geolite2[MaxMind site].
|
91
91
|
|
92
|
-
. Copy
|
92
|
+
. Copy both database files to a single directory.
|
93
93
|
|
94
94
|
. https://www.elastic.co/downloads/elasticsearch[Download {es}].
|
95
95
|
|
@@ -169,14 +169,57 @@ Example response:
|
|
169
169
|
}
|
170
170
|
--------------------------------------------------
|
171
171
|
|
172
|
+
[id="plugins-{type}s-{plugin}-field-mapping"]
|
173
|
+
==== Field mapping
|
174
|
+
|
175
|
+
When this plugin is run with <<plugins-{type}s-{plugin}-ecs_compatibility>> disabled, the MaxMind DB's fields are added directly to the <<plugins-{type}s-{plugin}-target>>.
|
176
|
+
When ECS compatibility is enabled, the fields are structured to fit into an ECS shape.
|
177
|
+
|
178
|
+
[cols="3,5,3"]
|
179
|
+
|===========================
|
180
|
+
| Database Field Name | ECS Field | Example
|
181
|
+
|
182
|
+
| `ip` | `[ip]` | `12.34.56.78`
|
183
|
+
|
184
|
+
| `city_name` | `[geo][city_name]` | `Seattle`
|
185
|
+
| `country_name` | `[geo][country_name]` | `United States`
|
186
|
+
| `continent_code` | `[geo][continent_code]` | `NA`
|
187
|
+
| `continent_name` | `[geo][continent_name]` | `North America`
|
188
|
+
| `country_code2` | `[geo][country_iso_code]` | `US`
|
189
|
+
| `country_code3` | _N/A_ | `US`
|
190
|
+
|
191
|
+
_maintained for legacy
|
192
|
+
support, but populated
|
193
|
+
with 2-character country
|
194
|
+
code_
|
195
|
+
|
196
|
+
| `postal_code` | `[geo][postal_code]` | `98106`
|
197
|
+
| `region_name` | `[geo][region_name]` | `Washington`
|
198
|
+
| `region_code` | `[geo][region_code]` | `WA`
|
199
|
+
| `region_iso_code`* | `[geo][region_iso_code]` | `US-WA`
|
200
|
+
| `timezone` | `[geo][timezone]` | `America/Los_Angeles`
|
201
|
+
| `location`* | `[geo][location]` | `{"lat": 47.6062, "lon": -122.3321}"`
|
202
|
+
| `latitude` | `[geo][location][lat]` | `47.6062`
|
203
|
+
| `longitude` | `[geo][location][lon]` | `-122.3321`
|
204
|
+
|
205
|
+
| `domain` | `[domain]` | `example.com`
|
206
|
+
|
207
|
+
| `asn` | `[as][number]` | `98765`
|
208
|
+
| `as_org` | `[as][organization][name]` | `Elastic, NV`
|
209
|
+
|
210
|
+
| `isp` | `[mmdb][isp]` | `InterLink Supra LLC`
|
211
|
+
| `dma_code` | `[mmdb][dma_code]` | `819`
|
212
|
+
| `organization` | `[mmdb][organization]` | `Elastic, NV`
|
213
|
+
|===========================
|
214
|
+
|
215
|
+
NOTE: `*` indicates a composite field, which is only populated if GeoIP lookup result contains all components.
|
216
|
+
|
172
217
|
==== Details
|
173
218
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
{logstash-ref}/plugins-outputs-elasticsearch.html[elasticsearch output] maps
|
179
|
-
the `[geoip][location]` field to an {ref}/geo-point.html[Elasticsearch Geo_point datatype].
|
219
|
+
When using a City database, the enrichment is aborted if no latitude/longitude pair is available.
|
220
|
+
|
221
|
+
The `location` field combines the latitude and longitude into a structure called https://datatracker.ietf.org/doc/html/rfc7946[GeoJSON].
|
222
|
+
When you are using a default <<plugins-{type}s-{plugin}-target>>, the templates provided by the {logstash-ref}/plugins-outputs-elasticsearch.html[elasticsearch output] map the field to an {ref}/geo-point.html[Elasticsearch Geo_point datatype].
|
180
223
|
|
181
224
|
As this field is a `geo_point` _and_ it is still valid GeoJSON, you get
|
182
225
|
the awesomeness of Elasticsearch's geospatial query, facet and filter functions
|
@@ -242,16 +285,16 @@ number of cache misses and waste memory.
|
|
242
285
|
===== `database`
|
243
286
|
|
244
287
|
* Value type is <<path,path>>
|
245
|
-
* If not specified, the database defaults to the GeoLite2 City database that ships with Logstash.
|
288
|
+
* If not specified, the database defaults to the `GeoLite2 City` database that ships with Logstash.
|
246
289
|
|
247
|
-
The path to MaxMind's database file that Logstash should use.
|
248
|
-
|
249
|
-
|
290
|
+
The path to MaxMind's database file that Logstash should use.
|
291
|
+
The default database is `GeoLite2-City`.
|
292
|
+
This plugin supports several free databases (`GeoLite2-City`, `GeoLite2-Country`, `GeoLite2-ASN`)
|
293
|
+
and a selection of commercially-licensed databases (`GeoIP2-City`, `GeoIP2-ISP`, `GeoIP2-Country`).
|
250
294
|
|
251
|
-
Database auto-update applies to default distribution.
|
252
|
-
auto-update
|
253
|
-
See
|
254
|
-
<<plugins-{type}s-{plugin}-database_license,Database License>> for more information.
|
295
|
+
Database auto-update applies to the default distribution.
|
296
|
+
When `database` points to user's database path, auto-update is disabled.
|
297
|
+
See <<plugins-{type}s-{plugin}-database_license,Database License>> for more information.
|
255
298
|
|
256
299
|
[id="plugins-{type}s-{plugin}-default_database_type"]
|
257
300
|
===== `default_database_type`
|
@@ -270,13 +313,10 @@ This plugin now includes both the GeoLite2-City and GeoLite2-ASN databases. If
|
|
270
313
|
|
271
314
|
An array of geoip fields to be included in the event.
|
272
315
|
|
273
|
-
Possible fields depend on the database type.
|
274
|
-
are included in the event.
|
316
|
+
Possible fields depend on the database type.
|
317
|
+
By default, all geoip fields from the relevant database are included in the event.
|
275
318
|
|
276
|
-
For
|
277
|
-
`city_name`, `continent_code`, `country_code2`, `country_code3`, `country_name`,
|
278
|
-
`dma_code`, `ip`, `latitude`, `location`, `longitude`, `postal_code`, `region_code`,
|
279
|
-
`region_name` and `timezone`.
|
319
|
+
For a complete list of available fields and how they map to an event's structure, see <<plugins-{type}s-{plugin}-field-mapping,field mapping>>.
|
280
320
|
|
281
321
|
[id="plugins-{type}s-{plugin}-ecs_compatibility"]
|
282
322
|
===== `ecs_compatibility`
|
@@ -284,7 +324,7 @@ For the built-in GeoLite2 City database, the following are available:
|
|
284
324
|
* Value type is <<string,string>>
|
285
325
|
* Supported values are:
|
286
326
|
** `disabled`: unstructured geo data added at root level
|
287
|
-
** `v1`, `v8`:
|
327
|
+
** `v1`, `v8`: use fields that are compatible with Elastic Common Schema. Example: `[client][geo][country_name]`. See <<plugins-{type}s-{plugin}-field-mapping,field mapping>> for more info.
|
288
328
|
* Default value depends on which version of Logstash is running:
|
289
329
|
** When Logstash provides a `pipeline.ecs_compatibility` setting, its value is used as the default
|
290
330
|
** Otherwise, the default value is `disabled`.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-filter-geoip'
|
4
|
-
s.version = '7.2.
|
4
|
+
s.version = '7.2.11'
|
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"
|
@@ -27,6 +27,10 @@ describe LogStash::Filters::GeoIP do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
context "with city database" do
|
30
|
+
# example.com, has been static for 10+ years
|
31
|
+
# and has city-level details
|
32
|
+
let(:ip) { "93.184.216.34" }
|
33
|
+
|
30
34
|
let(:options) { common_options }
|
31
35
|
|
32
36
|
it "should return geo in target" do
|
@@ -36,19 +40,26 @@ describe LogStash::Filters::GeoIP do
|
|
36
40
|
expect( event.get ecs_select[disabled: "[#{target}][country_code2]", v1: "[#{target}][geo][country_iso_code]"] ).to eq 'US'
|
37
41
|
expect( event.get ecs_select[disabled: "[#{target}][country_name]", v1: "[#{target}][geo][country_name]"] ).to eq 'United States'
|
38
42
|
expect( event.get ecs_select[disabled: "[#{target}][continent_code]", v1: "[#{target}][geo][continent_code]"] ).to eq 'NA'
|
39
|
-
expect( event.get ecs_select[disabled: "[#{target}][location][lat]", v1: "[#{target}][geo][location][lat]"] ).to eq
|
40
|
-
expect( event.get ecs_select[disabled: "[#{target}][location][lon]", v1: "[#{target}][geo][location][lon]"] ).to eq -
|
43
|
+
expect( event.get ecs_select[disabled: "[#{target}][location][lat]", v1: "[#{target}][geo][location][lat]"] ).to eq 42.1596
|
44
|
+
expect( event.get ecs_select[disabled: "[#{target}][location][lon]", v1: "[#{target}][geo][location][lon]"] ).to eq -70.8217
|
45
|
+
expect( event.get ecs_select[disabled: "[#{target}][city_name]", v1: "[#{target}][geo][city_name]"] ).to eq 'Norwell'
|
46
|
+
expect( event.get ecs_select[disabled: "[#{target}][dma_code]", v1: "[#{target}][mmdb][dma_code]"] ).to eq 506
|
47
|
+
expect( event.get ecs_select[disabled: "[#{target}][region_name]", v1: "[#{target}][geo][region_name]"] ).to eq 'Massachusetts'
|
41
48
|
|
42
49
|
if ecs_select.active_mode == :disabled
|
43
50
|
expect( event.get "[#{target}][country_code3]" ).to eq 'US'
|
51
|
+
expect( event.get "[#{target}][region_code]" ).to eq 'MA'
|
52
|
+
expect( event.get "[#{target}][region_iso_code]" ).to be_nil
|
44
53
|
else
|
45
54
|
expect( event.get "[#{target}][geo][country_code3]" ).to be_nil
|
46
55
|
expect( event.get "[#{target}][country_code3]" ).to be_nil
|
56
|
+
expect( event.get "[#{target}][geo][region_iso_code]" ).to eq 'US-MA'
|
57
|
+
expect( event.get "[#{target}][region_code]" ).to be_nil
|
47
58
|
end
|
59
|
+
puts event.to_hash.inspect
|
48
60
|
end
|
49
61
|
end
|
50
62
|
|
51
|
-
|
52
63
|
context "with ASN database" do
|
53
64
|
let(:options) { common_options.merge({"database" => ASNDB}) }
|
54
65
|
|
@@ -59,27 +70,96 @@ describe LogStash::Filters::GeoIP do
|
|
59
70
|
expect( event.get ecs_select[disabled: "[#{target}][asn]", v1: "[#{target}][as][number]"] ).to eq 15169
|
60
71
|
expect( event.get ecs_select[disabled: "[#{target}][as_org]", v1: "[#{target}][as][organization][name]"] ).to eq "Google LLC"
|
61
72
|
end
|
73
|
+
|
74
|
+
context "with customize fields" do
|
75
|
+
let(:fields) { ["AUTONOMOUS_SYSTEM_NUMBER"] }
|
76
|
+
let(:options) { common_options.merge({"database" => ASNDB, "fields" => fields}) }
|
77
|
+
|
78
|
+
it "should give asn field" do
|
79
|
+
plugin.filter(event)
|
80
|
+
|
81
|
+
expect( event.get ecs_select[disabled: "[#{target}][ip]", v1: "[#{target}][ip]"] ).to be_nil
|
82
|
+
expect( event.get ecs_select[disabled: "[#{target}][as_org]", v1: "[#{target}][as][organization][name]"] ).to be_nil
|
83
|
+
|
84
|
+
expect( event.get ecs_select[disabled: "[#{target}][asn]", v1: "[#{target}][as][number]"] ).to eq 15169
|
85
|
+
end
|
86
|
+
end
|
62
87
|
end
|
63
88
|
|
64
89
|
context "with customize fields" do
|
65
|
-
|
66
|
-
|
90
|
+
context "continent_name and timezone" do
|
91
|
+
let(:fields) { ["continent_name", "timezone"] }
|
92
|
+
let(:options) { common_options.merge({"fields" => fields}) }
|
67
93
|
|
68
|
-
|
69
|
-
|
94
|
+
it "should return fields in UTF8" do
|
95
|
+
plugin.filter(event)
|
96
|
+
|
97
|
+
expect( event.get ecs_select[disabled: "[#{target}][ip]", v1: "[#{target}][ip]"] ).to be_nil
|
98
|
+
expect( event.get ecs_select[disabled: "[#{target}][country_code2]", v1: "[#{target}][geo][country_iso_code]"] ).to be_nil
|
99
|
+
expect( event.get ecs_select[disabled: "[#{target}][country_name]", v1: "[#{target}][geo][country_name]"] ).to be_nil
|
100
|
+
expect( event.get ecs_select[disabled: "[#{target}][continent_code]", v1: "[#{target}][geo][continent_code]"] ).to be_nil
|
101
|
+
expect( event.get ecs_select[disabled: "[#{target}][location][lat]", v1: "[#{target}][geo][location][lat]"] ).to be_nil
|
102
|
+
expect( event.get ecs_select[disabled: "[#{target}][location][lon]", v1: "[#{target}][geo][location][lon]"] ).to be_nil
|
103
|
+
|
104
|
+
continent_name = event.get ecs_select[disabled: "[#{target}][continent_name]", v1: "[#{target}][geo][continent_name]"]
|
105
|
+
timezone = event.get ecs_select[disabled: "[#{target}][timezone]", v1: "[#{target}][geo][timezone]"]
|
106
|
+
expect( continent_name ).to eq "North America"
|
107
|
+
expect( timezone ).to eq "America/Chicago"
|
108
|
+
expect( continent_name.encoding ).to eq Encoding::UTF_8
|
109
|
+
expect( timezone.encoding ).to eq Encoding::UTF_8
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "location" do
|
114
|
+
shared_examples "provide location, lat and lon" do
|
115
|
+
it "should return location, lat and lon" do
|
116
|
+
plugin.filter(event)
|
117
|
+
|
118
|
+
expect( event.get ecs_select[disabled: "[#{target}][ip]", v1: "[#{target}][ip]"] ).to be_nil
|
119
|
+
expect( event.get ecs_select[disabled: "[#{target}][country_code2]", v1: "[#{target}][geo][country_iso_code]"] ).to be_nil
|
120
|
+
expect( event.get ecs_select[disabled: "[#{target}][country_name]", v1: "[#{target}][geo][country_name]"] ).to be_nil
|
121
|
+
expect( event.get ecs_select[disabled: "[#{target}][continent_code]", v1: "[#{target}][geo][continent_code]"] ).to be_nil
|
122
|
+
expect( event.get ecs_select[disabled: "[#{target}][continent_name]", v1: "[#{target}][geo][continent_name]"] ).to be_nil
|
123
|
+
expect( event.get ecs_select[disabled: "[#{target}][timezone]", v1: "[#{target}][geo][timezone]"] ).to be_nil
|
124
|
+
|
125
|
+
expect( event.get ecs_select[disabled: "[#{target}][location][lat]", v1: "[#{target}][geo][location][lat]"] ).not_to be_nil
|
126
|
+
expect( event.get ecs_select[disabled: "[#{target}][location][lon]", v1: "[#{target}][geo][location][lon]"] ).not_to be_nil
|
127
|
+
end
|
128
|
+
end
|
70
129
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
expect( event.get ecs_select[disabled: "[#{target}][location][lon]", v1: "[#{target}][geo][location][lon]"] ).to be_nil
|
130
|
+
context "location and longitude" do
|
131
|
+
let(:fields) { ["location", "longitude"] }
|
132
|
+
let(:options) { common_options.merge({"fields" => fields}) }
|
133
|
+
it_behaves_like "provide location, lat and lon"
|
134
|
+
end
|
77
135
|
|
78
|
-
|
79
|
-
|
136
|
+
context "location and latitude" do
|
137
|
+
let(:fields) { ["location", "latitude"] }
|
138
|
+
let(:options) { common_options.merge({"fields" => fields}) }
|
139
|
+
it_behaves_like "provide location, lat and lon"
|
140
|
+
end
|
80
141
|
end
|
81
|
-
end
|
82
142
|
|
143
|
+
context "continent_code and IP is IPv6 format" do
|
144
|
+
let(:ip) { "2607:f0d0:1002:51::4" }
|
145
|
+
let(:fields) { ["continent_code", "ip"] }
|
146
|
+
let(:options) { common_options.merge({"fields" => fields}) }
|
147
|
+
|
148
|
+
it "should return fields" do
|
149
|
+
plugin.filter(event)
|
150
|
+
|
151
|
+
expect( event.get ecs_select[disabled: "[#{target}][country_code2]", v1: "[#{target}][geo][country_iso_code]"] ).to be_nil
|
152
|
+
expect( event.get ecs_select[disabled: "[#{target}][country_name]", v1: "[#{target}][geo][country_name]"] ).to be_nil
|
153
|
+
expect( event.get ecs_select[disabled: "[#{target}][continent_name]", v1: "[#{target}][geo][continent_name]"] ).to be_nil
|
154
|
+
expect( event.get ecs_select[disabled: "[#{target}][location][lat]", v1: "[#{target}][geo][location][lat]"] ).to be_nil
|
155
|
+
expect( event.get ecs_select[disabled: "[#{target}][location][lon]", v1: "[#{target}][geo][location][lon]"] ).to be_nil
|
156
|
+
expect( event.get ecs_select[disabled: "[#{target}][timezone]", v1: "[#{target}][geo][timezone]"] ).to be_nil
|
157
|
+
|
158
|
+
expect( event.get ecs_select[disabled: "[#{target}][ip]", v1: "[#{target}][ip]"] ).to eq("2607:f0d0:1002:51:0:0:0:4")
|
159
|
+
expect( event.get ecs_select[disabled: "[#{target}][continent_code]", v1: "[#{target}][geo][continent_code]"] ).to eq("NA")
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
83
163
|
end
|
84
164
|
end
|
85
165
|
|
@@ -6,78 +6,33 @@ require "logstash/filters/geoip"
|
|
6
6
|
CITYDB = ::Dir.glob(::File.expand_path(::File.join("..", "..", "..", "vendor", "GeoLite2-City.mmdb"), __FILE__)).first
|
7
7
|
ASNDB = ::Dir.glob(::File.expand_path(::File.join("..", "..", "..", "vendor", "GeoLite2-ASN.mmdb"), __FILE__)).first
|
8
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
9
|
|
30
|
-
|
31
|
-
|
32
|
-
|
10
|
+
describe LogStash::Filters::GeoIP do
|
11
|
+
shared_examples "invalid empty IP" do
|
12
|
+
it "should not give target field" do
|
13
|
+
expect(event.get(target)).to be_nil
|
14
|
+
expect(event.get("tags")).to include("_geoip_lookup_failure")
|
33
15
|
end
|
34
16
|
end
|
35
17
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
18
|
+
shared_examples "invalid string IP" do
|
19
|
+
it "should give empty hash in target field" do
|
20
|
+
expect(event.get(target)).to eq({})
|
21
|
+
expect(event.get("tags")).to include("_geoip_lookup_failure")
|
70
22
|
end
|
71
23
|
end
|
72
24
|
|
73
|
-
|
74
|
-
|
25
|
+
let(:target) { "server" }
|
26
|
+
|
27
|
+
describe "invalid IP" do
|
28
|
+
let(:ip) { "173.9.34.107" }
|
29
|
+
let(:event) { LogStash::Event.new("client" => { "ip" => ip } ) }
|
75
30
|
let(:plugin) {
|
76
31
|
LogStash::Filters::GeoIP.new(
|
77
|
-
"source" => "[
|
78
|
-
"target" =>
|
79
|
-
"fields" => [
|
80
|
-
"
|
32
|
+
"source" => "[client][ip]",
|
33
|
+
"target" => target,
|
34
|
+
"fields" => %w[country_name continent_code],
|
35
|
+
"database" => CITYDB
|
81
36
|
)
|
82
37
|
}
|
83
38
|
|
@@ -86,200 +41,71 @@ describe LogStash::Filters::GeoIP do
|
|
86
41
|
plugin.filter(event)
|
87
42
|
end
|
88
43
|
|
89
|
-
context "when
|
90
|
-
|
91
|
-
it "should
|
92
|
-
expect(event.get(
|
44
|
+
context "when ip is 127.0.0.1" do
|
45
|
+
let(:ip) { "127.0.0.1" }
|
46
|
+
it "should give empty hash" do
|
47
|
+
expect(event.get(target)).to eq({})
|
93
48
|
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
49
|
end
|
102
50
|
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
51
|
+
context "when ip is empty string" do
|
52
|
+
let(:ip) { "" }
|
53
|
+
it_behaves_like "invalid empty IP"
|
126
54
|
end
|
127
55
|
|
128
|
-
|
129
|
-
|
130
|
-
|
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
|
56
|
+
context "when ip is space" do
|
57
|
+
let(:ip) { " " }
|
58
|
+
it_behaves_like "invalid empty IP"
|
136
59
|
end
|
137
60
|
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|
61
|
+
context "when ip is dash" do
|
62
|
+
let(:ip) { "-" }
|
63
|
+
it_behaves_like "invalid string IP"
|
153
64
|
end
|
154
65
|
|
155
|
-
context "when
|
156
|
-
let(:
|
157
|
-
it_behaves_like "
|
66
|
+
context "when ip is N/A" do
|
67
|
+
let(:ip) { "N/A" }
|
68
|
+
it_behaves_like "invalid string IP"
|
158
69
|
end
|
159
70
|
|
160
|
-
context "when
|
161
|
-
let(:
|
162
|
-
it_behaves_like "
|
71
|
+
context "when ip is two ip comma separated" do
|
72
|
+
let(:ip) { "123.45.67.89,61.160.232.222" }
|
73
|
+
it_behaves_like "invalid string IP"
|
163
74
|
end
|
164
75
|
|
165
|
-
context "when
|
166
|
-
let(:
|
167
|
-
it_behaves_like "
|
76
|
+
context "when ip is not found in the DB" do
|
77
|
+
let(:ip) { "0.0.0.0" }
|
78
|
+
it_behaves_like "invalid string IP"
|
168
79
|
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
80
|
|
185
|
-
|
186
|
-
|
187
|
-
|
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
|
81
|
+
context "when ip is IPv6 format for localhost" do
|
82
|
+
let(:ip) { "::1" }
|
83
|
+
it_behaves_like "invalid string IP"
|
196
84
|
end
|
85
|
+
end
|
197
86
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
context "when database manager give nil database path" do
|
203
|
-
it "should tag expired database" do
|
204
|
-
expect(plugin).to receive(:select_database_path).and_return(nil)
|
205
|
-
|
206
|
-
plugin.register
|
207
|
-
plugin.filter(event)
|
208
|
-
|
209
|
-
expect(event.get("tags")).to include("_geoip_expired_database")
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
87
|
+
describe "database path is empty" do
|
88
|
+
let(:plugin) { LogStash::Filters::GeoIP.new("source" => "message", "target" => target) }
|
89
|
+
let(:event) { LogStash::Event.new("message" => "8.8.8.8") }
|
213
90
|
|
214
|
-
|
215
|
-
|
216
|
-
|
91
|
+
context "when database manager give nil database path" do
|
92
|
+
it "should tag expired database" do
|
93
|
+
expect(plugin).to receive(:select_database_path).and_return(nil)
|
217
94
|
|
218
|
-
before do
|
219
95
|
plugin.register
|
220
96
|
plugin.filter(event)
|
221
|
-
end
|
222
|
-
|
223
|
-
context "when the bad IP is N/A" do
|
224
|
-
# regression test for issue https://github.com/logstash-plugins/logstash-filter-geoip/issues/50
|
225
|
-
let(:ipstring) { "N/A" }
|
226
|
-
|
227
|
-
it "should set the target field to an empty hash" do
|
228
|
-
expect(event.get("geoip")).to eq({})
|
229
|
-
end
|
230
|
-
|
231
|
-
it "should add failure tags" do
|
232
|
-
expect(event.get("tags")).to include("_geoip_lookup_failure")
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
context "when the bad IP is two ip comma separated" do
|
237
|
-
# regression test for issue https://github.com/logstash-plugins/logstash-filter-geoip/issues/51
|
238
|
-
let(:ipstring) { "123.45.67.89,61.160.232.222" }
|
239
97
|
|
240
|
-
|
241
|
-
expect(event.get("geoip")).to eq({})
|
242
|
-
end
|
98
|
+
expect(event.get("tags")).to include("_geoip_expired_database")
|
243
99
|
end
|
244
|
-
|
245
|
-
context "when a IP is not found in the DB" do
|
246
|
-
let(:ipstring) { "0.0.0.0" }
|
247
|
-
|
248
|
-
it "should set the target field to an empty hash" do
|
249
|
-
expect(event.get("geoip")).to eq({})
|
250
|
-
expect(event.get("tags")).to include("_geoip_lookup_failure")
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
context "when IP is IPv6 format for localhost" do
|
255
|
-
let(:ipstring) { "::1" }
|
256
|
-
|
257
|
-
it "should set the target field to an empty hash" do
|
258
|
-
expect(event.get("geoip")).to eq({})
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
context "when IP is valid IPv6 format" do
|
263
|
-
let(:ipstring) { "2607:f0d0:1002:51::4" }
|
264
|
-
|
265
|
-
it "should set the target fields properly" do
|
266
|
-
expect(event.get("geoip")).not_to be_empty
|
267
|
-
expect(event.get("geoip")["ip"]).to eq("2607:f0d0:1002:51:0:0:0:4")
|
268
|
-
expect(event.get("geoip").to_hash.keys.sort).to eq(
|
269
|
-
["continent_code", "country_code2", "country_code3", "country_name", "ip", "latitude", "location", "longitude", "timezone"]
|
270
|
-
)
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
100
|
end
|
275
|
-
|
276
101
|
end
|
277
102
|
|
278
|
-
describe "an invalid database" do
|
103
|
+
describe "database path is an invalid database file" do
|
279
104
|
config <<-CONFIG
|
280
105
|
filter {
|
281
106
|
geoip {
|
282
107
|
source => "ip"
|
108
|
+
target => "geo"
|
283
109
|
database => "./Gemfile"
|
284
110
|
}
|
285
111
|
}
|
@@ -292,40 +118,4 @@ describe LogStash::Filters::GeoIP do
|
|
292
118
|
end
|
293
119
|
end
|
294
120
|
|
295
|
-
describe "GeoIP2-ASN database" do
|
296
|
-
config <<-CONFIG
|
297
|
-
filter {
|
298
|
-
geoip {
|
299
|
-
source => "ip"
|
300
|
-
database => "#{ASNDB}"
|
301
|
-
default_database_type => "ASN"
|
302
|
-
}
|
303
|
-
}
|
304
|
-
CONFIG
|
305
|
-
|
306
|
-
sample("ip" => "8.8.8.8") do
|
307
|
-
expect(subject.get("geoip")).not_to be_empty
|
308
|
-
expect(subject.get("geoip")["asn"]).to eq(15169)
|
309
|
-
expect(subject.get("geoip")["as_org"]).to eq("Google LLC")
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
describe "GeoIP2-ASN database with fields" do
|
314
|
-
config <<-CONFIG
|
315
|
-
filter {
|
316
|
-
geoip {
|
317
|
-
source => "ip"
|
318
|
-
database => "#{ASNDB}"
|
319
|
-
default_database_type => "ASN"
|
320
|
-
fields => [ "AUTONOMOUS_SYSTEM_NUMBER" ]
|
321
|
-
}
|
322
|
-
}
|
323
|
-
CONFIG
|
324
|
-
|
325
|
-
sample("ip" => "8.8.8.8") do
|
326
|
-
expect(subject.get("geoip")).not_to be_empty
|
327
|
-
expect(subject.get("geoip")["asn"]).to eq(15169)
|
328
|
-
end
|
329
|
-
end
|
330
|
-
|
331
121
|
end
|
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: 7.2.
|
4
|
+
version: 7.2.11
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|