logstash-filter-dns 3.0.1 → 3.0.3
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 +10 -1
- data/CONTRIBUTORS +1 -0
- data/lib/logstash/filters/dns.rb +29 -8
- data/logstash-filter-dns.gemspec +2 -3
- data/spec/filters/dns_spec.rb +294 -259
- data/spec/fixtures/hosts +2 -0
- metadata +15 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71ea1ae4db2be0cfc2ef5e4c7e109d8ab52ea66e
|
4
|
+
data.tar.gz: 9da02b4bd4f919e0a08ba2df3d85a5baf871023e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c6d9c9f130680c2c08d5c42f28e313c28fa9da74e4bb7b4e54367a11bf8c25b6c2199d487af71911180e61cb8e627cffd59740e941f4949e2f659c8ea5c9061
|
7
|
+
data.tar.gz: e4be62edea5cc7d006a7aae79d7c2ef02fbc974e0522dd4a92974acd47444570ce28da677d760a978000bb45c572c7f4edf5b5e8644e74fb1297281609b4a977
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,16 @@
|
|
1
|
+
## 3.0.3
|
2
|
+
- Relax constraint on logstash-core-plugin-api to >= 1.60 <= 2.99
|
3
|
+
|
4
|
+
## 3.0.2
|
5
|
+
- Add support for International Domain Names e.g. müller.com. Fixes https://github.com/logstash-plugins/logstash-filter-dns/issues/22
|
6
|
+
- Add support for custom hosts files (helps with testing but could be useful to some folks).
|
7
|
+
|
1
8
|
## 3.0.1
|
2
9
|
- Republish all the gems under jruby.
|
10
|
+
|
3
11
|
## 3.0.0
|
4
12
|
- Update the plugin to the version 2.0 of the plugin api, this change is required for Logstash 5.0 compatibility. See https://github.com/elastic/logstash/issues/5141
|
13
|
+
|
5
14
|
## 2.1.3
|
6
15
|
- Fix spec early termination by removing an explicit return from a block
|
7
16
|
|
@@ -17,7 +26,7 @@
|
|
17
26
|
- Retry a maximum of :max_retries instead of failing immediately
|
18
27
|
|
19
28
|
## 2.0.0
|
20
|
-
- Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
|
29
|
+
- Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
|
21
30
|
instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
|
22
31
|
- Dependency on logstash-core update to 2.0
|
23
32
|
|
data/CONTRIBUTORS
CHANGED
@@ -16,6 +16,7 @@ Contributors:
|
|
16
16
|
* Richard Pijnenburg (electrical)
|
17
17
|
* Suyog Rao (suyograo)
|
18
18
|
* hal-awesome
|
19
|
+
* Guy Boertje (guyboertje)
|
19
20
|
|
20
21
|
Note: If you've sent us patches, bug reports, or otherwise contributed to
|
21
22
|
Logstash, and you aren't on the list above and want to be, please let us know
|
data/lib/logstash/filters/dns.rb
CHANGED
@@ -2,17 +2,20 @@
|
|
2
2
|
require "logstash/filters/base"
|
3
3
|
require "logstash/namespace"
|
4
4
|
require "lru_redux"
|
5
|
+
require "resolv"
|
6
|
+
require "timeout"
|
7
|
+
|
8
|
+
java_import 'java.net.IDN'
|
5
9
|
|
6
10
|
|
7
11
|
# The DNS filter performs a lookup (either an A record/CNAME record lookup
|
8
12
|
# or a reverse lookup at the PTR record) on records specified under the
|
9
|
-
# `reverse`
|
13
|
+
# `reverse` arrays or respectively under the `resolve` arrays.
|
10
14
|
#
|
11
15
|
# The config should look like this:
|
12
16
|
# [source,ruby]
|
13
17
|
# filter {
|
14
18
|
# dns {
|
15
|
-
# type => 'type'
|
16
19
|
# reverse => [ "source_host", "field_with_address" ]
|
17
20
|
# resolve => [ "field_with_fqdn" ]
|
18
21
|
# action => "replace"
|
@@ -63,14 +66,15 @@ class LogStash::Filters::DNS < LogStash::Filters::Base
|
|
63
66
|
# how long to cache failed requests (in seconds)
|
64
67
|
config :failed_cache_ttl, :validate => :number, :default => 5
|
65
68
|
|
69
|
+
# Use custom hosts file(s). For example: `["/var/db/my_custom_hosts"]`
|
70
|
+
config :hostsfile, :validate => :array
|
71
|
+
|
66
72
|
public
|
67
73
|
def register
|
68
|
-
|
69
|
-
require "timeout"
|
70
|
-
if @nameserver.nil?
|
74
|
+
if @nameserver.nil? && @hostsfile.nil?
|
71
75
|
@resolv = Resolv.new
|
72
76
|
else
|
73
|
-
@resolv = Resolv.new(
|
77
|
+
@resolv = Resolv.new(build_resolvers)
|
74
78
|
end
|
75
79
|
|
76
80
|
if @hit_cache_size > 0
|
@@ -99,6 +103,21 @@ class LogStash::Filters::DNS < LogStash::Filters::Base
|
|
99
103
|
end
|
100
104
|
|
101
105
|
private
|
106
|
+
|
107
|
+
def build_resolvers
|
108
|
+
build_user_host_resolvers.concat([::Resolv::Hosts.new]).concat(build_user_dns_resolver)
|
109
|
+
end
|
110
|
+
|
111
|
+
def build_user_host_resolvers
|
112
|
+
return [] if @hostsfile.nil? || @hostsfile.empty?
|
113
|
+
@hostsfile.map{|fn| ::Resolv::Hosts.new(fn)}
|
114
|
+
end
|
115
|
+
|
116
|
+
def build_user_dns_resolver
|
117
|
+
return [] if @nameserver.nil? || @nameserver.empty?
|
118
|
+
[::Resolv::DNS.new(:nameserver => @nameserver, :search => [], :ndots => 1)]
|
119
|
+
end
|
120
|
+
|
102
121
|
def resolve(event)
|
103
122
|
@resolve.each do |field|
|
104
123
|
is_array = false
|
@@ -245,11 +264,13 @@ class LogStash::Filters::DNS < LogStash::Filters::Base
|
|
245
264
|
|
246
265
|
private
|
247
266
|
def getname(address)
|
248
|
-
@resolv.getname(address).force_encoding(Encoding::UTF_8)
|
267
|
+
name = @resolv.getname(address).force_encoding(Encoding::UTF_8)
|
268
|
+
IDN.toUnicode(name)
|
249
269
|
end
|
250
270
|
|
251
271
|
private
|
252
272
|
def getaddress(name)
|
253
|
-
|
273
|
+
idn = IDN.toASCII(name)
|
274
|
+
@resolv.getaddress(idn).force_encoding(Encoding::UTF_8)
|
254
275
|
end
|
255
276
|
end # class LogStash::Filters::DNS
|
data/logstash-filter-dns.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-filter-dns'
|
4
|
-
s.version = '3.0.
|
4
|
+
s.version = '3.0.3'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "This filter will resolve any IP addresses from a field of your choosing."
|
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"
|
@@ -20,9 +20,8 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }
|
21
21
|
|
22
22
|
# Gem dependencies
|
23
|
-
s.add_runtime_dependency "logstash-core-plugin-api", "
|
23
|
+
s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
|
24
24
|
s.add_runtime_dependency 'lru_redux', "~> 1.1.0"
|
25
25
|
|
26
26
|
s.add_development_dependency 'logstash-devutils'
|
27
27
|
end
|
28
|
-
|
data/spec/filters/dns_spec.rb
CHANGED
@@ -4,357 +4,392 @@ require "logstash/filters/dns"
|
|
4
4
|
require "resolv"
|
5
5
|
|
6
6
|
describe LogStash::Filters::DNS do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
describe "with stubbed Resolv" do
|
8
|
+
before(:each) do
|
9
|
+
allow_any_instance_of(Resolv).to receive(:getaddress).with("carrera.databits.net").and_return("199.192.228.250")
|
10
|
+
allow_any_instance_of(Resolv).to receive(:getaddress).with("does.not.exist").and_raise(Resolv::ResolvError)
|
11
|
+
allow_any_instance_of(Resolv).to receive(:getaddress).with("nonexistanthostname###.net").and_raise(Resolv::ResolvError)
|
12
|
+
allow_any_instance_of(Resolv).to receive(:getname).with("199.192.228.250").and_return("carrera.databits.net")
|
13
|
+
allow_any_instance_of(Resolv).to receive(:getname).with("127.0.0.1").and_return("localhost")
|
14
|
+
allow_any_instance_of(Resolv).to receive(:getname).with("128.0.0.1").and_raise(Resolv::ResolvError)
|
15
|
+
allow_any_instance_of(Resolv).to receive(:getname).with("199.192.228.250").and_return("carrera.databits.net")
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
describe "dns reverse lookup, replace (on a field)" do
|
19
|
+
config <<-CONFIG
|
20
|
+
filter {
|
21
|
+
dns {
|
22
|
+
reverse => "foo"
|
23
|
+
action => "replace"
|
24
|
+
}
|
23
25
|
}
|
24
|
-
|
25
|
-
CONFIG
|
26
|
+
CONFIG
|
26
27
|
|
27
|
-
|
28
|
-
|
28
|
+
sample("foo" => "199.192.228.250") do
|
29
|
+
insist { subject.get("foo") } == "carrera.databits.net"
|
30
|
+
end
|
29
31
|
end
|
30
|
-
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
describe "dns reverse lookup, append" do
|
34
|
+
config <<-CONFIG
|
35
|
+
filter {
|
36
|
+
dns {
|
37
|
+
reverse => "foo"
|
38
|
+
action => "append"
|
39
|
+
}
|
38
40
|
}
|
39
|
-
|
40
|
-
CONFIG
|
41
|
+
CONFIG
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
sample("foo" => "199.192.228.250") do
|
44
|
+
insist { subject.get("foo")[0] } == "199.192.228.250"
|
45
|
+
insist { subject.get("foo")[1] } == "carrera.databits.net"
|
46
|
+
end
|
45
47
|
end
|
46
|
-
end
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
49
|
+
describe "dns reverse lookup, not an IP" do
|
50
|
+
config <<-CONFIG
|
51
|
+
filter {
|
52
|
+
dns {
|
53
|
+
reverse => "foo"
|
54
|
+
}
|
53
55
|
}
|
54
|
-
|
55
|
-
CONFIG
|
56
|
+
CONFIG
|
56
57
|
|
57
|
-
|
58
|
-
|
58
|
+
sample("foo" => "not.an.ip") do
|
59
|
+
insist { subject.get("foo") } == "not.an.ip"
|
60
|
+
end
|
59
61
|
end
|
60
|
-
end
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
63
|
+
describe "dns resolve lookup, replace" do
|
64
|
+
config <<-CONFIG
|
65
|
+
filter {
|
66
|
+
dns {
|
67
|
+
resolve => ["host"]
|
68
|
+
action => "replace"
|
69
|
+
add_tag => ["success"]
|
70
|
+
}
|
69
71
|
}
|
70
|
-
|
71
|
-
CONFIG
|
72
|
+
CONFIG
|
72
73
|
|
73
|
-
|
74
|
-
|
75
|
-
|
74
|
+
sample("host" => "carrera.databits.net") do
|
75
|
+
insist { subject.get("host") } == "199.192.228.250"
|
76
|
+
insist { subject.get("tags") } == ["success"]
|
77
|
+
end
|
76
78
|
end
|
77
|
-
end
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
80
|
+
describe "dns fail resolve lookup, don't add tag" do
|
81
|
+
config <<-CONFIG
|
82
|
+
filter {
|
83
|
+
dns {
|
84
|
+
resolve => ["host1", "host2"]
|
85
|
+
action => "replace"
|
86
|
+
add_tag => ["success"]
|
87
|
+
}
|
86
88
|
}
|
87
|
-
|
88
|
-
CONFIG
|
89
|
+
CONFIG
|
89
90
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
91
|
+
sample("host1" => "carrera.databits.net", "host2" => "nonexistanthostname###.net") do
|
92
|
+
insist { subject.get("tags") }.nil?
|
93
|
+
insist { subject.get("host1") } == "199.192.228.250"
|
94
|
+
insist { subject.get("host2") } == "nonexistanthostname###.net"
|
95
|
+
end
|
94
96
|
end
|
95
|
-
end
|
96
97
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
98
|
+
describe "dns resolves lookups, adds tag" do
|
99
|
+
config <<-CONFIG
|
100
|
+
filter {
|
101
|
+
dns {
|
102
|
+
resolve => ["host1", "host2"]
|
103
|
+
action => "replace"
|
104
|
+
add_tag => ["success"]
|
105
|
+
}
|
104
106
|
}
|
105
|
-
|
106
|
-
CONFIG
|
107
|
+
CONFIG
|
107
108
|
|
108
|
-
|
109
|
-
|
109
|
+
sample("host1" => "carrera.databits.net", "host2" => "carrera.databits.net") do
|
110
|
+
insist { subject.get("tags") } == ["success"]
|
111
|
+
end
|
110
112
|
end
|
111
|
-
end
|
112
113
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
114
|
+
describe "dns resolves and reverses, fails last, no tag" do
|
115
|
+
config <<-CONFIG
|
116
|
+
filter {
|
117
|
+
dns {
|
118
|
+
resolve => ["host1"]
|
119
|
+
reverse => ["ip1", "ip2"]
|
120
|
+
action => "replace"
|
121
|
+
add_tag => ["success"]
|
122
|
+
}
|
121
123
|
}
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
124
|
+
CONFIG
|
125
|
+
|
126
|
+
sample("host1" => "carrera.databits.net",
|
127
|
+
"ip1" => "127.0.0.1",
|
128
|
+
"ip2" => "128.0.0.1") do
|
129
|
+
insist { subject.get("tags") }.nil?
|
130
|
+
insist { subject.get("host1") } == "199.192.228.250"
|
131
|
+
insist { subject.get("ip1") } == "localhost"
|
132
|
+
insist { subject.get("ip2") } == "128.0.0.1"
|
133
|
+
end
|
132
134
|
end
|
133
|
-
end
|
134
135
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
136
|
+
describe "dns resolve lookup, replace (on a field)" do
|
137
|
+
config <<-CONFIG
|
138
|
+
filter {
|
139
|
+
dns {
|
140
|
+
resolve => "foo"
|
141
|
+
action => "replace"
|
142
|
+
}
|
141
143
|
}
|
142
|
-
|
143
|
-
CONFIG
|
144
|
+
CONFIG
|
144
145
|
|
145
|
-
|
146
|
-
|
146
|
+
sample("foo" => "carrera.databits.net") do
|
147
|
+
insist { subject.get("foo") } == "199.192.228.250"
|
148
|
+
end
|
147
149
|
end
|
148
|
-
end
|
149
150
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
151
|
+
describe "dns resolve lookup, skip multi-value" do
|
152
|
+
config <<-CONFIG
|
153
|
+
filter {
|
154
|
+
dns {
|
155
|
+
resolve => "foo"
|
156
|
+
action => "replace"
|
157
|
+
}
|
156
158
|
}
|
157
|
-
|
158
|
-
CONFIG
|
159
|
+
CONFIG
|
159
160
|
|
160
|
-
|
161
|
-
|
161
|
+
sample("foo" => ["carrera.databits.net", "foo.databits.net"]) do
|
162
|
+
insist { subject.get("foo") } == ["carrera.databits.net", "foo.databits.net"]
|
163
|
+
end
|
162
164
|
end
|
163
|
-
end
|
164
165
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
166
|
+
describe "dns resolve lookup, append" do
|
167
|
+
config <<-CONFIG
|
168
|
+
filter {
|
169
|
+
dns {
|
170
|
+
resolve => "foo"
|
171
|
+
action => "append"
|
172
|
+
}
|
171
173
|
}
|
172
|
-
|
173
|
-
CONFIG
|
174
|
+
CONFIG
|
174
175
|
|
175
|
-
|
176
|
-
|
177
|
-
|
176
|
+
sample("foo" => "carrera.databits.net") do
|
177
|
+
insist { subject.get("foo")[0] } == "carrera.databits.net"
|
178
|
+
insist { subject.get("foo")[1] } == "199.192.228.250"
|
179
|
+
end
|
178
180
|
end
|
179
|
-
end
|
180
181
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
182
|
+
describe "dns resolve lookup, append with multi-value does nothing" do
|
183
|
+
config <<-CONFIG
|
184
|
+
filter {
|
185
|
+
dns {
|
186
|
+
resolve => "foo"
|
187
|
+
action => "append"
|
188
|
+
}
|
187
189
|
}
|
188
|
-
|
189
|
-
CONFIG
|
190
|
+
CONFIG
|
190
191
|
|
191
|
-
|
192
|
-
|
192
|
+
sample("foo" => ["carrera.databits.net", "foo.databits.net"]) do
|
193
|
+
insist { subject.get("foo") } == ["carrera.databits.net", "foo.databits.net"]
|
194
|
+
end
|
193
195
|
end
|
194
|
-
end
|
195
196
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
197
|
+
describe "dns resolve lookup, not a valid hostname" do
|
198
|
+
config <<-CONFIG
|
199
|
+
filter {
|
200
|
+
dns {
|
201
|
+
resolve=> "foo"
|
202
|
+
}
|
201
203
|
}
|
202
|
-
|
203
|
-
CONFIG
|
204
|
+
CONFIG
|
204
205
|
|
205
|
-
|
206
|
-
|
206
|
+
sample("foo" => "does.not.exist") do
|
207
|
+
insist { subject.get("foo") } == "does.not.exist"
|
208
|
+
end
|
207
209
|
end
|
208
|
-
end
|
209
210
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
211
|
+
describe "dns resolve lookup, single custom nameserver" do
|
212
|
+
config <<-CONFIG
|
213
|
+
filter {
|
214
|
+
dns {
|
215
|
+
resolve => ["host"]
|
216
|
+
action => "replace"
|
217
|
+
nameserver => "8.8.8.8"
|
218
|
+
}
|
217
219
|
}
|
218
|
-
|
219
|
-
CONFIG
|
220
|
+
CONFIG
|
220
221
|
|
221
|
-
|
222
|
-
|
222
|
+
sample("host" => "carrera.databits.net") do
|
223
|
+
insist { subject.get("host") } == "199.192.228.250"
|
224
|
+
end
|
223
225
|
end
|
224
|
-
end
|
225
226
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
227
|
+
describe "dns resolve lookup, multiple nameserver fallback" do
|
228
|
+
config <<-CONFIG
|
229
|
+
filter {
|
230
|
+
dns {
|
231
|
+
resolve => ["host"]
|
232
|
+
action => "replace"
|
233
|
+
nameserver => ["127.0.0.99", "8.8.8.8"]
|
234
|
+
}
|
233
235
|
}
|
234
|
-
|
235
|
-
CONFIG
|
236
|
+
CONFIG
|
236
237
|
|
237
|
-
|
238
|
-
|
238
|
+
sample("host" => "carrera.databits.net") do
|
239
|
+
insist { subject.get("host") } == "199.192.228.250"
|
240
|
+
end
|
239
241
|
end
|
240
|
-
end
|
241
242
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
243
|
+
describe "dns resolve lookup, multiple nameserver fallback" do
|
244
|
+
config <<-CONFIG
|
245
|
+
filter {
|
246
|
+
dns {
|
247
|
+
resolve => ["host"]
|
248
|
+
action => "replace"
|
249
|
+
nameserver => ["127.0.0.99", "8.8.8.8"]
|
250
|
+
}
|
249
251
|
}
|
250
|
-
|
251
|
-
CONFIG
|
252
|
+
CONFIG
|
252
253
|
|
253
|
-
|
254
|
-
|
254
|
+
sample("host" => "carrera.databits.net") do
|
255
|
+
insist { subject.get("host") } == "199.192.228.250"
|
256
|
+
end
|
255
257
|
end
|
256
|
-
end
|
257
258
|
|
258
|
-
|
259
|
+
describe "failed cache" do
|
259
260
|
|
260
|
-
|
261
|
-
|
262
|
-
|
261
|
+
let(:subject) { LogStash::Filters::DNS.new(config) }
|
262
|
+
let(:event1) { LogStash::Event.new("message" => "unkownhost") }
|
263
|
+
let(:event2) { LogStash::Event.new("message" => "unkownhost") }
|
263
264
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
265
|
+
before(:each) do
|
266
|
+
allow(subject).to receive(:getaddress).and_raise Resolv::ResolvError
|
267
|
+
subject.register
|
268
|
+
end
|
268
269
|
|
269
|
-
|
270
|
-
|
270
|
+
context "when enabled" do
|
271
|
+
let(:config) { { "resolve" => ["message"], "failed_cache_size" => 3 } }
|
271
272
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
273
|
+
it "should cache a failed lookup" do
|
274
|
+
expect(subject).to receive(:getaddress).once
|
275
|
+
subject.filter(event1)
|
276
|
+
subject.filter(event2)
|
277
|
+
end
|
276
278
|
end
|
277
|
-
end
|
278
279
|
|
279
|
-
|
280
|
-
|
280
|
+
context "when disabled" do
|
281
|
+
let(:config) { { "resolve" => ["message"] } }
|
281
282
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
283
|
+
it "should not cache a failed lookup" do
|
284
|
+
expect(subject).to receive(:getaddress).twice
|
285
|
+
subject.filter(event1)
|
286
|
+
subject.filter(event2)
|
287
|
+
end
|
286
288
|
end
|
287
289
|
end
|
288
|
-
end
|
289
290
|
|
290
|
-
|
291
|
+
describe "hit cache" do
|
291
292
|
|
292
|
-
|
293
|
-
|
294
|
-
|
293
|
+
let(:subject) { LogStash::Filters::DNS.new(config) }
|
294
|
+
let(:event1) { LogStash::Event.new("message" => "unkownhost") }
|
295
|
+
let(:event2) { LogStash::Event.new("message" => "unkownhost") }
|
295
296
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
297
|
+
before(:each) do
|
298
|
+
allow(subject).to receive(:getaddress).and_return("127.0.0.1")
|
299
|
+
subject.register
|
300
|
+
end
|
300
301
|
|
301
|
-
|
302
|
-
|
302
|
+
context "when enabled" do
|
303
|
+
let(:config) { { "resolve" => ["message"], "hit_cache_size" => 3 } }
|
303
304
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
305
|
+
it "should cache a succesful lookup" do
|
306
|
+
expect(subject).to receive(:getaddress).once
|
307
|
+
subject.filter(event1)
|
308
|
+
subject.filter(event2)
|
309
|
+
end
|
308
310
|
end
|
309
|
-
end
|
310
311
|
|
311
|
-
|
312
|
-
|
312
|
+
context "when disabled" do
|
313
|
+
let(:config) { { "resolve" => ["message"] } }
|
313
314
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
315
|
+
it "should not cache a successful lookup" do
|
316
|
+
expect(subject).to receive(:getaddress).twice
|
317
|
+
subject.filter(event1)
|
318
|
+
subject.filter(event2)
|
319
|
+
end
|
318
320
|
end
|
319
321
|
end
|
320
|
-
end
|
321
322
|
|
322
|
-
|
323
|
+
describe "retries" do
|
323
324
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
325
|
+
let(:subject) { LogStash::Filters::DNS.new(config) }
|
326
|
+
let(:event) { LogStash::Event.new("message" => "unkownhost") }
|
327
|
+
let(:max_retries) { 3 }
|
328
|
+
let(:config) { { "resolve" => ["message"], "max_retries" => max_retries } }
|
328
329
|
|
329
|
-
|
330
|
+
before(:each) { subject.register }
|
330
331
|
|
331
|
-
|
332
|
-
|
333
|
-
|
332
|
+
context "when failing permanently" do
|
333
|
+
before(:each) do
|
334
|
+
allow(subject).to receive(:getaddress).and_raise(Timeout::Error)
|
335
|
+
end
|
336
|
+
|
337
|
+
it "should fail a resolve after max_retries" do
|
338
|
+
expect(subject).to receive(:getaddress).exactly(max_retries+1).times
|
339
|
+
subject.filter(event)
|
340
|
+
end
|
334
341
|
end
|
335
342
|
|
336
|
-
|
337
|
-
|
338
|
-
|
343
|
+
context "when failing temporarily" do
|
344
|
+
before(:each) do
|
345
|
+
allow(subject).to receive(:getaddress) do
|
346
|
+
@try ||= 0
|
347
|
+
if @try < 2
|
348
|
+
@try = @try + 1
|
349
|
+
raise Timeout::Error
|
350
|
+
else
|
351
|
+
"127.0.0.1"
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
it "should resolve before max_retries" do
|
357
|
+
expect(subject).to receive(:getaddress).exactly(3).times
|
358
|
+
subject.filter(event)
|
359
|
+
end
|
339
360
|
end
|
340
361
|
end
|
362
|
+
end
|
363
|
+
|
364
|
+
describe "with nameserver integration" do
|
365
|
+
describe "lookup using fixture hosts file" do
|
366
|
+
let(:subject) { LogStash::Filters::DNS.new(config) }
|
367
|
+
let(:hostsfile) { File.join(File.dirname(__FILE__), "..", "fixtures", "hosts") }
|
368
|
+
# From the custom hosts file
|
369
|
+
# 10.10.0.1 xn--d1acpjx3f.xn--p1ai # -> Яндекс.рф
|
370
|
+
# 10.10.0.2 xn--mller-kva.com # -> müller.com
|
341
371
|
|
342
|
-
context "when failing temporarily" do
|
343
372
|
before(:each) do
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
373
|
+
subject.register
|
374
|
+
subject.filter(event)
|
375
|
+
end
|
376
|
+
|
377
|
+
context "when domain is an IDN" do
|
378
|
+
let(:config) { { "resolve" => ["domain"], "action" => "replace", "hostsfile" => [hostsfile]} }
|
379
|
+
let(:event) { LogStash::Event.new("domain" => "Яндекс.рф") }
|
380
|
+
|
381
|
+
it "should return the IP" do
|
382
|
+
expect(event.get("domain")).to eq("10.10.0.1")
|
352
383
|
end
|
353
384
|
end
|
354
385
|
|
355
|
-
|
356
|
-
|
357
|
-
|
386
|
+
context "when IP points to an IDN" do
|
387
|
+
let(:config) { { "reverse" => ["domain"], "action" => "replace", "hostsfile" => [hostsfile]} }
|
388
|
+
let(:event) { LogStash::Event.new("domain" => "10.10.0.2") }
|
389
|
+
|
390
|
+
it "should return the IDN" do
|
391
|
+
expect(event.get("domain")).to eq("müller.com")
|
392
|
+
end
|
358
393
|
end
|
359
394
|
end
|
360
395
|
end
|
data/spec/fixtures/hosts
ADDED
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-filter-dns
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
|
-
- - "
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '1.60'
|
19
|
+
- - "<="
|
17
20
|
- !ruby/object:Gem::Version
|
18
|
-
version: '2.
|
21
|
+
version: '2.99'
|
19
22
|
name: logstash-core-plugin-api
|
20
23
|
prerelease: false
|
21
24
|
type: :runtime
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.60'
|
30
|
+
- - "<="
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version: '2.
|
32
|
+
version: '2.99'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
requirement: !ruby/object:Gem::Requirement
|
29
35
|
requirements:
|
@@ -67,6 +73,7 @@ files:
|
|
67
73
|
- lib/logstash/filters/dns.rb
|
68
74
|
- logstash-filter-dns.gemspec
|
69
75
|
- spec/filters/dns_spec.rb
|
76
|
+
- spec/fixtures/hosts
|
70
77
|
homepage: http://www.elastic.co/guide/en/logstash/current/index.html
|
71
78
|
licenses:
|
72
79
|
- Apache License (2.0)
|
@@ -89,9 +96,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
96
|
version: '0'
|
90
97
|
requirements: []
|
91
98
|
rubyforge_project:
|
92
|
-
rubygems_version: 2.
|
99
|
+
rubygems_version: 2.6.3
|
93
100
|
signing_key:
|
94
101
|
specification_version: 4
|
95
102
|
summary: This filter will resolve any IP addresses from a field of your choosing.
|
96
103
|
test_files:
|
97
104
|
- spec/filters/dns_spec.rb
|
105
|
+
- spec/fixtures/hosts
|