logstash-patterns-core 4.0.2 → 4.3.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 +5 -5
- data/CHANGELOG.md +149 -8
- data/CONTRIBUTORS +1 -0
- data/Gemfile +11 -1
- data/LICENSE +199 -10
- data/README.md +12 -19
- data/lib/logstash/patterns/core.rb +11 -3
- data/logstash-patterns-core.gemspec +1 -1
- data/patterns/ecs-v1/aws +28 -0
- data/patterns/ecs-v1/bacula +53 -0
- data/patterns/ecs-v1/bind +13 -0
- data/patterns/ecs-v1/bro +30 -0
- data/patterns/ecs-v1/exim +26 -0
- data/patterns/ecs-v1/firewalls +111 -0
- data/patterns/ecs-v1/grok-patterns +95 -0
- data/patterns/ecs-v1/haproxy +40 -0
- data/patterns/ecs-v1/httpd +17 -0
- data/patterns/ecs-v1/java +34 -0
- data/patterns/ecs-v1/junos +13 -0
- data/patterns/ecs-v1/linux-syslog +16 -0
- data/patterns/ecs-v1/maven +1 -0
- data/patterns/ecs-v1/mcollective +4 -0
- data/patterns/ecs-v1/mongodb +7 -0
- data/patterns/ecs-v1/nagios +124 -0
- data/patterns/ecs-v1/postgresql +2 -0
- data/patterns/ecs-v1/rails +13 -0
- data/patterns/ecs-v1/redis +3 -0
- data/patterns/ecs-v1/ruby +2 -0
- data/patterns/ecs-v1/squid +6 -0
- data/patterns/ecs-v1/zeek +33 -0
- data/patterns/legacy/aws +14 -0
- data/patterns/{bacula → legacy/bacula} +5 -5
- data/patterns/legacy/bind +3 -0
- data/patterns/{bro → legacy/bro} +0 -0
- data/patterns/{exim → legacy/exim} +8 -2
- data/patterns/{firewalls → legacy/firewalls} +7 -2
- data/patterns/{grok-patterns → legacy/grok-patterns} +5 -13
- data/patterns/{haproxy → legacy/haproxy} +1 -1
- data/patterns/legacy/httpd +15 -0
- data/patterns/{java → legacy/java} +1 -4
- data/patterns/{junos → legacy/junos} +0 -0
- data/patterns/{linux-syslog → legacy/linux-syslog} +1 -1
- data/patterns/legacy/maven +1 -0
- data/patterns/{mcollective → legacy/mcollective} +0 -0
- data/patterns/{mcollective-patterns → legacy/mcollective-patterns} +0 -0
- data/patterns/{mongodb → legacy/mongodb} +0 -0
- data/patterns/{nagios → legacy/nagios} +1 -1
- data/patterns/{postgresql → legacy/postgresql} +0 -0
- data/patterns/{rails → legacy/rails} +0 -0
- data/patterns/legacy/redis +3 -0
- data/patterns/{ruby → legacy/ruby} +0 -0
- data/patterns/legacy/squid +4 -0
- data/spec/patterns/aws_spec.rb +395 -0
- data/spec/patterns/bacula_spec.rb +367 -0
- data/spec/patterns/bind_spec.rb +78 -0
- data/spec/patterns/bro_spec.rb +613 -0
- data/spec/patterns/core_spec.rb +271 -16
- data/spec/patterns/exim_spec.rb +201 -0
- data/spec/patterns/firewalls_spec.rb +683 -49
- data/spec/patterns/haproxy_spec.rb +253 -28
- data/spec/patterns/httpd_spec.rb +291 -10
- data/spec/patterns/java_spec.rb +375 -0
- data/spec/patterns/junos_spec.rb +101 -0
- data/spec/patterns/maven_spec.rb +61 -0
- data/spec/patterns/mcollective_spec.rb +35 -0
- data/spec/patterns/mongodb_spec.rb +170 -33
- data/spec/patterns/nagios_spec.rb +299 -78
- data/spec/patterns/netscreen_spec.rb +123 -0
- data/spec/patterns/rails3_spec.rb +87 -29
- data/spec/patterns/redis_spec.rb +207 -0
- data/spec/patterns/shorewall_spec.rb +85 -74
- data/spec/patterns/squid_spec.rb +139 -0
- data/spec/patterns/syslog_spec.rb +266 -8
- data/spec/spec_helper.rb +83 -5
- metadata +74 -26
- data/patterns/aws +0 -11
- data/patterns/redis +0 -3
- data/spec/patterns/bro.rb +0 -126
- data/spec/patterns/s3_spec.rb +0 -132
data/spec/patterns/core_spec.rb
CHANGED
@@ -20,16 +20,6 @@ describe "SYSLOGLINE" do
|
|
20
20
|
|
21
21
|
end
|
22
22
|
|
23
|
-
describe "COMMONAPACHELOG" do
|
24
|
-
|
25
|
-
let(:value) { '83.149.9.216 - - [24/Feb/2015:23:13:42 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-search.png HTTP/1.1" 200 203023 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36'}
|
26
|
-
|
27
|
-
it "generates the clientip field" do
|
28
|
-
expect(grok_match(subject, value)).to include("clientip" => "83.149.9.216")
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
23
|
describe "HTTP DATE parsing" do
|
34
24
|
|
35
25
|
context "HTTPDATE", "when having a German month" do
|
@@ -64,12 +54,16 @@ describe "HTTP DATE parsing" do
|
|
64
54
|
|
65
55
|
end
|
66
56
|
|
67
|
-
describe
|
68
|
-
|
69
|
-
|
57
|
+
describe 'LOGLEVEL' do
|
58
|
+
it 'matches info label' do
|
59
|
+
expect(grok_match(subject, 'INFO')).to pass
|
60
|
+
expect(grok_match(subject, 'info')).to pass
|
61
|
+
end
|
70
62
|
|
71
|
-
it
|
72
|
-
expect(grok_match(subject,
|
63
|
+
it 'matches information label' do
|
64
|
+
expect(grok_match(subject, 'information')).to pass
|
65
|
+
expect(grok_match(subject, 'Information')).to pass
|
66
|
+
expect(grok_match(subject, 'INFORMATION')).to pass
|
73
67
|
end
|
74
68
|
end
|
75
69
|
|
@@ -100,14 +94,224 @@ describe "UNIXPATH" do
|
|
100
94
|
let(:value) { '/foo/bar' }
|
101
95
|
|
102
96
|
it "should match the path" do
|
103
|
-
expect(grok_match(pattern,value)).to pass
|
97
|
+
expect(grok_match(pattern, value, true)).to pass
|
104
98
|
end
|
105
99
|
|
106
100
|
context "when using comma separators and other regexp" do
|
107
101
|
|
102
|
+
let(:pattern) { '((a=(?<a>%{UNIXPATH})?|b=(?<b>%{UNIXPATH})?)(,\s)?)+' }
|
103
|
+
|
104
|
+
let(:grok) do
|
105
|
+
grok = LogStash::Filters::Grok.new("match" => ["message", pattern])
|
106
|
+
grok.register
|
107
|
+
grok
|
108
|
+
end
|
109
|
+
|
108
110
|
let(:value) { 'a=/some/path, b=/some/other/path' }
|
109
111
|
|
112
|
+
it "was expected to extract both but never really did" do # or maybe on JRuby 1.7
|
113
|
+
event = build_event(value)
|
114
|
+
grok.filter(event)
|
115
|
+
expect( event.to_hash['a'] ).to eql '/some/path,'
|
116
|
+
expect( event.to_hash['b'] ).to be nil
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'relative path' do
|
122
|
+
|
123
|
+
let(:path_matcher) do # non-exact matcher
|
124
|
+
grok = LogStash::Filters::Grok.new("match" => ["message", '%{UNIXPATH:path}'])
|
125
|
+
grok.register
|
126
|
+
lambda { |msg| event = build_event(msg); grok.filter(event); event }
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should not match (only partially)" do
|
130
|
+
expect(grok_match(pattern, 'a/./b/c', true)).to_not pass
|
131
|
+
event = path_matcher.('a/./b/c')
|
132
|
+
expect( event.to_hash['path'] ).to eql '/./b/c'
|
133
|
+
|
134
|
+
expect(grok_match(pattern, ',/.', true)).to_not pass
|
135
|
+
event = path_matcher.(',/.')
|
136
|
+
expect( event.to_hash['path'] ).to eql '/.'
|
137
|
+
|
138
|
+
expect(grok_match(pattern, '+/.../', true)).to_not pass
|
139
|
+
event = path_matcher.('+/.../')
|
140
|
+
expect( event.to_hash['path'] ).to eql '/.../'
|
141
|
+
|
142
|
+
expect(grok_match(pattern, '~/b/', true)).to_not pass
|
143
|
+
event = path_matcher.('~/b/')
|
144
|
+
expect( event.to_hash['path'] ).to eql '/b/'
|
145
|
+
|
146
|
+
expect(grok_match(pattern, './b//', true)).to_not pass
|
147
|
+
expect(grok_match(pattern, 'a//b', true)).to_not pass
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should not match paths starting with ." do
|
151
|
+
expect(grok_match(pattern, '../0', true)).to_not pass
|
152
|
+
expect(grok_match(pattern, './~', true)).to_not pass
|
153
|
+
expect(grok_match(pattern, '.../-', true)).to_not pass
|
154
|
+
expect(grok_match(pattern, './', true)).to_not pass
|
155
|
+
expect(grok_match(pattern, './,', true)).to_not pass
|
156
|
+
expect(grok_match(pattern, '../', true)).to_not pass
|
157
|
+
expect(grok_match(pattern, '.a/', true)).to_not pass
|
158
|
+
expect(grok_match(pattern, '.~/', true)).to_not pass
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should not match expression wout separator" do
|
162
|
+
expect(grok_match(pattern, '.')).to_not pass
|
163
|
+
expect(grok_match(pattern, '..')).to_not pass
|
164
|
+
expect(grok_match(pattern, '...')).to_not pass
|
165
|
+
expect(grok_match(pattern, '.,')).to_not pass
|
166
|
+
expect(grok_match(pattern, '.-')).to_not pass
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
context "dotted path" do
|
172
|
+
|
173
|
+
it "should match path containing ." do
|
174
|
+
expect(grok_match(pattern, '/some/./path/', true)).to pass
|
175
|
+
expect(grok_match(pattern, '/some/../path', true)).to pass
|
176
|
+
expect(grok_match(pattern, '/../.', true)).to pass
|
177
|
+
expect(grok_match(pattern, '/.', true)).to pass
|
178
|
+
expect(grok_match(pattern, '/..', true)).to pass
|
179
|
+
expect(grok_match(pattern, '/...', true)).to pass
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
context "separators" do
|
185
|
+
|
186
|
+
it "should match root" do
|
187
|
+
expect(grok_match(pattern, '/', true)).to pass
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should match" do
|
191
|
+
expect(grok_match(pattern, '//', true)).to pass
|
192
|
+
expect(grok_match(pattern, '//00', true)).to pass
|
193
|
+
expect(grok_match(pattern, '///a', true)).to pass
|
194
|
+
expect(grok_match(pattern, '/a//', true)).to pass
|
195
|
+
expect(grok_match(pattern, '///a//b/c///', true)).to pass
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should not match windows separator" do
|
199
|
+
expect(grok_match(pattern, "\\a", true)).to_not pass
|
200
|
+
expect(grok_match(pattern, '/0\\', true)).to_not pass
|
201
|
+
expect(grok_match(pattern, "/a\\b", true)).to_not pass
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
context "long path" do
|
207
|
+
|
208
|
+
let(:grok) do
|
209
|
+
grok = LogStash::Filters::Grok.new("match" => ["message", '%{UNIXPATH:path} '], 'timeout_millis' => 1500)
|
210
|
+
grok.register
|
211
|
+
grok
|
212
|
+
end
|
213
|
+
|
214
|
+
let(:value) { '/opt/abcdef/1/.22/3:3+3/foo@BAR/X-Y+Z/~Sample_l_SUBc b' }
|
215
|
+
|
110
216
|
it "should match the path" do
|
217
|
+
event = build_event(value)
|
218
|
+
grok.filter(event)
|
219
|
+
expect( event.to_hash['path'] ).to eql '/opt/abcdef/1/.22/3:3+3/foo@BAR/X-Y+Z/~Sample_l_SUBc'
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should not match with invalid chars (or cause DoS)" do
|
223
|
+
event = build_event(value.sub('SUB', '&^_'))
|
224
|
+
grok.filter(event) # used to call a looong looop (DoS) despite the timeout guard
|
225
|
+
expect( event.to_hash['tags'] ).to include '_grokparsefailure'
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
it "matches paths with non-ascii characters" do
|
230
|
+
event = build_event path = '/opt/Čierný_Peter/.中'
|
231
|
+
build_grok('UNIXPATH:path').filter event
|
232
|
+
expect( event.get('path') ).to eql path
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
describe "WINPATH" do
|
238
|
+
|
239
|
+
let(:pattern) { 'WINPATH' }
|
240
|
+
let(:value) { 'C:\\foo\\bar' }
|
241
|
+
|
242
|
+
it "should match the path" do
|
243
|
+
expect(grok_match(pattern, value, true)).to pass
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should match root path" do
|
247
|
+
expect(grok_match(pattern, 'C:\\', true)).to pass
|
248
|
+
expect(grok_match(pattern, 'C:\\\\', true)).to pass
|
249
|
+
expect(grok_match(pattern, 'a:\\', true)).to pass
|
250
|
+
expect(grok_match(pattern, 'x:\\\\', true)).to pass
|
251
|
+
end
|
252
|
+
|
253
|
+
it "should match paths with spaces" do
|
254
|
+
expect(grok_match(pattern, 'C:\\Documents and Settings\\Public', true)).to pass
|
255
|
+
expect(grok_match(pattern, 'C:\\\\Users\\\\Public\\\\.Mozilla Firefox', true)).to pass
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should not match unix-style paths" do
|
259
|
+
expect(grok_match(pattern, '/foo', true)).to_not pass
|
260
|
+
expect(grok_match(pattern, '//C/path', true)).to_not pass
|
261
|
+
expect(grok_match(pattern, '/', true)).to_not pass
|
262
|
+
expect(grok_match(pattern, '/foo/bar', true)).to_not pass
|
263
|
+
expect(grok_match(pattern, '/..', true)).to_not pass
|
264
|
+
expect(grok_match(pattern, 'C://', true)).to_not pass
|
265
|
+
end
|
266
|
+
|
267
|
+
it "matches paths with non-ascii characters" do
|
268
|
+
expect(grok_match(pattern, 'C:\\Čierný Peter\\.中.exe', true)).to pass
|
269
|
+
end
|
270
|
+
|
271
|
+
context 'relative paths' do
|
272
|
+
|
273
|
+
it "should not match" do
|
274
|
+
expect(grok_match(pattern, 'a\\bar', true)).to_not pass
|
275
|
+
expect(grok_match(pattern, 'foo\\bar', true)).to_not pass
|
276
|
+
expect(grok_match(pattern, 'C\\A\\B', true)).to_not pass
|
277
|
+
expect(grok_match(pattern, 'C\\\\0', true)).to_not pass
|
278
|
+
expect(grok_match(pattern, '.\\0', true)).to_not pass
|
279
|
+
expect(grok_match(pattern, '..\\', true)).to_not pass
|
280
|
+
expect(grok_match(pattern, '...\\-', true)).to_not pass
|
281
|
+
expect(grok_match(pattern, '.\\', true)).to_not pass
|
282
|
+
expect(grok_match(pattern, '.\\,', true)).to_not pass
|
283
|
+
expect(grok_match(pattern, '..\\', true)).to_not pass
|
284
|
+
expect(grok_match(pattern, '.a\\', true)).to_not pass
|
285
|
+
end
|
286
|
+
|
287
|
+
it "should not match expression wout separator" do
|
288
|
+
expect(grok_match(pattern, '.')).to_not pass
|
289
|
+
expect(grok_match(pattern, '..')).to_not pass
|
290
|
+
expect(grok_match(pattern, '...')).to_not pass
|
291
|
+
expect(grok_match(pattern, 'C:')).to_not pass
|
292
|
+
expect(grok_match(pattern, 'C')).to_not pass
|
293
|
+
end
|
294
|
+
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
298
|
+
|
299
|
+
|
300
|
+
describe "URIPROTO" do
|
301
|
+
let(:pattern) { 'URIPROTO' }
|
302
|
+
|
303
|
+
context "http is a valid URIPROTO" do
|
304
|
+
let(:value) { 'http' }
|
305
|
+
|
306
|
+
it "should match" do
|
307
|
+
expect(grok_match(pattern,value)).to pass
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
context "android-app is a valid URIPROTO" do
|
312
|
+
let(:value) { 'android-app' }
|
313
|
+
|
314
|
+
it "should match" do
|
111
315
|
expect(grok_match(pattern,value)).to pass
|
112
316
|
end
|
113
317
|
end
|
@@ -282,3 +486,54 @@ describe "URN" do
|
|
282
486
|
end
|
283
487
|
end
|
284
488
|
end
|
489
|
+
|
490
|
+
describe_pattern "EMAILADDRESS", ['legacy', 'ecs-v1'] do
|
491
|
+
|
492
|
+
# NOTE: EMAILLOCALPART was only updated in ECS mode, as following the RFC is
|
493
|
+
# actually a breaking change -> legacy does match incorrect e-mail addresses.
|
494
|
+
|
495
|
+
it "matches 'hello.world@123.net' address" do
|
496
|
+
expect(grok_exact_match(pattern, 'hello.world@123.net')).to pass
|
497
|
+
end
|
498
|
+
|
499
|
+
[
|
500
|
+
'a@example.com',
|
501
|
+
'a{b}@example.com',
|
502
|
+
'Foo+Bar@x.exposed',
|
503
|
+
].each do |valid_email|
|
504
|
+
it "matches #{valid_email.inspect} address" do
|
505
|
+
expect(grok_exact_match(pattern, valid_email)).to pass if ecs_compatibility?
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
it "does not match 'x y@example.com' address" do
|
510
|
+
expect(grok_exact_match(pattern, 'hello.world@123.net')).to pass
|
511
|
+
end
|
512
|
+
|
513
|
+
[
|
514
|
+
'a:b@example.com',
|
515
|
+
'a..b@example.com',
|
516
|
+
].each do |invalid_email|
|
517
|
+
it "does not match #{invalid_email.inspect} address" do
|
518
|
+
expect(grok_exact_match(pattern, invalid_email)).to_not pass if ecs_compatibility?
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
it "matches e-mail with digits only local-part" do
|
523
|
+
expect(grok_exact_match(pattern, '00@q.ro')).to pass if ecs_compatibility?
|
524
|
+
end
|
525
|
+
|
526
|
+
it "matches e-mail with 64 chars in local-part" do
|
527
|
+
expect(grok_exact_match(pattern, ('ab' * 32) + '@root.cz')).to pass
|
528
|
+
expect(grok_exact_match(pattern, ('a.bc' * 16) + '@00.cz')).to pass
|
529
|
+
end
|
530
|
+
|
531
|
+
it "does not match e-mail with more than 64 char length local-part" do
|
532
|
+
if ecs_compatibility?
|
533
|
+
expect(grok_exact_match(pattern, ('ab' * 32) + 'a' + '@root.cz')).to_not pass
|
534
|
+
# NOTE: we allow longer with '.' but at least we limit "too long" :
|
535
|
+
expect(grok_exact_match(pattern, ('a.bc' * 64) + '@00.cz')).to_not pass
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
require "logstash/patterns/core"
|
4
|
+
|
5
|
+
describe_pattern 'EXIM', ['legacy', 'ecs-v1'] do
|
6
|
+
|
7
|
+
context 'message arrival (old)' do
|
8
|
+
|
9
|
+
let(:message) do
|
10
|
+
"1995-10-31 08:57:53 0tACW1-0005MB-00 <= kryten@dwarf.fict.example H=mailer.fict.example [192.168.123.123] " +
|
11
|
+
"U=exim P=smtp S=5678 id=f828ca60127d8646a0fa75cbf8db9ba3@dwarf.fict.example"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "matches" do
|
15
|
+
expect(grok).to include("timestamp" => "1995-10-31 08:57:53")
|
16
|
+
|
17
|
+
if ecs_compatibility?
|
18
|
+
expect(grok).to include("exim"=>{"log"=>{
|
19
|
+
"flags"=>"<=",
|
20
|
+
"sender"=>{"email"=>"kryten@dwarf.fict.example"},
|
21
|
+
"message"=>{"id"=>"0tACW1-0005MB-00", "size"=>5678},
|
22
|
+
"header_id"=>"f828ca60127d8646a0fa75cbf8db9ba3@dwarf.fict.example"
|
23
|
+
}})
|
24
|
+
expect(grok).to include("source"=>{"address"=>"mailer.fict.example", "ip"=>"192.168.123.123"})
|
25
|
+
expect(grok).to include("network"=>{"protocol"=>"smtp"})
|
26
|
+
else
|
27
|
+
expect(grok).to include("exim_year" => "1995", "exim_month" => "10", "exim_day" => "31", "@version" => "1", "exim_time" => "08:57:53")
|
28
|
+
expect(grok.keys).to_not include("pid")
|
29
|
+
expect(grok).to include("exim_sender_email" => "kryten@dwarf.fict.example")
|
30
|
+
expect(grok).to include("exim_flags" => "<=")
|
31
|
+
expect(grok).to include("exim_msg_size" => "5678")
|
32
|
+
expect(grok).to include("exim_msgid" => "0tACW1-0005MB-00")
|
33
|
+
expect(grok).to include("remote_hostname" => "mailer.fict.example", "remote_host" => "192.168.123.123")
|
34
|
+
expect(grok).to include("protocol" => "smtp")
|
35
|
+
expect(grok).to include("exim_header_id" => "f828ca60127d8646a0fa75cbf8db9ba3@dwarf.fict.example")
|
36
|
+
end
|
37
|
+
|
38
|
+
expect(grok).to include("message" => message)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'message arrival (new)' do
|
44
|
+
let(:message) do
|
45
|
+
'2010-09-13 05:00:13 [1487] 1Ov4tU-0000Nz-Rm <= mailling.list@domain.com ' +
|
46
|
+
'H=mailhost.domain.com [208.42.54.2]:51792 I=[67.215.162.175]:25 P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=21778 ' +
|
47
|
+
'id=384a86a39e83be0d9b3a94d1feb3119f@domain.com T="Daily List: Chameleon" for user@example.com'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "matches" do
|
51
|
+
expect(grok).to include("timestamp" => "2010-09-13 05:00:13") # new in legacy mode
|
52
|
+
|
53
|
+
if ecs_compatibility?
|
54
|
+
expect(grok).to include("process"=>{"pid"=>1487})
|
55
|
+
expect(grok).to include("exim"=>{"log"=>hash_including(
|
56
|
+
"message"=>{"id"=>"1Ov4tU-0000Nz-Rm", "size"=>21778, "subject"=>"Daily List: Chameleon"},
|
57
|
+
"flags"=>"<=",
|
58
|
+
"header_id"=>"384a86a39e83be0d9b3a94d1feb3119f@domain.com",
|
59
|
+
"sender"=>{"email"=>"mailling.list@domain.com"},
|
60
|
+
"recipient"=>{"email"=>"user@example.com"},
|
61
|
+
)})
|
62
|
+
expect(grok).to include("source"=>{"address"=>"mailhost.domain.com", "ip"=>"208.42.54.2", "port"=>51792})
|
63
|
+
expect(grok).to include("destination"=>{"ip"=>"67.215.162.175", "port"=>25})
|
64
|
+
else
|
65
|
+
|
66
|
+
expect(grok).to include("exim_year" => "2010", "exim_month" => "09", "exim_day" => "13", "exim_time" => "05:00:13")
|
67
|
+
expect(grok).to include("pid" => "1487") # new
|
68
|
+
expect(grok).to include("exim_sender_email" => "mailling.list@domain.com") # new
|
69
|
+
expect(grok).to include("remote_hostname" => "mailhost.domain.com", "remote_host" => "208.42.54.2", "remote_port" => "51792") # (remote_port) new
|
70
|
+
expect(grok).to include("exim_interface" => "67.215.162.175", "exim_interface_port" => "25")
|
71
|
+
expect(grok).to include("protocol" => "esmtps")
|
72
|
+
expect(grok).to include("exim_msg_size" => "21778")
|
73
|
+
expect(grok).to include("exim_header_id" => "384a86a39e83be0d9b3a94d1feb3119f@domain.com")
|
74
|
+
expect(grok).to include("exim_subject" => '"Daily List: Chameleon"')
|
75
|
+
expect(grok).to include("exim_recipient_email" => "user@example.com") # new
|
76
|
+
end
|
77
|
+
|
78
|
+
expect(grok).to include("message" => message)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'message arrival (simple)' do
|
84
|
+
|
85
|
+
let(:message) do
|
86
|
+
'2020-02-11 17:09:46 1j1Z2g-00Faoy-Uh <= example@strawberry.active-ns.com U=example P=local ' +
|
87
|
+
'T="[Examples Galore] Please moderate: \"Hello world!\"" for admin@example.net'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "matches" do
|
91
|
+
expect(grok).to include("timestamp"=>"2020-02-11 17:09:46")
|
92
|
+
if ecs_compatibility?
|
93
|
+
expect(grok).to include("exim"=>{"log"=>{
|
94
|
+
"flags"=>"<=",
|
95
|
+
"message"=>{"id"=>"1j1Z2g-00Faoy-Uh", "subject"=>'[Examples Galore] Please moderate: \\"Hello world!\\"'},
|
96
|
+
"sender"=>{"email"=>"example@strawberry.active-ns.com"},
|
97
|
+
"recipient"=>{"email"=>"admin@example.net"}
|
98
|
+
}})
|
99
|
+
expect(grok).to include("network"=>{"protocol"=>"local"})
|
100
|
+
else
|
101
|
+
expect(grok).to include(
|
102
|
+
"exim_msgid"=>"1j1Z2g-00Faoy-Uh",
|
103
|
+
"exim_sender_email"=>"example@strawberry.active-ns.com",
|
104
|
+
"exim_flags"=>"<=",
|
105
|
+
"protocol"=>"local",
|
106
|
+
"exim_subject"=>"\"[Examples Galore] Please moderate: \\\"Hello world!\\\"\""
|
107
|
+
)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'message arrival with quoted hostname' do
|
114
|
+
|
115
|
+
let(:message) do
|
116
|
+
'2013-03-20 12:44:02 1UIIN7-0004t9-8R <= root@example.com ' +
|
117
|
+
'H=localhost (hostname.example.com) [127.0.0.1] ' +
|
118
|
+
'P=esmtps X=TLSv1:DHE-RSA-AES256-SHA:256 S=811 id=201303201244.r2KCi11V018784@hostname.example.com'
|
119
|
+
end
|
120
|
+
|
121
|
+
it "matches" do
|
122
|
+
expect(grok).to include("timestamp"=>"2013-03-20 12:44:02")
|
123
|
+
|
124
|
+
if ecs_compatibility?
|
125
|
+
expect(grok).to include("exim"=>{"log"=>hash_including(
|
126
|
+
"sender"=>{ "email"=>"root@example.com" },
|
127
|
+
"message"=>{ "id"=>"1UIIN7-0004t9-8R", "size"=>811 },
|
128
|
+
"header_id"=>"201303201244.r2KCi11V018784@hostname.example.com",
|
129
|
+
"remote_address"=>"hostname.example.com")})
|
130
|
+
expect(grok).to include("source"=>{"address"=>"localhost", "ip"=>"127.0.0.1"})
|
131
|
+
expect(grok).to include("network"=>{"protocol"=>"esmtps"})
|
132
|
+
else
|
133
|
+
expect(grok).to include(
|
134
|
+
"exim_msgid"=>"1UIIN7-0004t9-8R",
|
135
|
+
"exim_sender_email"=>"root@example.com",
|
136
|
+
"exim_flags"=>"<=",
|
137
|
+
"protocol"=>"esmtps",
|
138
|
+
"exim_header_id"=>"201303201244.r2KCi11V018784@hostname.example.com"
|
139
|
+
)
|
140
|
+
expect(grok).to include(
|
141
|
+
"remote_host"=>"127.0.0.1",
|
142
|
+
"remote_heloname"=>"hostname.example.com",
|
143
|
+
"remote_hostname"=>"localhost"
|
144
|
+
)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
context 'message arrival with quoted hostname and port' do
|
152
|
+
|
153
|
+
let(:message) do
|
154
|
+
'2014-08-10 11:18:35 [28107] 1gsu1C-003dCu-Hb <= aaron@domain.com ' +
|
155
|
+
'H=localhost (10.5.40.204) [127.0.0.1]:39753 I=[127.0.0.1]:25 ' +
|
156
|
+
'P=esmtpa A=dovecot_plain:aaron@domain.com S=4315 M8S=0 id=d2b648f00f1a1b0813c483d552778dc6@domain.com ' +
|
157
|
+
"T=\"what's up?!? ;-)\" from <aaron@domain.com> for aaron+forward@domain.com"
|
158
|
+
end
|
159
|
+
|
160
|
+
it "matches" do
|
161
|
+
if ecs_compatibility?
|
162
|
+
expect(grok).to include("exim"=>{"log"=>hash_including(
|
163
|
+
"message"=>hash_including("id"=>"1gsu1C-003dCu-Hb", "subject"=>"what's up?!? ;-)"),
|
164
|
+
)})
|
165
|
+
expect(grok).to include("destination"=>{"ip"=>"127.0.0.1", "port"=>25})
|
166
|
+
expect(grok).to include("exim"=>{"log"=>hash_including(
|
167
|
+
"sender"=>{"email"=>"aaron@domain.com", 'original'=>'aaron@domain.com'}
|
168
|
+
)})
|
169
|
+
expect(grok).to include("exim"=>{"log"=>hash_including("recipient"=>{"email"=>"aaron+forward@domain.com"})})
|
170
|
+
expect(grok).to include("source"=>{"address"=>"localhost", "ip"=>"127.0.0.1", "port"=>39753})
|
171
|
+
expect(grok).to include("exim"=>{"log" => hash_including("remote_address"=>'10.5.40.204')})
|
172
|
+
else
|
173
|
+
expect(grok).to include(
|
174
|
+
"exim_msgid"=>"1gsu1C-003dCu-Hb",
|
175
|
+
"exim_sender_email"=>"aaron@domain.com",
|
176
|
+
"exim_flags"=>"<=",
|
177
|
+
"protocol"=>"esmtpa"
|
178
|
+
)
|
179
|
+
expect(grok).to include(
|
180
|
+
"remote_host"=>"127.0.0.1", "remote_port"=>"39753",
|
181
|
+
"remote_heloname"=>"10.5.40.204",
|
182
|
+
"remote_hostname"=>"localhost"
|
183
|
+
)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'delivery failed' do
|
190
|
+
|
191
|
+
let(:message) do
|
192
|
+
'2020-02-11 17:09:47 1j1Z2g-00Faoy-Uh ** admin@example.net R=virtual_aliases: No such person at this address.'
|
193
|
+
end
|
194
|
+
|
195
|
+
it "does not parse" do # matching not implemented
|
196
|
+
expect(grok['tags']).to include("_grokparsefailure")
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|