logstash-filter-private_geoip 1.0.0
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 +7 -0
- data/Gemfile +2 -0
- data/LICENSE +13 -0
- data/README.md +49 -0
- data/lib/logstash/filters/private_geoip.rb +79 -0
- data/logstash-filter-private_geoip.gemspec +29 -0
- data/spec/filters/private_geoip_spec.rb +140 -0
- data/spec/resources/cidr.json +5 -0
- metadata +102 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bb1d1e7b4b8854ff8ed70dad9b8f2cd995deff51
|
4
|
+
data.tar.gz: 4fd7f2f248d4cd01ef4dd31f8c32c41281121f21
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1989fd62d6cd32f95890430baced04915fefaf89686a0715b5e71a97ebb40e5530e755623a1bc0fa856e63c508f55c0d0d8380523fe8e5c4860f19b5cec556b5
|
7
|
+
data.tar.gz: 114a016e0540a3f77147054f6ee4a9ee29f04efddea782487942996afb32b1364269c229a286d5070b880d5ad78fade46a9f4f3eccce332e9ae9fd70b94fd5df
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright (c) 2015 KULeuven/LIBIS <http://www.libis.be>
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# logstash-filter-private_geoip
|
2
|
+
|
3
|
+
Extends or overwrites the GeoIP event data. If you have a large network with _mixed_ calls from **public** and **private**
|
4
|
+
IP address the **private** IP addresses are NOT resolved by GeoIP.
|
5
|
+
|
6
|
+
If you supply the different local networks they will get mapped.
|
7
|
+
|
8
|
+
## Filter definition
|
9
|
+
```json
|
10
|
+
filter {
|
11
|
+
private_geoip {
|
12
|
+
source => "client_ip"
|
13
|
+
database => "/path/to/network_file.json"
|
14
|
+
target => 'geoip'
|
15
|
+
merge => false
|
16
|
+
}
|
17
|
+
}
|
18
|
+
```
|
19
|
+
|
20
|
+
* source: field that contains the ip address that needs to be mapped. This can be http_clientip, http_x_forwarded_for or ...
|
21
|
+
* database: location of the the JSON mapping file.
|
22
|
+
* target: where should the mapping result be stored. default = private_geoip but you could change it to geoip
|
23
|
+
* merge: should the target be overwritten with the mapping result. default = true
|
24
|
+
|
25
|
+
## Mapping definition
|
26
|
+
```JSON
|
27
|
+
[
|
28
|
+
{"cidr":"10.33.104.0/22",
|
29
|
+
"data":{"organization_name":"XYZ Faculty",
|
30
|
+
"city_name":"Leuven",
|
31
|
+
"country_name":"Belgium",
|
32
|
+
...
|
33
|
+
}
|
34
|
+
},
|
35
|
+
...
|
36
|
+
]
|
37
|
+
```
|
38
|
+
|
39
|
+
* cidr: contains the network
|
40
|
+
* data: can contain any key/value pair. If you want to extend/overwrite GeoIP take those fields ...
|
41
|
+
|
42
|
+
|
43
|
+
# Install
|
44
|
+
|
45
|
+
```sh
|
46
|
+
bin/plugin install /your/local/plugin/logstash-filter-private_geoip.gem
|
47
|
+
```
|
48
|
+
|
49
|
+
Restart LogStash.
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/filters/base"
|
3
|
+
require "logstash/namespace"
|
4
|
+
|
5
|
+
# The Private GeoIP filter add information about local private IP addresses
|
6
|
+
# This is a CIDR filter on steroids
|
7
|
+
|
8
|
+
class LogStash::Filters::PrivateGeoIP < LogStash::Filters::Base
|
9
|
+
config_name "private_geoip"
|
10
|
+
|
11
|
+
#The field that that has the IP address to compare
|
12
|
+
config :source, validate: :string, required: true
|
13
|
+
|
14
|
+
#The path to the JSON file. "data" can contain any key/value pair
|
15
|
+
#[
|
16
|
+
# {
|
17
|
+
# "cidr":"10.32.1.0/24",
|
18
|
+
# "data": {
|
19
|
+
# "organization_name": "MyOrganization or Description",
|
20
|
+
# "city_name": "Leuven",
|
21
|
+
# "country_name": "Belgium",
|
22
|
+
# "country_code2": "BE",
|
23
|
+
# "country_code3": "BEL",
|
24
|
+
# "continent_code": "Europe/Brussels"
|
25
|
+
# }
|
26
|
+
# }
|
27
|
+
#]
|
28
|
+
config :database, validate: :string, required: true
|
29
|
+
|
30
|
+
#contains the target object. it is by default private_geoip but you could change it to geoip
|
31
|
+
config :target, validate: :string, default: "private_geoip"
|
32
|
+
|
33
|
+
#if a geoip object exists on the event should it be merged and thus overwritten
|
34
|
+
config :merge, validate: :boolean, default: true
|
35
|
+
|
36
|
+
public
|
37
|
+
def register
|
38
|
+
require 'ip'
|
39
|
+
require 'json'
|
40
|
+
|
41
|
+
@cidrs = {}
|
42
|
+
JSON.parse(File.read(@database)).each do |entry|
|
43
|
+
@cidrs.store(IP::CIDR.new(entry['cidr']), entry['data'])
|
44
|
+
end
|
45
|
+
|
46
|
+
rescue Exception => e
|
47
|
+
raise "Error registering filter: #{e.message}"
|
48
|
+
end
|
49
|
+
|
50
|
+
public
|
51
|
+
def filter(event)
|
52
|
+
ip = IP::Address::Util.string_to_ip(event[@source])
|
53
|
+
|
54
|
+
matched_cidr_data = {}
|
55
|
+
|
56
|
+
@cidrs.each do |cidr, data|
|
57
|
+
if cidr.includes?(ip)
|
58
|
+
matched_cidr_data = data
|
59
|
+
break
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
return if matched_cidr_data.nil? || matched_cidr_data.empty?
|
64
|
+
|
65
|
+
geo_data = event[@target].nil? ? {} : event[@target]
|
66
|
+
|
67
|
+
if @merge
|
68
|
+
geo_data.merge!(matched_cidr_data)
|
69
|
+
geo_data['ip'] = event[@source]
|
70
|
+
else
|
71
|
+
add_keys = matched_cidr_data.keys - geo_data.keys
|
72
|
+
geo_data.merge!(matched_cidr_data.select{|k,v| add_keys.include?(k)})
|
73
|
+
end
|
74
|
+
|
75
|
+
event[@target] = geo_data
|
76
|
+
|
77
|
+
filter_matched(event)
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
|
3
|
+
s.name = 'logstash-filter-private_geoip'
|
4
|
+
s.version = '1.0.0'
|
5
|
+
s.licenses = ['Apache License (2.0)']
|
6
|
+
s.summary = "$summary"
|
7
|
+
s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
|
8
|
+
s.authors = ["Mehmet Celik"]
|
9
|
+
s.email = 'mehmet.celik@kuleuven.libis.be'
|
10
|
+
s.homepage = "http://www.elastic.co/guide/en/logstash/current/index.html"
|
11
|
+
s.require_paths = ["lib"]
|
12
|
+
|
13
|
+
# Files
|
14
|
+
s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
|
15
|
+
|
16
|
+
# Tests
|
17
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
18
|
+
|
19
|
+
# Special flag to let us know this is actually a logstash plugin
|
20
|
+
s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }
|
21
|
+
|
22
|
+
# Gem dependencies
|
23
|
+
s.add_runtime_dependency "logstash-core", '>= 1.4.0', '< 2.0.0'
|
24
|
+
#s.add_runtime_dependency "logstash-core", ">= 2.0.0.beta2", "< 3.0.0"
|
25
|
+
s.add_runtime_dependency 'ip', "0.3.1"
|
26
|
+
|
27
|
+
|
28
|
+
s.add_development_dependency 'logstash-devutils', '~> 0'
|
29
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require "logstash/devutils/rspec/spec_helper"
|
2
|
+
require "logstash/filters/private_geoip"
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
DATABASE = "spec/resources/cidr.json"
|
6
|
+
|
7
|
+
describe LogStash::Filters::PrivateGeoIP do
|
8
|
+
describe "does find match" do
|
9
|
+
config <<-CONFIG
|
10
|
+
filter {
|
11
|
+
private_geoip {
|
12
|
+
source => "ip"
|
13
|
+
database => "#{DATABASE}"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
CONFIG
|
17
|
+
|
18
|
+
sample("ip" => "10.33.108.120") do
|
19
|
+
insist {subject}.include?("private_geoip")
|
20
|
+
insist {subject["private_geoip"]["organization_name"]}.eql?("centrale bibliotheek")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "does not find match" do
|
25
|
+
config <<-CONFIG
|
26
|
+
filter {
|
27
|
+
private_geoip {
|
28
|
+
source => "ip"
|
29
|
+
database => "#{DATABASE}"
|
30
|
+
}
|
31
|
+
}
|
32
|
+
CONFIG
|
33
|
+
|
34
|
+
sample("ip" => "10.33.101.120") do
|
35
|
+
reject {subject}.include?("private_geoip")
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "target = geoip instead of private_geoip" do
|
41
|
+
config <<-CONFIG
|
42
|
+
filter {
|
43
|
+
private_geoip {
|
44
|
+
source => "ip"
|
45
|
+
database => "#{DATABASE}"
|
46
|
+
target => "geoip"
|
47
|
+
}
|
48
|
+
}
|
49
|
+
CONFIG
|
50
|
+
|
51
|
+
|
52
|
+
sample("ip" => "10.33.108.120") do
|
53
|
+
insist {subject}.include?("geoip")
|
54
|
+
reject {subject}.include?("private_geoip")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "do merge with overwrite" do
|
59
|
+
config <<-CONFIG
|
60
|
+
filter {
|
61
|
+
private_geoip {
|
62
|
+
source => "client_ip"
|
63
|
+
database => "#{DATABASE}"
|
64
|
+
target => "geoip"
|
65
|
+
}
|
66
|
+
}
|
67
|
+
CONFIG
|
68
|
+
|
69
|
+
sample_data = {
|
70
|
+
"client_ip" => "10.33.108.120",
|
71
|
+
"geoip" => {
|
72
|
+
"ip" => "134.58.179.35",
|
73
|
+
"country_code2" => "BE",
|
74
|
+
"country_code3" => "BEL",
|
75
|
+
"country_name" => "Belgium",
|
76
|
+
"continent_code" => "EU",
|
77
|
+
"region_name" => "12",
|
78
|
+
"city_name" => "Leuven",
|
79
|
+
"postal_code" => "3000",
|
80
|
+
"latitude" => 50.88329999999999,
|
81
|
+
"longitude" => 4.699999999999989,
|
82
|
+
"timezone" => "Europe/Brussels",
|
83
|
+
"real_region_name" => "Vlaams-Brabant",
|
84
|
+
"location" => [
|
85
|
+
4.699999999999989,
|
86
|
+
50.88329999999999
|
87
|
+
]
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
|
92
|
+
sample(sample_data) do
|
93
|
+
#insist {subject}.include?("geoip")
|
94
|
+
insist {subject["geoip"]["city_name"]} == "KULASSOC"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "do merge NO overwrite" do
|
99
|
+
config <<-CONFIG
|
100
|
+
filter {
|
101
|
+
private_geoip {
|
102
|
+
source => "client_ip"
|
103
|
+
database => "#{DATABASE}"
|
104
|
+
target => "geoip"
|
105
|
+
merge => false
|
106
|
+
}
|
107
|
+
}
|
108
|
+
CONFIG
|
109
|
+
|
110
|
+
sample_data = {
|
111
|
+
"client_ip" => "10.33.108.120",
|
112
|
+
"geoip" => {
|
113
|
+
"ip" => "134.58.179.35",
|
114
|
+
"country_code2" => "BE",
|
115
|
+
"country_code3" => "BEL",
|
116
|
+
"country_name" => "Belgium",
|
117
|
+
"continent_code" => "EU",
|
118
|
+
"region_name" => "12",
|
119
|
+
"city_name" => "Leuven",
|
120
|
+
"postal_code" => "3000",
|
121
|
+
"latitude" => 50.88329999999999,
|
122
|
+
"longitude" => 4.699999999999989,
|
123
|
+
"timezone" => "Europe/Brussels",
|
124
|
+
"real_region_name" => "Vlaams-Brabant",
|
125
|
+
"location" => [
|
126
|
+
4.699999999999989,
|
127
|
+
50.88329999999999
|
128
|
+
]
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
sample(sample_data) do
|
133
|
+
insist {subject}.include?("geoip")
|
134
|
+
reject {subject}.include?("private_geoip")
|
135
|
+
insist {subject["geoip"]["city_name"]} == "Leuven"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
[
|
2
|
+
{"cidr":"10.33.104.0/22","data":{"organization_name":"Faculteit Landbouw","city_name":"KULASSOC","country_name":"Belgium","country_code2":"BE","country_code3":"BEL","continent_code":"Europe/Brussels"}},
|
3
|
+
{"cidr":"10.33.108.0/24","data":{"organization_name":"Centrale Bibliotheek","city_name":"KULASSOC","country_name":"Belgium","country_code2":"BE","country_code3":"BEL","continent_code":"Europe/Brussels"}},
|
4
|
+
{"cidr":"10.33.109.0/24","data":{"organization_name":"Burgerlijke Bouwkunde","city_name":"KULASSOC","country_name":"Belgium","country_code2":"BE","country_code3":"BEL","continent_code":"Europe/Brussels"}}
|
5
|
+
]
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: logstash-filter-private_geoip
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mehmet Celik
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - '>='
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: 1.4.0
|
19
|
+
- - <
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.0.0
|
22
|
+
name: logstash-core
|
23
|
+
prerelease: false
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.4.0
|
30
|
+
- - <
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.0.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - '='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 0.3.1
|
39
|
+
name: ip
|
40
|
+
prerelease: false
|
41
|
+
type: :runtime
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - '='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.3.1
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ~>
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
name: logstash-devutils
|
54
|
+
prerelease: false
|
55
|
+
type: :development
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
|
62
|
+
email: mehmet.celik@kuleuven.libis.be
|
63
|
+
executables: []
|
64
|
+
extensions: []
|
65
|
+
extra_rdoc_files: []
|
66
|
+
files:
|
67
|
+
- Gemfile
|
68
|
+
- LICENSE
|
69
|
+
- README.md
|
70
|
+
- lib/logstash/filters/private_geoip.rb
|
71
|
+
- logstash-filter-private_geoip.gemspec
|
72
|
+
- spec/filters/private_geoip_spec.rb
|
73
|
+
- spec/resources/cidr.json
|
74
|
+
homepage: http://www.elastic.co/guide/en/logstash/current/index.html
|
75
|
+
licenses:
|
76
|
+
- Apache License (2.0)
|
77
|
+
metadata:
|
78
|
+
logstash_plugin: 'true'
|
79
|
+
logstash_group: filter
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.4.8
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: $summary
|
100
|
+
test_files:
|
101
|
+
- spec/filters/private_geoip_spec.rb
|
102
|
+
- spec/resources/cidr.json
|