logstash-patterns-core 4.0.1 → 4.2.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 +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
|