logstash-patterns-core 4.0.1 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +54 -8
- data/CONTRIBUTORS +2 -0
- data/Gemfile +8 -1
- data/LICENSE +199 -10
- data/README.md +1 -1
- data/logstash-patterns-core.gemspec +2 -2
- data/patterns/aws +3 -0
- data/patterns/bind +3 -0
- data/patterns/firewalls +6 -1
- data/patterns/grok-patterns +8 -14
- data/patterns/haproxy +1 -1
- data/patterns/httpd +15 -0
- data/patterns/java +3 -6
- data/patterns/linux-syslog +1 -1
- data/patterns/maven +1 -0
- data/patterns/nagios +1 -1
- data/patterns/redis +1 -1
- data/patterns/squid +4 -0
- data/spec/patterns/core_spec.rb +311 -11
- data/spec/patterns/firewalls_spec.rb +31 -0
- data/spec/patterns/haproxy_spec.rb +17 -0
- data/spec/patterns/httpd_spec.rb +169 -9
- data/spec/patterns/java_spec.rb +45 -0
- data/spec/patterns/maven_spec.rb +61 -0
- data/spec/patterns/nagios_spec.rb +5 -1
- data/spec/patterns/redis_spec.rb +171 -0
- data/spec/patterns/s3_spec.rb +41 -0
- data/spec/patterns/syslog_spec.rb +14 -0
- data/spec/spec_helper.rb +8 -4
- metadata +26 -8
data/patterns/haproxy
CHANGED
@@ -31,7 +31,7 @@ HAPROXYCAPTUREDRESPONSEHEADERS %{DATA:captured_response_headers}
|
|
31
31
|
# HAPROXYCAPTUREDRESPONSEHEADERS %{DATA:response_header_content_type}\|%{DATA:response_header_content_encoding}\|%{DATA:response_header_cache_control}\|%{DATA:response_header_last_modified}
|
32
32
|
|
33
33
|
# parse a haproxy 'httplog' line
|
34
|
-
HAPROXYHTTPBASE %{IP:client_ip}:%{INT:client_port} \[%{HAPROXYDATE:accept_date}\] %{NOTSPACE:frontend_name} %{NOTSPACE:backend_name}/%{NOTSPACE:server_name} %{INT:time_request}/%{INT:time_queue}/%{INT:time_backend_connect}/%{INT:time_backend_response}/%{NOTSPACE:time_duration} %{INT:http_status_code} %{NOTSPACE:bytes_read} %{DATA:captured_request_cookie} %{DATA:captured_response_cookie} %{NOTSPACE:termination_state} %{INT:actconn}/%{INT:feconn}/%{INT:beconn}/%{INT:srvconn}/%{NOTSPACE:retries} %{INT:srv_queue}/%{INT:backend_queue} (\{%{HAPROXYCAPTUREDREQUESTHEADERS}\})?( )?(\{%{HAPROXYCAPTUREDRESPONSEHEADERS}\})?( )?"(<BADREQ>|(%{WORD:http_verb} (%{URIPROTO:http_proto}://)?(?:%{USER:http_user}(?::[^@]*)?@)?(?:%{URIHOST:http_host})?(?:%{URIPATHPARAM:http_request})?( HTTP/%{NUMBER:http_version})?))?"
|
34
|
+
HAPROXYHTTPBASE %{IP:client_ip}:%{INT:client_port} \[%{HAPROXYDATE:accept_date}\] %{NOTSPACE:frontend_name} %{NOTSPACE:backend_name}/%{NOTSPACE:server_name} %{INT:time_request}/%{INT:time_queue}/%{INT:time_backend_connect}/%{INT:time_backend_response}/%{NOTSPACE:time_duration} %{INT:http_status_code} %{NOTSPACE:bytes_read} %{DATA:captured_request_cookie} %{DATA:captured_response_cookie} %{NOTSPACE:termination_state} %{INT:actconn}/%{INT:feconn}/%{INT:beconn}/%{INT:srvconn}/%{NOTSPACE:retries} %{INT:srv_queue}/%{INT:backend_queue} (\{%{HAPROXYCAPTUREDREQUESTHEADERS}\})?( )?(\{%{HAPROXYCAPTUREDRESPONSEHEADERS}\})?( )?"(<BADREQ>|(%{WORD:http_verb} (%{URIPROTO:http_proto}://)?(?:%{USER:http_user}(?::[^@]*)?@)?(?:%{URIHOST:http_host})?(?:%{URIPATHPARAM:http_request})?( HTTP/%{NUMBER:http_version})?))?"?
|
35
35
|
|
36
36
|
HAPROXYHTTP (?:%{SYSLOGTIMESTAMP:syslog_timestamp}|%{TIMESTAMP_ISO8601:timestamp8601}) %{IPORHOST:syslog_server} %{SYSLOGPROG}: %{HAPROXYHTTPBASE}
|
37
37
|
|
data/patterns/httpd
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
HTTPDUSER %{EMAILADDRESS}|%{USER}
|
2
|
+
HTTPDERROR_DATE %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{YEAR}
|
3
|
+
|
4
|
+
# Log formats
|
5
|
+
HTTPD_COMMONLOG %{IPORHOST:clientip} %{HTTPDUSER:ident} %{HTTPDUSER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" (?:-|%{NUMBER:response}) (?:-|%{NUMBER:bytes})
|
6
|
+
HTTPD_COMBINEDLOG %{HTTPD_COMMONLOG} %{QS:referrer} %{QS:agent}
|
7
|
+
|
8
|
+
# Error logs
|
9
|
+
HTTPD20_ERRORLOG \[%{HTTPDERROR_DATE:timestamp}\] \[%{LOGLEVEL:loglevel}\] (?:\[client %{IPORHOST:clientip}\] ){0,1}%{GREEDYDATA:message}
|
10
|
+
HTTPD24_ERRORLOG \[%{HTTPDERROR_DATE:timestamp}\] \[%{WORD:module}:%{LOGLEVEL:loglevel}\] \[pid %{POSINT:pid}(:tid %{NUMBER:tid})?\]( \(%{POSINT:proxy_errorcode}\)%{DATA:proxy_message}:)?( \[client %{IPORHOST:clientip}:%{POSINT:clientport}\])?( %{DATA:errorcode}:)? %{GREEDYDATA:message}
|
11
|
+
HTTPD_ERRORLOG %{HTTPD20_ERRORLOG}|%{HTTPD24_ERRORLOG}
|
12
|
+
|
13
|
+
# Deprecated
|
14
|
+
COMMONAPACHELOG %{HTTPD_COMMONLOG}
|
15
|
+
COMBINEDAPACHELOG %{HTTPD_COMBINEDLOG}
|
data/patterns/java
CHANGED
@@ -1,15 +1,12 @@
|
|
1
1
|
JAVACLASS (?:[a-zA-Z$_][a-zA-Z$_0-9]*\.)*[a-zA-Z$_][a-zA-Z$_0-9]*
|
2
2
|
#Space is an allowed character to match special cases like 'Native Method' or 'Unknown Source'
|
3
|
-
JAVAFILE (?:[
|
4
|
-
#Allow special <init>
|
5
|
-
JAVAMETHOD (?:(<init>)|[a-zA-Z$_][a-zA-Z$_0-9]*)
|
3
|
+
JAVAFILE (?:[a-zA-Z$_0-9. -]+)
|
4
|
+
#Allow special <init>, <clinit> methods
|
5
|
+
JAVAMETHOD (?:(<(?:cl)?init>)|[a-zA-Z$_][a-zA-Z$_0-9]*)
|
6
6
|
#Line number is optional in special cases 'Native method' or 'Unknown source'
|
7
7
|
JAVASTACKTRACEPART %{SPACE}at %{JAVACLASS:class}\.%{JAVAMETHOD:method}\(%{JAVAFILE:file}(?::%{NUMBER:line})?\)
|
8
8
|
# Java Logs
|
9
9
|
JAVATHREAD (?:[A-Z]{2}-Processor[\d]+)
|
10
|
-
JAVACLASS (?:[a-zA-Z0-9-]+\.)+[A-Za-z0-9$]+
|
11
|
-
JAVAFILE (?:[A-Za-z0-9_.-]+)
|
12
|
-
JAVASTACKTRACEPART at %{JAVACLASS:class}\.%{WORD:method}\(%{JAVAFILE:file}:%{NUMBER:line}\)
|
13
10
|
JAVALOGMESSAGE (.*)
|
14
11
|
# MMM dd, yyyy HH:mm:ss eg: Jan 9, 2014 7:13:13 AM
|
15
12
|
CATALINA_DATESTAMP %{MONTH} %{MONTHDAY}, 20%{YEAR} %{HOUR}:?%{MINUTE}(?::?%{SECOND}) (?:AM|PM)
|
data/patterns/linux-syslog
CHANGED
@@ -11,6 +11,6 @@ SYSLOGLINE %{SYSLOGBASE2} %{GREEDYDATA:message}
|
|
11
11
|
# IETF 5424 syslog(8) format (see http://www.rfc-editor.org/info/rfc5424)
|
12
12
|
SYSLOG5424PRI <%{NONNEGINT:syslog5424_pri}>
|
13
13
|
SYSLOG5424SD \[%{DATA}\]+
|
14
|
-
SYSLOG5424BASE %{SYSLOG5424PRI}%{NONNEGINT:syslog5424_ver} +(?:%{TIMESTAMP_ISO8601:syslog5424_ts}|-) +(?:%{
|
14
|
+
SYSLOG5424BASE %{SYSLOG5424PRI}%{NONNEGINT:syslog5424_ver} +(?:%{TIMESTAMP_ISO8601:syslog5424_ts}|-) +(?:%{IPORHOST:syslog5424_host}|-) +(-|%{SYSLOG5424PRINTASCII:syslog5424_app}) +(-|%{SYSLOG5424PRINTASCII:syslog5424_proc}) +(-|%{SYSLOG5424PRINTASCII:syslog5424_msgid}) +(?:%{SYSLOG5424SD:syslog5424_sd}|-|)
|
15
15
|
|
16
16
|
SYSLOG5424LINE %{SYSLOG5424BASE} +%{GREEDYDATA:syslog5424_msg}
|
data/patterns/maven
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
MAVEN_VERSION (?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)(?:[.-](RELEASE|SNAPSHOT))?
|
data/patterns/nagios
CHANGED
@@ -89,7 +89,7 @@ NAGIOS_PASSIVE_HOST_CHECK %{NAGIOS_TYPE_PASSIVE_HOST_CHECK:nagios_type}: %{DATA:
|
|
89
89
|
NAGIOS_SERVICE_EVENT_HANDLER %{NAGIOS_TYPE_SERVICE_EVENT_HANDLER:nagios_type}: %{DATA:nagios_hostname};%{DATA:nagios_service};%{DATA:nagios_state};%{DATA:nagios_statelevel};%{DATA:nagios_event_handler_name}
|
90
90
|
NAGIOS_HOST_EVENT_HANDLER %{NAGIOS_TYPE_HOST_EVENT_HANDLER:nagios_type}: %{DATA:nagios_hostname};%{DATA:nagios_state};%{DATA:nagios_statelevel};%{DATA:nagios_event_handler_name}
|
91
91
|
|
92
|
-
NAGIOS_TIMEPERIOD_TRANSITION %{NAGIOS_TYPE_TIMEPERIOD_TRANSITION:nagios_type}: %{DATA:nagios_service};%{
|
92
|
+
NAGIOS_TIMEPERIOD_TRANSITION %{NAGIOS_TYPE_TIMEPERIOD_TRANSITION:nagios_type}: %{DATA:nagios_service};%{NUMBER:nagios_unknown1};%{NUMBER:nagios_unknown2}
|
93
93
|
|
94
94
|
####################
|
95
95
|
#### External checks
|
data/patterns/redis
CHANGED
data/patterns/squid
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
# Pattern squid3
|
2
|
+
# Documentation of squid3 logs formats can be found at the following link:
|
3
|
+
# http://wiki.squid-cache.org/Features/LogFormat
|
4
|
+
SQUID3 %{NUMBER:timestamp}\s+%{NUMBER:duration}\s%{IP:client_address}\s%{WORD:cache_result}/%{POSINT:status_code}\s%{NUMBER:bytes}\s%{WORD:request_method}\s%{NOTSPACE:url}\s(%{NOTSPACE:user}|-)\s%{WORD:hierarchy_code}/%{IPORHOST:server}\s%{NOTSPACE:content_type}
|
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
|
@@ -73,6 +63,19 @@ describe "TOMCATLOG" do
|
|
73
63
|
end
|
74
64
|
end
|
75
65
|
|
66
|
+
describe 'LOGLEVEL' do
|
67
|
+
it 'matches info label' do
|
68
|
+
expect(grok_match(subject, 'INFO')).to pass
|
69
|
+
expect(grok_match(subject, 'info')).to pass
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'matches information label' do
|
73
|
+
expect(grok_match(subject, 'information')).to pass
|
74
|
+
expect(grok_match(subject, 'Information')).to pass
|
75
|
+
expect(grok_match(subject, 'INFORMATION')).to pass
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
76
79
|
describe "IPORHOST" do
|
77
80
|
|
78
81
|
let(:pattern) { "IPORHOST" }
|
@@ -100,14 +103,224 @@ describe "UNIXPATH" do
|
|
100
103
|
let(:value) { '/foo/bar' }
|
101
104
|
|
102
105
|
it "should match the path" do
|
103
|
-
expect(grok_match(pattern,value)).to pass
|
106
|
+
expect(grok_match(pattern, value, true)).to pass
|
104
107
|
end
|
105
108
|
|
106
109
|
context "when using comma separators and other regexp" do
|
107
110
|
|
111
|
+
let(:pattern) { '((a=(?<a>%{UNIXPATH})?|b=(?<b>%{UNIXPATH})?)(,\s)?)+' }
|
112
|
+
|
113
|
+
let(:grok) do
|
114
|
+
grok = LogStash::Filters::Grok.new("match" => ["message", pattern])
|
115
|
+
grok.register
|
116
|
+
grok
|
117
|
+
end
|
118
|
+
|
108
119
|
let(:value) { 'a=/some/path, b=/some/other/path' }
|
109
120
|
|
121
|
+
it "was expected to extract both but never really did" do # or maybe on JRuby 1.7
|
122
|
+
event = build_event(value)
|
123
|
+
grok.filter(event)
|
124
|
+
expect( event.to_hash['a'] ).to eql '/some/path,'
|
125
|
+
expect( event.to_hash['b'] ).to be nil
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'relative path' do
|
131
|
+
|
132
|
+
let(:path_matcher) do # non-exact matcher
|
133
|
+
grok = LogStash::Filters::Grok.new("match" => ["message", '%{UNIXPATH:path}'])
|
134
|
+
grok.register
|
135
|
+
lambda { |msg| event = build_event(msg); grok.filter(event); event }
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should not match (only partially)" do
|
139
|
+
expect(grok_match(pattern, 'a/./b/c', true)).to_not pass
|
140
|
+
event = path_matcher.('a/./b/c')
|
141
|
+
expect( event.to_hash['path'] ).to eql '/./b/c'
|
142
|
+
|
143
|
+
expect(grok_match(pattern, ',/.', true)).to_not pass
|
144
|
+
event = path_matcher.(',/.')
|
145
|
+
expect( event.to_hash['path'] ).to eql '/.'
|
146
|
+
|
147
|
+
expect(grok_match(pattern, '+/.../', true)).to_not pass
|
148
|
+
event = path_matcher.('+/.../')
|
149
|
+
expect( event.to_hash['path'] ).to eql '/.../'
|
150
|
+
|
151
|
+
expect(grok_match(pattern, '~/b/', true)).to_not pass
|
152
|
+
event = path_matcher.('~/b/')
|
153
|
+
expect( event.to_hash['path'] ).to eql '/b/'
|
154
|
+
|
155
|
+
expect(grok_match(pattern, './b//', true)).to_not pass
|
156
|
+
expect(grok_match(pattern, 'a//b', true)).to_not pass
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should not match paths starting with ." do
|
160
|
+
expect(grok_match(pattern, '../0', true)).to_not pass
|
161
|
+
expect(grok_match(pattern, './~', true)).to_not pass
|
162
|
+
expect(grok_match(pattern, '.../-', true)).to_not pass
|
163
|
+
expect(grok_match(pattern, './', true)).to_not pass
|
164
|
+
expect(grok_match(pattern, './,', true)).to_not pass
|
165
|
+
expect(grok_match(pattern, '../', true)).to_not pass
|
166
|
+
expect(grok_match(pattern, '.a/', true)).to_not pass
|
167
|
+
expect(grok_match(pattern, '.~/', true)).to_not pass
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should not match expression wout separator" do
|
171
|
+
expect(grok_match(pattern, '.')).to_not pass
|
172
|
+
expect(grok_match(pattern, '..')).to_not pass
|
173
|
+
expect(grok_match(pattern, '...')).to_not pass
|
174
|
+
expect(grok_match(pattern, '.,')).to_not pass
|
175
|
+
expect(grok_match(pattern, '.-')).to_not pass
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
context "dotted path" do
|
181
|
+
|
182
|
+
it "should match path containing ." do
|
183
|
+
expect(grok_match(pattern, '/some/./path/', true)).to pass
|
184
|
+
expect(grok_match(pattern, '/some/../path', true)).to pass
|
185
|
+
expect(grok_match(pattern, '/../.', true)).to pass
|
186
|
+
expect(grok_match(pattern, '/.', true)).to pass
|
187
|
+
expect(grok_match(pattern, '/..', true)).to pass
|
188
|
+
expect(grok_match(pattern, '/...', true)).to pass
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
context "separators" do
|
194
|
+
|
195
|
+
it "should match root" do
|
196
|
+
expect(grok_match(pattern, '/', true)).to pass
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should match" do
|
200
|
+
expect(grok_match(pattern, '//', true)).to pass
|
201
|
+
expect(grok_match(pattern, '//00', true)).to pass
|
202
|
+
expect(grok_match(pattern, '///a', true)).to pass
|
203
|
+
expect(grok_match(pattern, '/a//', true)).to pass
|
204
|
+
expect(grok_match(pattern, '///a//b/c///', true)).to pass
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should not match windows separator" do
|
208
|
+
expect(grok_match(pattern, "\\a", true)).to_not pass
|
209
|
+
expect(grok_match(pattern, '/0\\', true)).to_not pass
|
210
|
+
expect(grok_match(pattern, "/a\\b", true)).to_not pass
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
context "long path" do
|
216
|
+
|
217
|
+
let(:grok) do
|
218
|
+
grok = LogStash::Filters::Grok.new("match" => ["message", '%{UNIXPATH:path} '], 'timeout_millis' => 1500)
|
219
|
+
grok.register
|
220
|
+
grok
|
221
|
+
end
|
222
|
+
|
223
|
+
let(:value) { '/opt/abcdef/1/.22/3:3+3/foo@BAR/X-Y+Z/~Sample_l_SUBc b' }
|
224
|
+
|
110
225
|
it "should match the path" do
|
226
|
+
event = build_event(value)
|
227
|
+
grok.filter(event)
|
228
|
+
expect( event.to_hash['path'] ).to eql '/opt/abcdef/1/.22/3:3+3/foo@BAR/X-Y+Z/~Sample_l_SUBc'
|
229
|
+
end
|
230
|
+
|
231
|
+
it "should not match with invalid chars (or cause DoS)" do
|
232
|
+
event = build_event(value.sub('SUB', '&^_'))
|
233
|
+
grok.filter(event) # used to call a looong looop (DoS) despite the timeout guard
|
234
|
+
expect( event.to_hash['tags'] ).to include '_grokparsefailure'
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
it "matches paths with non-ascii characters" do
|
239
|
+
event = build_event path = '/opt/Čierný_Peter/.中'
|
240
|
+
build_grok('UNIXPATH:path').filter event
|
241
|
+
expect( event.get('path') ).to eql path
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "WINPATH" do
|
247
|
+
|
248
|
+
let(:pattern) { 'WINPATH' }
|
249
|
+
let(:value) { 'C:\\foo\\bar' }
|
250
|
+
|
251
|
+
it "should match the path" do
|
252
|
+
expect(grok_match(pattern, value, true)).to pass
|
253
|
+
end
|
254
|
+
|
255
|
+
it "should match root path" do
|
256
|
+
expect(grok_match(pattern, 'C:\\', true)).to pass
|
257
|
+
expect(grok_match(pattern, 'C:\\\\', true)).to pass
|
258
|
+
expect(grok_match(pattern, 'a:\\', true)).to pass
|
259
|
+
expect(grok_match(pattern, 'x:\\\\', true)).to pass
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should match paths with spaces" do
|
263
|
+
expect(grok_match(pattern, 'C:\\Documents and Settings\\Public', true)).to pass
|
264
|
+
expect(grok_match(pattern, 'C:\\\\Users\\\\Public\\\\.Mozilla Firefox', true)).to pass
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should not match unix-style paths" do
|
268
|
+
expect(grok_match(pattern, '/foo', true)).to_not pass
|
269
|
+
expect(grok_match(pattern, '//C/path', true)).to_not pass
|
270
|
+
expect(grok_match(pattern, '/', true)).to_not pass
|
271
|
+
expect(grok_match(pattern, '/foo/bar', true)).to_not pass
|
272
|
+
expect(grok_match(pattern, '/..', true)).to_not pass
|
273
|
+
expect(grok_match(pattern, 'C://', true)).to_not pass
|
274
|
+
end
|
275
|
+
|
276
|
+
it "matches paths with non-ascii characters" do
|
277
|
+
expect(grok_match(pattern, 'C:\\Čierný Peter\\.中.exe', true)).to pass
|
278
|
+
end
|
279
|
+
|
280
|
+
context 'relative paths' do
|
281
|
+
|
282
|
+
it "should not match" do
|
283
|
+
expect(grok_match(pattern, 'a\\bar', true)).to_not pass
|
284
|
+
expect(grok_match(pattern, 'foo\\bar', true)).to_not pass
|
285
|
+
expect(grok_match(pattern, 'C\\A\\B', true)).to_not pass
|
286
|
+
expect(grok_match(pattern, 'C\\\\0', true)).to_not pass
|
287
|
+
expect(grok_match(pattern, '.\\0', true)).to_not pass
|
288
|
+
expect(grok_match(pattern, '..\\', true)).to_not pass
|
289
|
+
expect(grok_match(pattern, '...\\-', true)).to_not pass
|
290
|
+
expect(grok_match(pattern, '.\\', true)).to_not pass
|
291
|
+
expect(grok_match(pattern, '.\\,', true)).to_not pass
|
292
|
+
expect(grok_match(pattern, '..\\', true)).to_not pass
|
293
|
+
expect(grok_match(pattern, '.a\\', true)).to_not pass
|
294
|
+
end
|
295
|
+
|
296
|
+
it "should not match expression wout separator" do
|
297
|
+
expect(grok_match(pattern, '.')).to_not pass
|
298
|
+
expect(grok_match(pattern, '..')).to_not pass
|
299
|
+
expect(grok_match(pattern, '...')).to_not pass
|
300
|
+
expect(grok_match(pattern, 'C:')).to_not pass
|
301
|
+
expect(grok_match(pattern, 'C')).to_not pass
|
302
|
+
end
|
303
|
+
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
307
|
+
|
308
|
+
|
309
|
+
describe "URIPROTO" do
|
310
|
+
let(:pattern) { 'URIPROTO' }
|
311
|
+
|
312
|
+
context "http is a valid URIPROTO" do
|
313
|
+
let(:value) { 'http' }
|
314
|
+
|
315
|
+
it "should match" do
|
316
|
+
expect(grok_match(pattern,value)).to pass
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
context "android-app is a valid URIPROTO" do
|
321
|
+
let(:value) { 'android-app' }
|
322
|
+
|
323
|
+
it "should match" do
|
111
324
|
expect(grok_match(pattern,value)).to pass
|
112
325
|
end
|
113
326
|
end
|
@@ -193,5 +406,92 @@ describe "IPV4" do
|
|
193
406
|
expect(grok_match(pattern,value)).not_to pass
|
194
407
|
end
|
195
408
|
end
|
409
|
+
end
|
410
|
+
|
411
|
+
describe "URN" do
|
412
|
+
|
413
|
+
let(:pattern) { "URN" }
|
414
|
+
|
415
|
+
# Valid URNs
|
416
|
+
# http://tools.ietf.org/html/rfc2141#section-2
|
417
|
+
let(:simple) { "urn:example:foo" }
|
418
|
+
let(:unreserved) { "urn:example:" +
|
419
|
+
[*'A'..'Z', *'a'..'z', *'0'..'9', "()+,-.::=@;$_!*'"].join() }
|
420
|
+
let(:reserved) { "urn:example:/#?" }
|
421
|
+
let(:escaped_upper) { "urn:example:%25foo%2Fbar%3F%23" }
|
422
|
+
let(:escaped_lower) { "urn:example:%25foo%2fbar%3f%23" }
|
423
|
+
let(:only_escaped) { "urn:example:%00" }
|
424
|
+
let(:long_nid) { "urn:example-example-example-example-:foo" }
|
425
|
+
|
426
|
+
# Invalid URNs
|
427
|
+
let(:bad_prefix) { "URN:example:foo" }
|
428
|
+
let(:empty_nid) { "urn::foo" }
|
429
|
+
let(:leading_hyphen) { "urn:-example:foo" }
|
430
|
+
let(:bad_nid) { "urn:example.com:foo" }
|
431
|
+
let(:percent_nid) { "urn:example%41com:foo" }
|
432
|
+
let(:too_long_nid) { "urn:example-example-example-example-x:foo" }
|
433
|
+
let(:empty_nss) { "urn:example:" }
|
434
|
+
let(:naked_percent) { "urn:example:%" }
|
435
|
+
let(:short_percent) { "urn:example:%a" }
|
436
|
+
let(:nonhex_percent) { "urn:example:%ax" }
|
437
|
+
|
438
|
+
context "when testing a valid URN" do
|
439
|
+
it "should match a simple URN" do
|
440
|
+
expect(grok_match(pattern, simple)).to pass
|
441
|
+
end
|
442
|
+
|
443
|
+
it "should match a complex URN" do
|
444
|
+
expect(grok_match(pattern, unreserved)).to pass
|
445
|
+
end
|
446
|
+
|
447
|
+
it "should allow reserved characters" do
|
448
|
+
expect(grok_match(pattern, reserved)).to pass
|
449
|
+
end
|
450
|
+
|
451
|
+
it "should allow percent-escapes" do
|
452
|
+
expect(grok_match(pattern, escaped_upper)).to pass
|
453
|
+
expect(grok_match(pattern, escaped_lower)).to pass
|
454
|
+
expect(grok_match(pattern, only_escaped)).to pass
|
455
|
+
end
|
456
|
+
|
457
|
+
it "should match a URN with a 32-character NID" do
|
458
|
+
expect(grok_match(pattern, long_nid)).to pass
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
context "when testing an invalid URN" do
|
463
|
+
it "should reject capitalized 'URN'" do
|
464
|
+
expect(grok_match(pattern, bad_prefix)).not_to pass
|
465
|
+
end
|
196
466
|
|
467
|
+
it "should reject an empty NID" do
|
468
|
+
expect(grok_match(pattern, empty_nid)).not_to pass
|
469
|
+
end
|
470
|
+
|
471
|
+
it "should reject an NID with a leading hyphen" do
|
472
|
+
expect(grok_match(pattern, leading_hyphen)).not_to pass
|
473
|
+
end
|
474
|
+
|
475
|
+
it "should reject an NID with a special character" do
|
476
|
+
expect(grok_match(pattern, bad_nid)).not_to pass
|
477
|
+
end
|
478
|
+
|
479
|
+
it "should reject an NID with a percent sign" do
|
480
|
+
expect(grok_match(pattern, percent_nid)).not_to pass
|
481
|
+
end
|
482
|
+
|
483
|
+
it "should reject an NID longer than 32 characters" do
|
484
|
+
expect(grok_match(pattern, too_long_nid)).not_to pass
|
485
|
+
end
|
486
|
+
|
487
|
+
it "should reject a URN with an empty NSS" do
|
488
|
+
expect(grok_match(pattern, empty_nss)).not_to pass
|
489
|
+
end
|
490
|
+
|
491
|
+
it "should reject non-escape percent signs" do
|
492
|
+
expect(grok_match(pattern, naked_percent)).not_to pass
|
493
|
+
expect(grok_match(pattern, short_percent)).not_to pass
|
494
|
+
expect(grok_match(pattern, nonhex_percent)).not_to pass
|
495
|
+
end
|
496
|
+
end
|
197
497
|
end
|
@@ -19,6 +19,21 @@ describe "FIREWALLS" do
|
|
19
19
|
expect(subject["message"]).to include("(Secondary) Switching to ACTIVE - Service card in other unit has failed")
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
let(:pattern106015) { "CISCOFW106015" }
|
24
|
+
|
25
|
+
context "parsing a 106015 message" do
|
26
|
+
|
27
|
+
let(:value) { "Deny TCP (no connection) from 192.168.150.65/2278 to 64.101.128.83/80 flags RST on interface inside" }
|
28
|
+
|
29
|
+
subject { grok_match(pattern106015, value) }
|
30
|
+
|
31
|
+
it { should include("interface" => "inside") }
|
32
|
+
|
33
|
+
it "generates a message field" do
|
34
|
+
expect(subject["message"]).to include("Deny TCP (no connection) from 192.168.150.65/2278 to 64.101.128.83/80 flags RST on interface inside")
|
35
|
+
end
|
36
|
+
end
|
22
37
|
|
23
38
|
let(:pattern106100) { "CISCOFW106100" }
|
24
39
|
|
@@ -50,6 +65,22 @@ describe "FIREWALLS" do
|
|
50
65
|
end
|
51
66
|
end
|
52
67
|
|
68
|
+
let(:pattern304001) { "CISCOFW304001" }
|
69
|
+
|
70
|
+
context "parsing a 304001 message" do
|
71
|
+
|
72
|
+
let(:value) { "10.20.30.40(DOMAIN\\login) Accessed URL 10.11.12.13:http://example.org/" }
|
73
|
+
|
74
|
+
subject { grok_match(pattern304001, value) }
|
75
|
+
|
76
|
+
it 'should break the message up into fields' do
|
77
|
+
expect(subject['src_ip']).to eq('10.20.30.40')
|
78
|
+
expect(subject['src_fwuser']).to eq('DOMAIN\\login')
|
79
|
+
expect(subject['dst_ip']).to eq('10.11.12.13')
|
80
|
+
expect(subject['dst_url']).to eq('http://example.org/')
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
53
84
|
let(:pattern106023) { "CISCOFW106023" }
|
54
85
|
|
55
86
|
context "parsing a 106023 message" do
|