logstash-patterns-core 4.2.0 → 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 +4 -4
- data/CHANGELOG.md +98 -0
- data/Gemfile +3 -0
- data/README.md +11 -18
- 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/{maven → ecs-v1/maven} +0 -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/{aws → legacy/aws} +1 -1
- 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} +2 -2
- data/patterns/{grok-patterns → legacy/grok-patterns} +0 -0
- data/patterns/{haproxy → legacy/haproxy} +0 -0
- data/patterns/{httpd → legacy/httpd} +1 -1
- data/patterns/{java → legacy/java} +0 -0
- data/patterns/{junos → legacy/junos} +0 -0
- data/patterns/{linux-syslog → legacy/linux-syslog} +0 -0
- 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} +0 -0
- data/patterns/{postgresql → legacy/postgresql} +0 -0
- data/patterns/{rails → legacy/rails} +0 -0
- data/patterns/{redis → legacy/redis} +0 -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 +51 -9
- data/spec/patterns/exim_spec.rb +201 -0
- data/spec/patterns/firewalls_spec.rb +669 -66
- data/spec/patterns/haproxy_spec.rb +246 -38
- data/spec/patterns/httpd_spec.rb +215 -94
- data/spec/patterns/java_spec.rb +357 -27
- data/spec/patterns/junos_spec.rb +101 -0
- data/spec/patterns/mcollective_spec.rb +35 -0
- data/spec/patterns/mongodb_spec.rb +170 -33
- data/spec/patterns/nagios_spec.rb +296 -79
- data/spec/patterns/netscreen_spec.rb +123 -0
- data/spec/patterns/rails3_spec.rb +87 -29
- data/spec/patterns/redis_spec.rb +157 -121
- data/spec/patterns/shorewall_spec.rb +85 -74
- data/spec/patterns/squid_spec.rb +139 -0
- data/spec/patterns/syslog_spec.rb +266 -22
- data/spec/spec_helper.rb +80 -6
- metadata +64 -28
- data/patterns/bind +0 -3
- data/patterns/squid +0 -4
- data/spec/patterns/bro.rb +0 -126
- data/spec/patterns/s3_spec.rb +0 -173
@@ -0,0 +1,367 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
require "logstash/patterns/core"
|
4
|
+
|
5
|
+
describe_pattern "BACULA_LOG_MAX_CAPACITY", ['legacy', 'ecs-v1'] do
|
6
|
+
|
7
|
+
let(:message) do
|
8
|
+
'User defined maximum volume capacity 108,372,182,400 exceeded on device "FStorage" (/var/lib/bac/storage).'
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'matches' do
|
12
|
+
if ecs_compatibility?
|
13
|
+
should include "bacula"=>{"volume"=>{"max_capacity"=>"108,372,182,400", "device"=>"FStorage", "path"=>"/var/lib/bac/storage"}}
|
14
|
+
else
|
15
|
+
should include("device"=>"FStorage")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe_pattern "BACULA_LOG_END_VOLUME", ['legacy', 'ecs-v1'] do
|
22
|
+
|
23
|
+
let(:message) do
|
24
|
+
'End of medium on Volume "TestShortZN0014" Bytes=5,228,777 Blocks=82 at 21-Dec-2016 12:30.'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'matches' do
|
28
|
+
if ecs_compatibility?
|
29
|
+
should include "bacula"=>hash_including("volume"=>{"name"=>"TestShortZN0014", "bytes"=>"5,228,777", "blocks"=>"82"})
|
30
|
+
# bacula.timestamp is 'duplicate' information when the full BACULA_LOGLINE is matched
|
31
|
+
# we're keeping it as it includes year and might be slightly off the matched timestamp
|
32
|
+
should include "bacula"=>hash_including("timestamp"=>"21-Dec-2016 12:30")
|
33
|
+
else
|
34
|
+
should include("volume"=>"TestShortZN0014")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_NEW_VOLUME
|
41
|
+
|
42
|
+
let(:message) do
|
43
|
+
'09-Jan 19:54 bacula-host JobId 265896: Created new Volume "FullAuto-8812" in catalog.'
|
44
|
+
# NOTE: we do not match full message log format that look like:
|
45
|
+
# 'Created new Volume="FullAuto-8812", Pool="FullFile", MediaType="FullFile" in catalog.'
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'matches' do
|
49
|
+
should include (ecs_compatibility? ? "timestamp" : "bts") => '09-Jan 19:54'
|
50
|
+
if ecs_compatibility?
|
51
|
+
should include "bacula"=>{"volume"=>{"name"=>"FullAuto-8812"}, "job"=>{"id"=>"265896"}}
|
52
|
+
should include "host" => {"hostname"=>"bacula-host"}
|
53
|
+
else
|
54
|
+
should include("volume"=>"FullAuto-8812")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_NEW_LABEL
|
61
|
+
|
62
|
+
let(:message) do
|
63
|
+
'25-Aug 10:50 bacula-sd JobId 24: Labeled new Volume "Vol-0018" on device "FileChgr1-Dev1" (/opt/bacula/disk).'
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'matches' do
|
67
|
+
should include (ecs_compatibility? ? "timestamp" : "bts") => '25-Aug 10:50'
|
68
|
+
if ecs_compatibility?
|
69
|
+
should include "bacula"=>hash_including("volume"=>{"name"=>"Vol-0018", "device"=>"FileChgr1-Dev1", "path"=>"/opt/bacula/disk"})
|
70
|
+
should include "bacula"=>hash_including("job"=>{"id"=>"24"})
|
71
|
+
should include "host" => {"hostname"=>"bacula-sd"}
|
72
|
+
else
|
73
|
+
should include("volume"=>"Vol-0018", "device" => "FileChgr1-Dev1")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_WROTE_LABEL
|
80
|
+
|
81
|
+
let(:message) do
|
82
|
+
'25-Aug 10:50 bacula-sd JobId 24: Wrote label to prelabeled Volume "Volume01" on device "Device01" (/dev/nst0)'
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'matches' do
|
86
|
+
should include (ecs_compatibility? ? "timestamp" : "bts") => '25-Aug 10:50'
|
87
|
+
if ecs_compatibility?
|
88
|
+
should include "bacula"=>hash_including("volume"=>{"name"=>"Volume01", "device"=>"Device01", "path"=>"/dev/nst0"})
|
89
|
+
else
|
90
|
+
should include("jobid"=>"24")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_NEW_MOUNT
|
97
|
+
|
98
|
+
let(:message) do
|
99
|
+
'24-Aug 01:54 crey-sd JobId 215534: New volume "DiffAuto-4861" mounted on device "vDrive-1" (/usr/local/bac/volumes) at 24-Aug-2015 01:54.'
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'matches' do
|
103
|
+
should include (ecs_compatibility? ? "timestamp" : "bts") => '24-Aug 01:54'
|
104
|
+
if ecs_compatibility?
|
105
|
+
should include "bacula"=>hash_including("volume"=>{"name"=>"DiffAuto-4861", "device"=>"vDrive-1", "path"=>"/usr/local/bac/volumes"})
|
106
|
+
else
|
107
|
+
should include("device"=>"vDrive-1", "volume"=>"DiffAuto-4861", "hostname"=>"crey-sd", "jobid"=>"215534")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_NOOPENDIR
|
114
|
+
|
115
|
+
let(:message) do
|
116
|
+
'24-Feb 16:36 starfury-fd JobId 3: Could not open directory "/root": ERR=Permission denied'
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'matches' do
|
120
|
+
should include (ecs_compatibility? ? "timestamp" : "bts") => '24-Feb 16:36'
|
121
|
+
if ecs_compatibility?
|
122
|
+
should include "file"=>{"path"=>"/root"}
|
123
|
+
should include "error"=>{"message"=>"Permission denied"}
|
124
|
+
else
|
125
|
+
should include("berror"=>"Permission denied")
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_NOSTAT
|
132
|
+
|
133
|
+
let(:message) do
|
134
|
+
'15-Dec 17:50 u22.com JobId 13: Could not stat /var/lib/bacula/bacula.sql: ERR=No such file or directory'
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'matches' do
|
138
|
+
if ecs_compatibility?
|
139
|
+
should include "timestamp" => '15-Dec 17:50'
|
140
|
+
should include "file"=>{"path"=>"/var/lib/bacula/bacula.sql"}
|
141
|
+
should include "error"=>{"message"=>"No such file or directory"}
|
142
|
+
else
|
143
|
+
# NOTE: not matching due BACULA_HOST
|
144
|
+
# should include "bts" => '15-Dec 17:50'
|
145
|
+
# should include "berror"=>"No such file or directory"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_ALL_RECORDS_PRUNED
|
152
|
+
|
153
|
+
let(:message) do
|
154
|
+
'12-Apr 14:23 VU0EM005: All records pruned from Volume "06D125L3"; marking it "Purged"'
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'matches' do
|
158
|
+
should include (ecs_compatibility? ? "timestamp" : "bts") => '12-Apr 14:23'
|
159
|
+
if ecs_compatibility?
|
160
|
+
should include "bacula"=>{"volume"=>{"name"=>"06D125L3"}},
|
161
|
+
"host"=>{"hostname"=>"VU0EM005"}
|
162
|
+
else
|
163
|
+
should include "hostname"=>"VU0EM005", "volume"=>"06D125L3"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_PRUNED_JOBS
|
170
|
+
|
171
|
+
let(:message) do
|
172
|
+
'29-Jan 04:16 lbu02-dir: Pruned 24 Jobs for client uni-horn from catalog.'
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'matches' do
|
176
|
+
should include (ecs_compatibility? ? "timestamp" : "bts") => '29-Jan 04:16'
|
177
|
+
if ecs_compatibility?
|
178
|
+
should include "bacula"=>{"client"=>{"name"=>"uni-horn"}}, "host"=>{"hostname"=>"lbu02-dir"}
|
179
|
+
else
|
180
|
+
should include "hostname"=>"lbu02-dir", "client"=>"uni-horn"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_STARTJOB
|
187
|
+
|
188
|
+
let(:message) do
|
189
|
+
'06-Mar 20:00 srvbkp-dir JobId 1075: Start Backup JobId 1075, Job=srv1-bind.2018-03-06_20.00.01_05'
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'matches' do
|
193
|
+
should include (ecs_compatibility? ? "timestamp" : "bts") => '06-Mar 20:00'
|
194
|
+
if ecs_compatibility?
|
195
|
+
should include "bacula"=>{"job"=>{"name"=>"srv1-bind.2018-03-06_20.00.01_05", "id"=>"1075"}}
|
196
|
+
else
|
197
|
+
should include "job"=>"srv1-bind.2018-03-06_20.00.01_05", "jobid"=>"1075"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_DIFF_FS
|
204
|
+
|
205
|
+
let(:message) do
|
206
|
+
'01-Feb 00:34 ohms-fd JobId 1662: /var/spool/bareos is a different filesystem. Will not descend from /var into it.'
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'matches' do
|
210
|
+
should include (ecs_compatibility? ? "timestamp" : "bts") => '01-Feb 00:34'
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_JOBEND
|
216
|
+
|
217
|
+
let(:message) do
|
218
|
+
'28-Aug 21:55 bacula-sd JobId 16: Job write elapsed time = 00:00:01, Transfer rate = 0 Bytes/second'
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'matches' do
|
222
|
+
should include (ecs_compatibility? ? "timestamp" : "bts") => '28-Aug 21:55'
|
223
|
+
if ecs_compatibility?
|
224
|
+
should include "bacula"=>{"job"=>{"elapsed_time"=>"00:00:01", "id"=>"16"}}
|
225
|
+
else
|
226
|
+
should include "jobid"=>"16", "elapsed" => "00:00:01"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
|
232
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_VOLUME_PREVWRITTEN
|
233
|
+
|
234
|
+
let(:message) do
|
235
|
+
'17-Jan-2003 16:45 home-sd: Volume test01 previously written, moving to end of data.'
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'matches' do
|
239
|
+
if ecs_compatibility?
|
240
|
+
should include "timestamp" => '17-Jan-2003 16:45'
|
241
|
+
should include "bacula"=>{"volume"=>{"name"=>"test01"}}
|
242
|
+
else
|
243
|
+
# fails to match (due timestamp format)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
describe_pattern "BACULA_LOG_READYAPPEND", ['legacy', 'ecs-v1'] do
|
250
|
+
|
251
|
+
let(:message) do
|
252
|
+
'Ready to append to end of Volume "F-0032" size=97835302'
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'matches' do
|
256
|
+
if ecs_compatibility?
|
257
|
+
should include "bacula"=>{"volume"=>{"name"=>"F-0032", "size"=>97835302}}
|
258
|
+
else
|
259
|
+
should include "volume"=>"F-0032"
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_CLIENT_RBJ
|
266
|
+
|
267
|
+
let(:message) do
|
268
|
+
'01-Aug 13:30 toe-fd JobId 686: shell command: run ClientRunBeforeJob "/etc/bacula/cbe_hanfs.sh /mnt/baxter/fs1"'
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'matches' do
|
272
|
+
if ecs_compatibility?
|
273
|
+
should include "bacula"=>{"job"=>{"id"=>"686", "client_run_before_command"=>'/etc/bacula/cbe_hanfs.sh /mnt/baxter/fs1'}}
|
274
|
+
else
|
275
|
+
should include "jobid"=>"686", "runjob"=>"/etc/bacula/cbe_hanfs.sh /mnt/baxter/fs1"
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
280
|
+
|
281
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_FATAL_CONN
|
282
|
+
|
283
|
+
let(:message) do
|
284
|
+
'11-Nov 13:28 bacula-dir JobId 11: Fatal error: bsock.c:133 Unable to connect to Client: dc0-fd on dc0.teamworld.com:9102. ERR=Connection refused'
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'matches' do
|
288
|
+
if ecs_compatibility?
|
289
|
+
should include "client"=>{"address"=>"dc0.teamworld.com", "port"=>9102},
|
290
|
+
"bacula"=>hash_including("client"=>{"name"=>"dc0-fd"}),
|
291
|
+
"error"=>{"message"=>"Connection refused"}
|
292
|
+
else
|
293
|
+
should include "client"=>"dc0-fd", "berror"=>"Connection refused"
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
298
|
+
|
299
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_NO_AUTH
|
300
|
+
|
301
|
+
let(:message) do
|
302
|
+
'16-May 11:59 samy-dir JobId 0: Fatal error: Unable to authenticate with File daemon at "cardam.home.domain:9102". Possible causes:'
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'matches' do
|
306
|
+
if ecs_compatibility?
|
307
|
+
# NOTE: due a grok bug port:int type-casting does not work :
|
308
|
+
#should include "client"=>{"address"=>"cardam.home.domain", "port"=>9102}
|
309
|
+
expect( subject['client'] ).to be_a Hash
|
310
|
+
expect( subject['client']['address'] ).to eql 'cardam.home.domain'
|
311
|
+
expect( subject['client']['port'].to_i ).to eql 9102
|
312
|
+
else
|
313
|
+
# does not match due client address:port
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
end
|
318
|
+
|
319
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_CANCELLING
|
320
|
+
|
321
|
+
let(:message) do
|
322
|
+
'03-Aug 06:20 DIRECTOR JobId 316677: Cancelling duplicate JobId=316646.'
|
323
|
+
end
|
324
|
+
|
325
|
+
it 'matches' do
|
326
|
+
if ecs_compatibility?
|
327
|
+
expect( subject ).to include "bacula" => hash_including("job" => {'id' => '316677', 'other_id' => '316646'})
|
328
|
+
else
|
329
|
+
expect( subject ).to include "jobid" => "316677"
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
end
|
334
|
+
|
335
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_MARKCANCEL
|
336
|
+
|
337
|
+
let(:message) do
|
338
|
+
'09-Aug 15:14 InternetServer-sd JobId 122971, Job nyi_maildir.2013-03-03_22.00.00_51 marked to be canceled.'
|
339
|
+
end
|
340
|
+
|
341
|
+
it 'matches' do
|
342
|
+
if ecs_compatibility?
|
343
|
+
expect( subject ).to include "bacula" => hash_including(
|
344
|
+
"job" => {'id' => '122971', 'name' => 'nyi_maildir.2013-03-03_22.00.00_51'})
|
345
|
+
else
|
346
|
+
expect( subject ).to include "job" => "nyi_maildir.2013-03-03_22.00.00_51"
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
end
|
351
|
+
|
352
|
+
|
353
|
+
describe_pattern "BACULA_LOGLINE", ['legacy', 'ecs-v1'] do # BACULA_LOG_FATAL_CONN
|
354
|
+
|
355
|
+
let(:message) do
|
356
|
+
'25-Aug 09:02 marlin2-dir JobId 10783: Fatal Error: JobId 10782 already running. Duplicate job not allowed.'
|
357
|
+
end
|
358
|
+
|
359
|
+
it 'matches' do
|
360
|
+
if ecs_compatibility?
|
361
|
+
expect( subject ).to include "bacula" => hash_including("job" => {'id' => '10783', 'other_id' => '10782'})
|
362
|
+
else
|
363
|
+
# NOTE: not matching due expecting 'error' instead of 'Error' in "Fatal Error: JobId ..."
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
require "logstash/patterns/core"
|
4
|
+
|
5
|
+
describe_pattern "BIND9", ['legacy', 'ecs-v1'] do
|
6
|
+
|
7
|
+
let(:message) do # Bind 9.10
|
8
|
+
'17-Feb-2018 23:06:56.326 queries: info: client 172.26.0.1#12345 (test.example.com): query: test.example.com IN A +E(0)K (172.26.0.3)'
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'matches' do
|
12
|
+
should include("timestamp" => "17-Feb-2018 23:06:56.326")
|
13
|
+
if ecs_compatibility?
|
14
|
+
should include("log" => hash_including("level" => "info"))
|
15
|
+
should include("client" => { "ip" => "172.26.0.1", "port" => 12345 })
|
16
|
+
should include("dns" => { "question" => { "name" => "test.example.com", "type" => 'A', "class" => 'IN' }})
|
17
|
+
should include("bind" => { "log" => { "question" => hash_including("flags" => '+E(0)K')}})
|
18
|
+
should include("server" => { "ip" => "172.26.0.3" })
|
19
|
+
# NOTE: duplicate but still captured since we've been doing that before as well :
|
20
|
+
should include("bind" => { "log" => { "question" => hash_including("name" => 'test.example.com')}})
|
21
|
+
else
|
22
|
+
should include("loglevel" => "info")
|
23
|
+
should include("clientip" => "172.26.0.1")
|
24
|
+
should include("clientport" => "12345")
|
25
|
+
should include("query" => ["test.example.com", "test.example.com"])
|
26
|
+
should include("querytype" => "A +E(0)K")
|
27
|
+
should include("dns" => "172.26.0.3")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with client memory address (since Bind 9.11)' do
|
32
|
+
# logging format is the same <= 9.16, but if using a separate query-log all options need to be enabled :
|
33
|
+
# channel query.log {
|
34
|
+
# file "/var/log/named/query.log";
|
35
|
+
# severity debug 3;
|
36
|
+
# //print-time YES; // @timestamp
|
37
|
+
# //print-category YES; // queries:
|
38
|
+
# //print-severity YES; // info:
|
39
|
+
# };
|
40
|
+
|
41
|
+
let(:message) do # client @0x7f64500020ef - memory address of the data structure representing the client
|
42
|
+
'30-Jun-2018 15:50:00.999 queries: info: client @0x7f64500020ef 192.168.10.48#60061 (91.2.10.170.in-addr.internal): query: 91.2.10.170.in-addr.internal IN PTR + (192.168.2.2)'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'matches' do
|
46
|
+
should include("timestamp" => "30-Jun-2018 15:50:00.999")
|
47
|
+
if ecs_compatibility?
|
48
|
+
should include("log" => hash_including("level" => "info"))
|
49
|
+
should include("client" => { "ip" => "192.168.10.48", "port" => 60061 })
|
50
|
+
should include("dns" => { "question" => { "name" => "91.2.10.170.in-addr.internal", "type" => 'PTR', "class" => 'IN' }})
|
51
|
+
should include("bind" => { "log" => { "question" => hash_including("flags" => '+')}})
|
52
|
+
should include("server" => { "ip" => "192.168.2.2" })
|
53
|
+
else
|
54
|
+
should include("loglevel" => "info")
|
55
|
+
should include("clientip" => "192.168.10.48")
|
56
|
+
should include("clientport" => "60061")
|
57
|
+
should include("query" => ["91.2.10.170.in-addr.internal", "91.2.10.170.in-addr.internal"])
|
58
|
+
should include("querytype" => "PTR +")
|
59
|
+
should include("dns" => "192.168.2.2")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
describe_pattern "BIND9_QUERYLOGBASE", ['ecs-v1'] do
|
68
|
+
let(:message) do
|
69
|
+
'client @0x7f85b4026ed0 127.0.0.1#42520 (ci.elastic.co): query: ci.elastic.co IN A +E(0)K (35.193.103.164)'
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'matches' do
|
73
|
+
should include("client" => { "ip" => "127.0.0.1", "port" => 42520 })
|
74
|
+
should include("dns" => { "question" => { "name" => "ci.elastic.co", "type" => 'A', "class" => 'IN' }})
|
75
|
+
should include("bind" => { "log" => { "question" => hash_including("flags" => '+E(0)K') }})
|
76
|
+
should include("server" => { "ip" => "35.193.103.164" })
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,613 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
require "logstash/patterns/core"
|
4
|
+
|
5
|
+
describe_pattern "BRO_HTTP", ['legacy', 'ecs-v1'] do
|
6
|
+
|
7
|
+
let(:message) do # old BRO logging format
|
8
|
+
"1432555199.633017 COpk6E3vkURP8QQNKl 192.168.9.35 55281 178.236.7.146 80 4 POST www.amazon.it /xa/dealcontent/v2/GetDeals?nocache=1432555199326 http://www.amazon.it/ Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 223 1859 200 OK - - - (empty) kares - - FrLEcY3AUPKdcYGf29 text/plain FOJpbGzIMh9syPxH8 text/plain"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "matches a simple message" do
|
12
|
+
expect(pattern).to match(message)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "generates the ts field" do
|
16
|
+
if ecs_compatibility?
|
17
|
+
expect(grok).to include("timestamp" => "1432555199.633017")
|
18
|
+
else
|
19
|
+
expect(grok).to include("ts" => "1432555199.633017")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "generates the uid field" do
|
24
|
+
if ecs_compatibility?
|
25
|
+
expect(grok).to include("zeek" => hash_including("session_id" => "COpk6E3vkURP8QQNKl"))
|
26
|
+
else
|
27
|
+
expect(grok).to include("uid" => "COpk6E3vkURP8QQNKl")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "generates the orig_ fields" do
|
32
|
+
if ecs_compatibility?
|
33
|
+
expect(grok).to include("source" => { "ip" => "192.168.9.35", "port" => 55281 })
|
34
|
+
else
|
35
|
+
expect(grok).to include("orig_h" => "192.168.9.35", "orig_p" => "55281")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "generates the resp_ fields" do
|
40
|
+
if ecs_compatibility?
|
41
|
+
expect(grok).to include("destination" => { "ip" => "178.236.7.146", "port" => 80 })
|
42
|
+
|
43
|
+
else
|
44
|
+
expect(grok).to include("resp_h" => "178.236.7.146", "resp_p" => "80")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "generates the trans_depth field" do
|
49
|
+
if ecs_compatibility?
|
50
|
+
expect(grok).to include("zeek" => hash_including("http" => hash_including("trans_depth" => 4)))
|
51
|
+
else
|
52
|
+
expect(grok).to include("trans_depth" => "4")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "generates the method/referrer field" do
|
57
|
+
if ecs_compatibility?
|
58
|
+
expect(grok).to include("http" => hash_including("request" => hash_including("method" => "POST", "referrer" => "http://www.amazon.it/" )))
|
59
|
+
else
|
60
|
+
expect(grok).to include("method" => "POST")
|
61
|
+
expect(grok).to include("referrer" => "http://www.amazon.it/")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it "generates the domain/uri/referrer & username/password field" do
|
66
|
+
if ecs_compatibility?
|
67
|
+
expect(grok).to include("url" => hash_including("domain" => "www.amazon.it"))
|
68
|
+
expect(grok).to include("url" => hash_including("original" => "/xa/dealcontent/v2/GetDeals?nocache=1432555199326"))
|
69
|
+
|
70
|
+
expect(grok).to include("url" => hash_including("username" => "kares"))
|
71
|
+
expect(grok['url'].keys).to_not include("password")
|
72
|
+
else
|
73
|
+
expect(grok).to include("domain" => "www.amazon.it")
|
74
|
+
expect(grok).to include("uri" => "/xa/dealcontent/v2/GetDeals?nocache=1432555199326")
|
75
|
+
|
76
|
+
expect(grok).to include("username" => "kares")
|
77
|
+
expect(grok).to include("password" => "-")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "generates the user_agent field" do
|
82
|
+
if ecs_compatibility?
|
83
|
+
expect(grok).to include("user_agent" => { "original" => "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36" })
|
84
|
+
else
|
85
|
+
expect(grok).to include("user_agent" => "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
it "generates the request_body_len/response_body_len fields" do
|
90
|
+
if ecs_compatibility?
|
91
|
+
expect(grok).to include("http" => hash_including("request" => hash_including("body" => { "bytes" => 223 })))
|
92
|
+
expect(grok).to include("http" => hash_including("response" => hash_including("body" => { "bytes" => 1859 })))
|
93
|
+
else
|
94
|
+
expect(grok).to include("request_body_len" => "223")
|
95
|
+
expect(grok).to include("response_body_len" => "1859")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
it "generates the status_ fields" do
|
100
|
+
if ecs_compatibility?
|
101
|
+
expect(grok).to include("http" => hash_including("response" => hash_including("status_code" => 200)))
|
102
|
+
expect(grok).to include("zeek" => hash_including("http" => hash_including("status_msg" => "OK")))
|
103
|
+
else
|
104
|
+
expect(grok).to include("status_code" => "200", "status_msg" => "OK")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "generates the info_ fields" do
|
109
|
+
if ecs_compatibility?
|
110
|
+
expect(grok['zeek']['http'].keys).to_not include("info_code", "info_msg")
|
111
|
+
else
|
112
|
+
expect(grok).to include("info_code" => "-", "info_msg" => "-")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
it "generates the filename field" do
|
117
|
+
if ecs_compatibility?
|
118
|
+
expect(grok['zeek']['http'].keys).to_not include("filename")
|
119
|
+
else
|
120
|
+
expect(grok).to include("filename" => "-")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
it "generates the bro_tags field" do
|
125
|
+
if ecs_compatibility?
|
126
|
+
expect(grok['zeek']['http'].keys).to_not include("tags")
|
127
|
+
else
|
128
|
+
expect(grok).to include("bro_tags" => "(empty)")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
it "generates the proxied field" do
|
133
|
+
if ecs_compatibility?
|
134
|
+
expect(grok['zeek']['http'].keys).to_not include("proxied")
|
135
|
+
else
|
136
|
+
expect(grok).to include("proxied" => "-")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
it "generates the orig_ fields" do
|
141
|
+
if ecs_compatibility?
|
142
|
+
expect(grok).to include("zeek" => hash_including("http" => hash_including("orig_fuids" => "FrLEcY3AUPKdcYGf29")))
|
143
|
+
expect(grok).to include("http" => hash_including("request" => hash_including("mime_type" => "text/plain")))
|
144
|
+
else
|
145
|
+
expect(grok).to include("orig_fuids" => "FrLEcY3AUPKdcYGf29")
|
146
|
+
expect(grok).to include("orig_mime_types" => "text/plain")
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
it "generates the resp_ fields" do
|
151
|
+
if ecs_compatibility?
|
152
|
+
expect(grok).to include("zeek" => hash_including("http" => hash_including("resp_fuids" => "FOJpbGzIMh9syPxH8")))
|
153
|
+
expect(grok).to include("http" => hash_including("response" => hash_including("mime_type" => "text/plain")))
|
154
|
+
else
|
155
|
+
expect(grok).to include("resp_fuids" => "FOJpbGzIMh9syPxH8")
|
156
|
+
expect(grok).to include("resp_mime_types" => "text/plain")
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context '(zeek) updated log format' do
|
161
|
+
|
162
|
+
let(:message) do # ZEEK
|
163
|
+
'1602164975.587600 Ct73QY3M7T5dikxggf 192.168.122.59 55240 93.184.220.29 80 1 - - - - 1.1 - - 0 471 200 OK - - (empty) - - - - - - FPGXN33wAFL8MPKJXl - application/ocsp-response'
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'matches in legacy mode' do
|
167
|
+
unless ecs_compatibility? # wrong but backwards compatibility
|
168
|
+
expect(grok).to include("domain" => "1.1") # due GREEDYDATA: "method" => "-\t-\t-\t-"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'no longer matches in ecs mode' do
|
173
|
+
expect(grok['tags']).to include("_grokparsefailure") if ecs_compatibility?
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
describe_pattern "ZEEK_HTTP", ['ecs-v1'] do
|
181
|
+
|
182
|
+
context "long message" do
|
183
|
+
|
184
|
+
let(:message) do
|
185
|
+
"1333458850.375568 ClEkJM2Vm5giqnMf4h 10.131.47.185 1923 79.101.110.141 80 1 GET o-o.preferred.telekomrs-beg1.v2.lscache8.c.youtube.com /videoplayback?upn=MTU2MDY5NzQ5OTM0NTI3NDY4NDc&sparams=algorithm,burst,cp,factor,id,ip,ipbits,itag,source,upn,expire&fexp=912300,907210&algorithm=throttle-factor&itag=34&ip=212.0.0.0&burst=40&sver=3&signature=832FB1042E20780CFCA77A4DB5EA64AC593E8627.D1166C7E8365732E52DAFD68076DAE0146E0AE01&source=youtube&expire=1333484980&key=yt1&ipbits=8&factor=1.25&cp=U0hSSFRTUl9NSkNOMl9MTVZKOjh5eEN2SG8tZF84&id=ebf1e932d4bd1286&cm2=1 http://s.ytimg.com/yt/swfbin/watch_as3-vflqrJwOA.swf 1.1 Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko; X-SBLSP) Chrome/17.0.963.83 Safari/535.11 - 0 56320 206 Partial Content - - (empty) - - - - - - FpmJd62pFQcZ3gcUgl - -"
|
186
|
+
end
|
187
|
+
|
188
|
+
it "matches" do
|
189
|
+
expect(grok).to include("timestamp"=>"1333458850.375568")
|
190
|
+
expect(grok).to include("zeek" => hash_including("session_id"=>"ClEkJM2Vm5giqnMf4h"))
|
191
|
+
expect(grok).to include("http" => {
|
192
|
+
"response" => { "body" =>{ "bytes" => 56320 }, "status_code"=>206 },
|
193
|
+
"request" => { "body" => { "bytes" => 0 }, "referrer"=>"http://s.ytimg.com/yt/swfbin/watch_as3-vflqrJwOA.swf", "method"=>"GET"},
|
194
|
+
"version"=>"1.1"
|
195
|
+
})
|
196
|
+
expect(grok).to include("user_agent"=>{"original"=>"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko; X-SBLSP) Chrome/17.0.963.83 Safari/535.11"})
|
197
|
+
expect(grok).to include("url"=>{
|
198
|
+
"domain"=>"o-o.preferred.telekomrs-beg1.v2.lscache8.c.youtube.com",
|
199
|
+
"original"=>"/videoplayback?upn=MTU2MDY5NzQ5OTM0NTI3NDY4NDc&sparams=algorithm,burst,cp,factor,id,ip,ipbits,itag,source,upn,expire&fexp=912300,907210&algorithm=throttle-factor&itag=34&ip=212.0.0.0&burst=40&sver=3&signature=832FB1042E20780CFCA77A4DB5EA64AC593E8627.D1166C7E8365732E52DAFD68076DAE0146E0AE01&source=youtube&expire=1333484980&key=yt1&ipbits=8&factor=1.25&cp=U0hSSFRTUl9NSkNOMl9MTVZKOjh5eEN2SG8tZF84&id=ebf1e932d4bd1286&cm2=1"
|
200
|
+
})
|
201
|
+
expect(grok).to include("destination"=>{"port"=>80, "ip"=>"79.101.110.141"}, "source"=>{"port"=>1923, "ip"=>"10.131.47.185"})
|
202
|
+
expect(grok).to include("zeek" => hash_including("http"=>{"resp_fuids"=>"FpmJd62pFQcZ3gcUgl", "status_msg"=>"Partial Content", "trans_depth"=>1}))
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
context "sample message" do
|
208
|
+
|
209
|
+
let(:message) do
|
210
|
+
"1602165002.455618 CWGOypTfRypTC5C4g 192.168.122.59 44136 216.58.201.110 80 1 - - - - 1.1 Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0 https://example.com 0 219 301 Moved Permanently - - FOO,BAR - - - - - - FeJ7iiVorMXoLlRK - text/html"
|
211
|
+
end
|
212
|
+
|
213
|
+
it "matches" do
|
214
|
+
expect(grok).to include("timestamp"=>"1602165002.455618")
|
215
|
+
expect(grok).to include("user_agent"=>{"original"=>"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0"})
|
216
|
+
expect(grok).to include("http" => {
|
217
|
+
"request" => { "body" => {"bytes" => 0 } },
|
218
|
+
"response" => { "status_code" => 301, "body" =>{ "bytes" => 219 }, "mime_type" => 'text/html' },
|
219
|
+
"version"=>"1.1"
|
220
|
+
})
|
221
|
+
expect(grok).to include("zeek" => {
|
222
|
+
"session_id" => "CWGOypTfRypTC5C4g",
|
223
|
+
"http" => {
|
224
|
+
"trans_depth"=>1,
|
225
|
+
"origin"=>"https://example.com",
|
226
|
+
"tags"=>"FOO,BAR",
|
227
|
+
"status_msg"=>"Moved Permanently",
|
228
|
+
"resp_fuids"=>"FeJ7iiVorMXoLlRK"}
|
229
|
+
})
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
context 'old (bro) message' do
|
235
|
+
|
236
|
+
let(:message) do
|
237
|
+
"1432555199.633017 COpk6E3vkURP8QQNKl 192.168.9.35 55281 178.236.7.146 80 4 POST www.amazon.it /xa/dealcontent/v2/GetDeals?nocache=1432555199326 http://www.amazon.it/ Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 223 1859 200 OK - - - (empty) kares - - FrLEcY3AUPKdcYGf29 text/plain FOJpbGzIMh9syPxH8 text/plain"
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'does not match' do
|
241
|
+
expect(grok['tags']).to include("_grokparsefailure") if ecs_compatibility?
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
context 'old empty (bro) message' do
|
247
|
+
|
248
|
+
let(:message) do # theoretically everything except these is optional:
|
249
|
+
"1432555199.633017 COpk6E3vkURP8QQNKl 192.168.9.35 55281 178.236.7.146 80 0 - - - - - - - - - - - - (empty) - - - - - - -"
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'does not match' do
|
253
|
+
expect(grok['tags']).to include("_grokparsefailure") if ecs_compatibility?
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
describe_pattern 'BRO_DNS', ['legacy', 'ecs-v1'] do
|
261
|
+
|
262
|
+
let(:message) do # old BRO logging format
|
263
|
+
"1359565680.761790 UWkUyAuUGXf 192.168.6.10 53209 192.168.129.36 53 udp 41477 paypal.com 1 C_INTERNET 48 DNSKEY 0 NOERROR F F T F 1 - - F"
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'matches' do
|
267
|
+
if ecs_compatibility?
|
268
|
+
expect(grok).to include("timestamp" => "1359565680.761790")
|
269
|
+
expect(grok).to include("zeek" => hash_including("session_id" => "UWkUyAuUGXf"))
|
270
|
+
expect(grok).to include("source" => { "ip"=>"192.168.6.10", "port"=>53209 }, "destination" => { "ip"=>"192.168.129.36", "port"=>53 })
|
271
|
+
expect(grok).to include("network" => { "transport" => "udp" })
|
272
|
+
expect(grok).to include("dns" => {
|
273
|
+
"id" => 41477,
|
274
|
+
"question" => { "name" => "paypal.com", "type" => "DNSKEY" },
|
275
|
+
"response_code" => "NOERROR",
|
276
|
+
})
|
277
|
+
expect(grok['zeek']).to include("dns" => hash_including("qclass" => 1, "qclass_name" => "C_INTERNET"))
|
278
|
+
expect(grok['zeek']).to include("dns" => hash_including("qtype" => 48)) # beats compatibility
|
279
|
+
expect(grok['zeek']).to include("dns" => hash_including("rcode" => 0)) # beats compatibility
|
280
|
+
# TODO :bool type-casting would be nice
|
281
|
+
expect(grok['zeek']).to include("dns" => hash_including("AA"=>"F", "TC"=>"F", "RD"=>"T", "RA"=>"F"))
|
282
|
+
expect(grok['zeek']).to include("dns" => hash_including("Z" => 1)) # beats drops this field
|
283
|
+
expect(grok['zeek']).to include("dns" => hash_including("rejected" => "F"))
|
284
|
+
expect(grok['zeek']['dns'].keys).to_not include 'TTLs', 'answers'
|
285
|
+
else
|
286
|
+
expect(grok).to include(
|
287
|
+
"ts"=>"1359565680.761790", "uid"=>"UWkUyAuUGXf",
|
288
|
+
"orig_h"=>"192.168.6.10", "orig_p"=>"53209",
|
289
|
+
"resp_h" => "192.168.129.36", "resp_p"=>"53",
|
290
|
+
"proto"=>"udp",
|
291
|
+
"trans_id"=>"41477",
|
292
|
+
"query"=>"paypal.com",
|
293
|
+
"qclass"=>"1", "qclass_name"=>"C_INTERNET",
|
294
|
+
"qtype"=>"48", "qtype_name"=>"DNSKEY",
|
295
|
+
"rcode"=>"0", "rcode_name"=>"NOERROR",
|
296
|
+
"AA"=>"F", "TC"=>"F",
|
297
|
+
"RD"=>"T", "RA"=>"F",
|
298
|
+
"Z"=>"1",
|
299
|
+
"answers"=>"-",
|
300
|
+
"TTLs"=>"-",
|
301
|
+
"rejected"=>"F",
|
302
|
+
)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
context 'optional fields' do
|
307
|
+
|
308
|
+
let(:message) do
|
309
|
+
"1359565680.761790 UWkUyAuUGXf 192.168.6.10 53209 192.168.129.36 53 udp - - - - - - - - F F F F 0 - - -"
|
310
|
+
# AA/TC/RD/RA are optional with a F default, Z is optional with a 0 default
|
311
|
+
end
|
312
|
+
|
313
|
+
it 'matches (only) fields present' do
|
314
|
+
if ecs_compatibility?
|
315
|
+
expect(grok).to include("timestamp" => "1359565680.761790")
|
316
|
+
expect(grok).to include("source" => { "ip"=>"192.168.6.10", "port"=>53209 }, "destination" => { "ip"=>"192.168.129.36", "port"=>53 })
|
317
|
+
expect(grok).to include("network" => { "transport"=>"udp" })
|
318
|
+
expect(grok).to include("zeek" => { "session_id" => "UWkUyAuUGXf", "dns" => { "AA"=>"F", "TC"=>"F", "RD"=>"F", "RA"=>"F", "Z"=>0 } })
|
319
|
+
expect(grok.keys).to_not include('dns')
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
end
|
324
|
+
|
325
|
+
context '(zeek) updated log format' do
|
326
|
+
|
327
|
+
let(:message) do
|
328
|
+
"1359565680.761790 CHhAvVGS1DHFjwGM9 192.168.6.10 53209 192.168.129.36 53 udp 41477 0.075138 paypal.com 1 C_INTERNET 48 DNSKEY 0 NOERROR F F T T 1 DNSKEY 5,DNSKEY 5,RRSIG 48 paypal.com,RRSIG 48 paypal.com 455.000000,455.000000,455.000000,455.000000 F"
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'no longer matches in ecs mode' do
|
332
|
+
expect(grok['tags']).to include("_grokparsefailure") if ecs_compatibility?
|
333
|
+
end
|
334
|
+
|
335
|
+
end
|
336
|
+
|
337
|
+
end
|
338
|
+
|
339
|
+
describe_pattern "ZEEK_DNS", ['ecs-v1'] do
|
340
|
+
|
341
|
+
let(:message) do
|
342
|
+
"1359565680.761790 CHhAvVGS1DHFjwGM9 192.168.6.10 53209 192.168.129.36 53 udp 41477 0.075138 paypal.com 1 C_INTERNET 48 DNSKEY 0 NOERROR F F T T 1 DNSKEY 5,DNSKEY 5,RRSIG 48 paypal.com,RRSIG 48 paypal.com 455.000000,455.000000,455.000000,455.000000 F"
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'matches' do
|
346
|
+
expect(grok).to include("timestamp" => "1359565680.761790")
|
347
|
+
expect(grok).to include("destination"=>{"ip"=>"192.168.129.36", "port"=>53}, "source"=>{"ip"=>"192.168.6.10", "port"=>53209})
|
348
|
+
expect(grok).to include("network" => {"transport"=>"udp"})
|
349
|
+
expect(grok).to include("dns"=>{"question"=>{"type"=>"DNSKEY", "name"=>"paypal.com"}, "response_code"=>"NOERROR", "id"=>41477})
|
350
|
+
expect(grok).to include("zeek"=>{
|
351
|
+
"session_id"=>"CHhAvVGS1DHFjwGM9",
|
352
|
+
"dns"=>{
|
353
|
+
"rtt" => 0.075138 ,
|
354
|
+
"qclass"=>1, "qclass_name"=>"C_INTERNET", "qtype"=>48,
|
355
|
+
"rcode"=>0,
|
356
|
+
"RA"=>"T", "RD"=>"T", "TC"=>"F", "rejected"=>"F", "AA"=>"F", "Z"=>1,
|
357
|
+
"answers"=>"DNSKEY 5,DNSKEY 5,RRSIG 48 paypal.com,RRSIG 48 paypal.com",
|
358
|
+
"TTLs"=>"455.000000,455.000000,455.000000,455.000000"
|
359
|
+
}
|
360
|
+
})
|
361
|
+
end
|
362
|
+
|
363
|
+
end
|
364
|
+
|
365
|
+
describe_pattern 'BRO_CONN', ['legacy', 'ecs-v1'] do
|
366
|
+
|
367
|
+
let(:message) do
|
368
|
+
"1541350796.901974 C54zqz17PXuBv3HkLg 192.168.0.26 54855 54.85.115.89 443 tcp ssl 0.153642 1147 589 SF T 0 ShADadfF 7 1439 8 921 (empty)"
|
369
|
+
end
|
370
|
+
|
371
|
+
it 'matches' do
|
372
|
+
if ecs_compatibility?
|
373
|
+
expect(grok).to include("timestamp"=>"1541350796.901974")
|
374
|
+
expect(grok).to include("zeek" => hash_including("session_id" => "C54zqz17PXuBv3HkLg"))
|
375
|
+
expect(grok).to include("network"=>{"transport"=>"tcp", "protocol"=>"ssl"})
|
376
|
+
expect(grok).to include("source"=>{
|
377
|
+
"ip"=>"192.168.0.26", "port"=>54855,
|
378
|
+
"packets"=>7, "bytes"=>1439
|
379
|
+
})
|
380
|
+
expect(grok).to include("destination"=>{
|
381
|
+
"ip"=>"54.85.115.89", "port"=>443,
|
382
|
+
"packets"=>8, "bytes"=>921
|
383
|
+
})
|
384
|
+
expect(grok).to include("zeek" => hash_including(
|
385
|
+
"connection" => {
|
386
|
+
"duration"=>0.153642,
|
387
|
+
"orig_bytes"=>1147, "resp_bytes"=>589,
|
388
|
+
"state"=>"SF",
|
389
|
+
"local_orig"=>"T", "missed_bytes"=>0,
|
390
|
+
"history"=>"ShADadfF",
|
391
|
+
}
|
392
|
+
))
|
393
|
+
else
|
394
|
+
expect(grok).to include(
|
395
|
+
"ts"=>"1541350796.901974", "uid"=>"C54zqz17PXuBv3HkLg",
|
396
|
+
"orig_h"=>"192.168.0.26", "orig_p"=>"54855",
|
397
|
+
"resp_h" => "54.85.115.89", "resp_p"=>"443",
|
398
|
+
"proto"=>"tcp",
|
399
|
+
"service"=>"ssl",
|
400
|
+
"duration"=>"0.153642",
|
401
|
+
"orig_bytes"=>"1147", "resp_bytes"=>"589",
|
402
|
+
"conn_state"=>"SF",
|
403
|
+
"local_orig"=>"T",
|
404
|
+
"missed_bytes"=>"0",
|
405
|
+
"history"=>"ShADadfF",
|
406
|
+
"orig_pkts"=>"7", "orig_ip_bytes"=>"1439",
|
407
|
+
"resp_pkts"=>"8", "resp_ip_bytes"=>"921",
|
408
|
+
"tunnel_parents"=>"(empty)",
|
409
|
+
)
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
context 'updated log format' do # up to version 3.3
|
414
|
+
let(:message) do
|
415
|
+
"1300475168.853899 C4J4Th3PJpwUYZZ6gc 141.142.220.118 43927 141.142.2.2 53 udp dns 0.000435 38 89 SF - - 0 Dd 1 66 1 117 (empty)"
|
416
|
+
end
|
417
|
+
|
418
|
+
it 'matches' do
|
419
|
+
if ecs_compatibility?
|
420
|
+
expect(grok).to include("zeek" => hash_including("session_id" => "C4J4Th3PJpwUYZZ6gc"))
|
421
|
+
expect(grok).to include("network"=>{"transport"=>"udp", "protocol"=>"dns"})
|
422
|
+
expect(grok).to include("source"=>{
|
423
|
+
"ip"=>"141.142.220.118", "port"=>43927,
|
424
|
+
"packets"=>1, "bytes"=>66
|
425
|
+
})
|
426
|
+
expect(grok).to include("destination"=>{
|
427
|
+
"ip"=>"141.142.2.2", "port"=>53,
|
428
|
+
"packets"=>1, "bytes"=>117
|
429
|
+
})
|
430
|
+
expect(grok).to include("zeek" => hash_including(
|
431
|
+
"connection" => {
|
432
|
+
"duration"=>0.000435,
|
433
|
+
"orig_bytes"=>38, "resp_bytes"=>89,
|
434
|
+
"state"=>"SF",
|
435
|
+
"missed_bytes"=>0,
|
436
|
+
"history"=>"Dd",
|
437
|
+
}
|
438
|
+
))
|
439
|
+
else
|
440
|
+
expect(grok).to include("ts"=>"1300475168.853899")
|
441
|
+
expect(grok).to include("conn_state"=>"SF\t-") # matches incorrectly
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
end
|
447
|
+
|
448
|
+
describe_pattern 'ZEEK_CONN', ['ecs-v1'] do
|
449
|
+
|
450
|
+
let(:message) do
|
451
|
+
"1602165198.216970 CfVl4yNLJ4U3ptL12 192.168.122.59 47340 143.204.201.102 443 tcp - 115.669583 0 6238 SHR T F 0 ^hCadcCfA 1 52 21 5091 -"
|
452
|
+
end
|
453
|
+
|
454
|
+
it 'matches' do
|
455
|
+
expect(grok).to include("timestamp" => "1602165198.216970")
|
456
|
+
expect(grok).to include("network" => { "transport" => "tcp" })
|
457
|
+
expect(grok).to include("source" => { "ip"=>"192.168.122.59", "port"=>47340, "packets"=>1, "bytes"=>52 })
|
458
|
+
expect(grok).to include("destination" => { "ip"=>"143.204.201.102", "port"=>443, "packets"=>21, "bytes"=>5091 })
|
459
|
+
|
460
|
+
expect(grok).to include("zeek"=>{
|
461
|
+
"connection"=>{
|
462
|
+
"duration"=>115.669583,
|
463
|
+
"orig_bytes"=>0,
|
464
|
+
"resp_bytes"=>6238,
|
465
|
+
"state"=>"SHR",
|
466
|
+
"local_orig"=>"T",
|
467
|
+
"local_resp"=>"F",
|
468
|
+
"missed_bytes"=>0,
|
469
|
+
"history"=>"^hCadcCfA"
|
470
|
+
},
|
471
|
+
"session_id"=>"CfVl4yNLJ4U3ptL12"
|
472
|
+
})
|
473
|
+
end
|
474
|
+
|
475
|
+
context 'with mac adresses' do
|
476
|
+
|
477
|
+
let(:message) do
|
478
|
+
"1128727435.633408 CHhAvVGS1DHFjwGM9 141.42.64.125 56730 125.190.109.199 80 tcp http 1.550793 98 9417 SF - - 0 ^hADdFaf 11 670 10 9945 - 00:d0:03:3b:f4:00 00:b0:c2:86:ec:00"
|
479
|
+
end
|
480
|
+
|
481
|
+
it 'matches' do
|
482
|
+
expect(grok).to include("timestamp" => "1128727435.633408")
|
483
|
+
expect(grok).to include("zeek" => hash_including("session_id" => "CHhAvVGS1DHFjwGM9"))
|
484
|
+
expect(grok).to include("network" => { "transport" => "tcp", "protocol" => "http" })
|
485
|
+
expect(grok).to include("source" => { "mac"=>"00:d0:03:3b:f4:00", "ip"=>"141.42.64.125", "port"=>56730, "packets"=>11, "bytes"=>670 })
|
486
|
+
expect(grok).to include("destination" => { "mac"=>"00:b0:c2:86:ec:00", "ip"=>"125.190.109.199", "port"=>80, "packets"=>10, "bytes"=>9945 })
|
487
|
+
|
488
|
+
expect(grok).to include("zeek"=>hash_including("connection" => hash_including("duration"=>1.550793)))
|
489
|
+
end
|
490
|
+
|
491
|
+
end
|
492
|
+
|
493
|
+
end
|
494
|
+
|
495
|
+
describe_pattern 'BRO_FILES', ['legacy', 'ecs-v1'] do
|
496
|
+
|
497
|
+
let(:message) do
|
498
|
+
"1362692527.009512 FakNcS1Jfe01uljb3 192.150.187.43 141.142.228.5 CXWv6p3arKYeMETxOg HTTP 0 MD5,SHA1 text/plain - 0.000263 - F 4705 4705 0 0 F - 397168fd09991a0e712254df7bc639ac 1dd7ac0398df6cbc0696445a91ec681facf4dc47 - -"
|
499
|
+
end
|
500
|
+
|
501
|
+
it 'matches' do
|
502
|
+
if ecs_compatibility?
|
503
|
+
expect(grok).to include("timestamp"=>"1362692527.009512")
|
504
|
+
expect(grok).to include("server"=>{"ip"=>"192.150.187.43"})
|
505
|
+
expect(grok).to include("client"=>{"ip"=>"141.142.228.5"})
|
506
|
+
expect(grok).to include("zeek"=>{ "files" => {
|
507
|
+
"fuid"=>"FakNcS1Jfe01uljb3",
|
508
|
+
"session_ids"=>"CXWv6p3arKYeMETxOg",
|
509
|
+
"source"=>"HTTP", "depth"=>0, "analyzers"=>"MD5,SHA1",
|
510
|
+
"duration"=>0.000263,
|
511
|
+
"is_orig"=>"F",
|
512
|
+
"overflow_bytes"=>0, "missing_bytes"=>0, "seen_bytes"=>4705,
|
513
|
+
"timedout"=>"F"
|
514
|
+
}})
|
515
|
+
expect(grok).to include("file"=>{
|
516
|
+
"size"=>4705, "mime_type"=>"text/plain",
|
517
|
+
"hash"=>{"sha1"=>"1dd7ac0398df6cbc0696445a91ec681facf4dc47", "md5"=>"397168fd09991a0e712254df7bc639ac"}
|
518
|
+
})
|
519
|
+
else
|
520
|
+
expect(grok).to include("ts"=>"1362692527.009512", "fuid"=>"FakNcS1Jfe01uljb3")
|
521
|
+
expect(grok).to include("tx_hosts"=>"192.150.187.43", "rx_hosts"=>"141.142.228.5")
|
522
|
+
expect(grok).to include("conn_uids"=>"CXWv6p3arKYeMETxOg")
|
523
|
+
expect(grok).to include("source"=>"HTTP", "depth"=>"0", "analyzers"=>"MD5,SHA1", "mime_type"=>"text/plain")
|
524
|
+
expect(grok).to include("filename"=>"-")
|
525
|
+
expect(grok).to include("duration"=>"0.000263")
|
526
|
+
expect(grok).to include("local_orig"=>"-", "is_orig"=>"F",
|
527
|
+
"seen_bytes"=>"4705", "total_bytes"=>"4705", "missing_bytes"=>"0", "overflow_bytes"=>"0",
|
528
|
+
"timedout"=>"F",
|
529
|
+
"parent_fuid"=>"-",
|
530
|
+
"md5"=>"397168fd09991a0e712254df7bc639ac", "sha1"=>"1dd7ac0398df6cbc0696445a91ec681facf4dc47", "sha256"=>"-",
|
531
|
+
"extracted"=>"-"
|
532
|
+
)
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
context 'new (zeek) message format' do
|
537
|
+
|
538
|
+
let(:message) do
|
539
|
+
"1602576142.884704 Frp9wcpqbDl991Zh7 151.101.112.204 192.168.122.59 C3v3ce39xvI63Tn2E5 HTTP 0 SHA1,MD5 text/plain - 0.000000 F F 3707 51901 0 0 F - 995875a72487a52a657b94e3857ac4fe 00c45f6771d0006029a8ced68bf2a41ca3060e69 - - - -"
|
540
|
+
end
|
541
|
+
|
542
|
+
it 'matches (incorrectly) in legacy mode' do
|
543
|
+
unless ecs_compatibility?
|
544
|
+
expect(grok).to include("ts"=>"1602576142.884704", "fuid"=>"Frp9wcpqbDl991Zh7")
|
545
|
+
expect(grok).to include("source"=>"HTTP\t0\tSHA1,MD5") # BOGUS
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
it '~~does not match in ecs mode~~ matches (correctly) in ECS mode' do # since new format changes are additions at the end
|
550
|
+
if ecs_compatibility?
|
551
|
+
expect(grok).to include("timestamp"=>"1602576142.884704")
|
552
|
+
expect(grok).to include("server"=>{"ip"=>"151.101.112.204"})
|
553
|
+
expect(grok).to include("client"=>{"ip"=>"192.168.122.59"})
|
554
|
+
expect(grok).to include("zeek"=>{"files"=>{
|
555
|
+
"fuid"=>"Frp9wcpqbDl991Zh7",
|
556
|
+
"session_ids"=>"C3v3ce39xvI63Tn2E5",
|
557
|
+
"source"=>"HTTP", "depth"=>0, "analyzers"=>"SHA1,MD5",
|
558
|
+
"duration"=>0.0,
|
559
|
+
"local_orig"=>"F", "is_orig"=>"F",
|
560
|
+
"missing_bytes"=>0,
|
561
|
+
"timedout"=>"F",
|
562
|
+
"overflow_bytes"=>0, "seen_bytes"=>3707
|
563
|
+
}})
|
564
|
+
expect(grok).to include("file"=>{
|
565
|
+
"size"=>51901, "mime_type"=>"text/plain",
|
566
|
+
"hash"=>{"md5"=>"995875a72487a52a657b94e3857ac4fe", "sha1"=>"00c45f6771d0006029a8ced68bf2a41ca3060e69"}
|
567
|
+
})
|
568
|
+
end
|
569
|
+
end
|
570
|
+
|
571
|
+
end
|
572
|
+
|
573
|
+
end
|
574
|
+
|
575
|
+
describe_pattern 'ZEEK_FILES', ['ecs-v1'] do
|
576
|
+
|
577
|
+
let(:message) do
|
578
|
+
"1258867934.558264 F2xow8TIkvHG4Zz41 198.189.255.75 192.168.1.105 CHhAvVGS1DHFjwGM9 HTTP 0 EXTRACT - - 0.046240 - F 54229 605292323 4244449 0 T - - - - extract-1258867934.558264-HTTP-F2xow8TIkvHG4Zz41 T 4000"
|
579
|
+
end
|
580
|
+
|
581
|
+
it 'matches' do
|
582
|
+
expect(grok).to include("timestamp"=>"1258867934.558264")
|
583
|
+
expect(grok).to include("server"=>{"ip"=>'198.189.255.75'}) # tx_host
|
584
|
+
expect(grok).to include("client"=>{"ip"=>'192.168.1.105'}) # rx_host
|
585
|
+
expect(grok).to include("zeek"=>{"files"=>hash_including(
|
586
|
+
"fuid"=>"F2xow8TIkvHG4Zz41",
|
587
|
+
"session_ids"=>"CHhAvVGS1DHFjwGM9",
|
588
|
+
"source"=>"HTTP", "analyzers"=>"EXTRACT",
|
589
|
+
"timedout"=>"T",
|
590
|
+
|
591
|
+
"extracted"=>"extract-1258867934.558264-HTTP-F2xow8TIkvHG4Zz41",
|
592
|
+
"extracted_size"=>4000, "extracted_cutoff"=>"T"
|
593
|
+
)})
|
594
|
+
expect(grok).to include("file"=>{"size"=>605292323})
|
595
|
+
end
|
596
|
+
|
597
|
+
context 'multiple hosts' do
|
598
|
+
|
599
|
+
let(:message) do
|
600
|
+
# NOTE: Zeek sometimes treats set[ip/string] types as ',' separated other times as ' ' separated
|
601
|
+
"1258867934.558264 F2xow8TIkvHG4Zz41 10.1.1.2 10.1.1.1 192.168.1.105,192.168.1.10,192.168.1.11 - - 0 - - - 0.01234 - F - - - 0 T - - - - - - -"
|
602
|
+
end
|
603
|
+
|
604
|
+
it 'matches host(s)' do
|
605
|
+
expect(grok).to include("server"=>{"ip" => '10.1.1.2'}) # tx_host
|
606
|
+
expect(grok).to include("client"=>{"ip" => '192.168.1.105'}) # rx_host
|
607
|
+
expect(grok).to include("zeek"=>{"files" => hash_including("tx_hosts" => '10.1.1.2 10.1.1.1')})
|
608
|
+
expect(grok).to include("zeek"=>{"files" => hash_including("rx_hosts" => '192.168.1.105,192.168.1.10,192.168.1.11')})
|
609
|
+
end
|
610
|
+
|
611
|
+
end
|
612
|
+
|
613
|
+
end
|