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
data/spec/patterns/core_spec.rb
CHANGED
@@ -54,15 +54,6 @@ describe "HTTP DATE parsing" do
|
|
54
54
|
|
55
55
|
end
|
56
56
|
|
57
|
-
describe "TOMCATLOG" do
|
58
|
-
|
59
|
-
let(:value) { '2014-01-09 20:03:28,269 -0800 | ERROR | com.example.service.ExampleService - something compeletely unexpected happened...'}
|
60
|
-
|
61
|
-
it "generates the logmessage field" do
|
62
|
-
expect(grok_match(subject, value)).to include("logmessage" => "something compeletely unexpected happened...")
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
57
|
describe 'LOGLEVEL' do
|
67
58
|
it 'matches info label' do
|
68
59
|
expect(grok_match(subject, 'INFO')).to pass
|
@@ -495,3 +486,54 @@ describe "URN" do
|
|
495
486
|
end
|
496
487
|
end
|
497
488
|
end
|
489
|
+
|
490
|
+
describe_pattern "EMAILADDRESS", ['legacy', 'ecs-v1'] do
|
491
|
+
|
492
|
+
# NOTE: EMAILLOCALPART was only updated in ECS mode, as following the RFC is
|
493
|
+
# actually a breaking change -> legacy does match incorrect e-mail addresses.
|
494
|
+
|
495
|
+
it "matches 'hello.world@123.net' address" do
|
496
|
+
expect(grok_exact_match(pattern, 'hello.world@123.net')).to pass
|
497
|
+
end
|
498
|
+
|
499
|
+
[
|
500
|
+
'a@example.com',
|
501
|
+
'a{b}@example.com',
|
502
|
+
'Foo+Bar@x.exposed',
|
503
|
+
].each do |valid_email|
|
504
|
+
it "matches #{valid_email.inspect} address" do
|
505
|
+
expect(grok_exact_match(pattern, valid_email)).to pass if ecs_compatibility?
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
it "does not match 'x y@example.com' address" do
|
510
|
+
expect(grok_exact_match(pattern, 'hello.world@123.net')).to pass
|
511
|
+
end
|
512
|
+
|
513
|
+
[
|
514
|
+
'a:b@example.com',
|
515
|
+
'a..b@example.com',
|
516
|
+
].each do |invalid_email|
|
517
|
+
it "does not match #{invalid_email.inspect} address" do
|
518
|
+
expect(grok_exact_match(pattern, invalid_email)).to_not pass if ecs_compatibility?
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
it "matches e-mail with digits only local-part" do
|
523
|
+
expect(grok_exact_match(pattern, '00@q.ro')).to pass if ecs_compatibility?
|
524
|
+
end
|
525
|
+
|
526
|
+
it "matches e-mail with 64 chars in local-part" do
|
527
|
+
expect(grok_exact_match(pattern, ('ab' * 32) + '@root.cz')).to pass
|
528
|
+
expect(grok_exact_match(pattern, ('a.bc' * 16) + '@00.cz')).to pass
|
529
|
+
end
|
530
|
+
|
531
|
+
it "does not match e-mail with more than 64 char length local-part" do
|
532
|
+
if ecs_compatibility?
|
533
|
+
expect(grok_exact_match(pattern, ('ab' * 32) + 'a' + '@root.cz')).to_not pass
|
534
|
+
# NOTE: we allow longer with '.' but at least we limit "too long" :
|
535
|
+
expect(grok_exact_match(pattern, ('a.bc' * 64) + '@00.cz')).to_not pass
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
require "logstash/patterns/core"
|
4
|
+
|
5
|
+
describe_pattern 'EXIM', ['legacy', 'ecs-v1'] do
|
6
|
+
|
7
|
+
context 'message arrival (old)' do
|
8
|
+
|
9
|
+
let(:message) do
|
10
|
+
"1995-10-31 08:57:53 0tACW1-0005MB-00 <= kryten@dwarf.fict.example H=mailer.fict.example [192.168.123.123] " +
|
11
|
+
"U=exim P=smtp S=5678 id=f828ca60127d8646a0fa75cbf8db9ba3@dwarf.fict.example"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "matches" do
|
15
|
+
expect(grok).to include("timestamp" => "1995-10-31 08:57:53")
|
16
|
+
|
17
|
+
if ecs_compatibility?
|
18
|
+
expect(grok).to include("exim"=>{"log"=>{
|
19
|
+
"flags"=>"<=",
|
20
|
+
"sender"=>{"email"=>"kryten@dwarf.fict.example"},
|
21
|
+
"message"=>{"id"=>"0tACW1-0005MB-00", "size"=>5678},
|
22
|
+
"header_id"=>"f828ca60127d8646a0fa75cbf8db9ba3@dwarf.fict.example"
|
23
|
+
}})
|
24
|
+
expect(grok).to include("source"=>{"address"=>"mailer.fict.example", "ip"=>"192.168.123.123"})
|
25
|
+
expect(grok).to include("network"=>{"protocol"=>"smtp"})
|
26
|
+
else
|
27
|
+
expect(grok).to include("exim_year" => "1995", "exim_month" => "10", "exim_day" => "31", "@version" => "1", "exim_time" => "08:57:53")
|
28
|
+
expect(grok.keys).to_not include("pid")
|
29
|
+
expect(grok).to include("exim_sender_email" => "kryten@dwarf.fict.example")
|
30
|
+
expect(grok).to include("exim_flags" => "<=")
|
31
|
+
expect(grok).to include("exim_msg_size" => "5678")
|
32
|
+
expect(grok).to include("exim_msgid" => "0tACW1-0005MB-00")
|
33
|
+
expect(grok).to include("remote_hostname" => "mailer.fict.example", "remote_host" => "192.168.123.123")
|
34
|
+
expect(grok).to include("protocol" => "smtp")
|
35
|
+
expect(grok).to include("exim_header_id" => "f828ca60127d8646a0fa75cbf8db9ba3@dwarf.fict.example")
|
36
|
+
end
|
37
|
+
|
38
|
+
expect(grok).to include("message" => message)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'message arrival (new)' do
|
44
|
+
let(:message) do
|
45
|
+
'2010-09-13 05:00:13 [1487] 1Ov4tU-0000Nz-Rm <= mailling.list@domain.com ' +
|
46
|
+
'H=mailhost.domain.com [208.42.54.2]:51792 I=[67.215.162.175]:25 P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=21778 ' +
|
47
|
+
'id=384a86a39e83be0d9b3a94d1feb3119f@domain.com T="Daily List: Chameleon" for user@example.com'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "matches" do
|
51
|
+
expect(grok).to include("timestamp" => "2010-09-13 05:00:13") # new in legacy mode
|
52
|
+
|
53
|
+
if ecs_compatibility?
|
54
|
+
expect(grok).to include("process"=>{"pid"=>1487})
|
55
|
+
expect(grok).to include("exim"=>{"log"=>hash_including(
|
56
|
+
"message"=>{"id"=>"1Ov4tU-0000Nz-Rm", "size"=>21778, "subject"=>"Daily List: Chameleon"},
|
57
|
+
"flags"=>"<=",
|
58
|
+
"header_id"=>"384a86a39e83be0d9b3a94d1feb3119f@domain.com",
|
59
|
+
"sender"=>{"email"=>"mailling.list@domain.com"},
|
60
|
+
"recipient"=>{"email"=>"user@example.com"},
|
61
|
+
)})
|
62
|
+
expect(grok).to include("source"=>{"address"=>"mailhost.domain.com", "ip"=>"208.42.54.2", "port"=>51792})
|
63
|
+
expect(grok).to include("destination"=>{"ip"=>"67.215.162.175", "port"=>25})
|
64
|
+
else
|
65
|
+
|
66
|
+
expect(grok).to include("exim_year" => "2010", "exim_month" => "09", "exim_day" => "13", "exim_time" => "05:00:13")
|
67
|
+
expect(grok).to include("pid" => "1487") # new
|
68
|
+
expect(grok).to include("exim_sender_email" => "mailling.list@domain.com") # new
|
69
|
+
expect(grok).to include("remote_hostname" => "mailhost.domain.com", "remote_host" => "208.42.54.2", "remote_port" => "51792") # (remote_port) new
|
70
|
+
expect(grok).to include("exim_interface" => "67.215.162.175", "exim_interface_port" => "25")
|
71
|
+
expect(grok).to include("protocol" => "esmtps")
|
72
|
+
expect(grok).to include("exim_msg_size" => "21778")
|
73
|
+
expect(grok).to include("exim_header_id" => "384a86a39e83be0d9b3a94d1feb3119f@domain.com")
|
74
|
+
expect(grok).to include("exim_subject" => '"Daily List: Chameleon"')
|
75
|
+
expect(grok).to include("exim_recipient_email" => "user@example.com") # new
|
76
|
+
end
|
77
|
+
|
78
|
+
expect(grok).to include("message" => message)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'message arrival (simple)' do
|
84
|
+
|
85
|
+
let(:message) do
|
86
|
+
'2020-02-11 17:09:46 1j1Z2g-00Faoy-Uh <= example@strawberry.active-ns.com U=example P=local ' +
|
87
|
+
'T="[Examples Galore] Please moderate: \"Hello world!\"" for admin@example.net'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "matches" do
|
91
|
+
expect(grok).to include("timestamp"=>"2020-02-11 17:09:46")
|
92
|
+
if ecs_compatibility?
|
93
|
+
expect(grok).to include("exim"=>{"log"=>{
|
94
|
+
"flags"=>"<=",
|
95
|
+
"message"=>{"id"=>"1j1Z2g-00Faoy-Uh", "subject"=>'[Examples Galore] Please moderate: \\"Hello world!\\"'},
|
96
|
+
"sender"=>{"email"=>"example@strawberry.active-ns.com"},
|
97
|
+
"recipient"=>{"email"=>"admin@example.net"}
|
98
|
+
}})
|
99
|
+
expect(grok).to include("network"=>{"protocol"=>"local"})
|
100
|
+
else
|
101
|
+
expect(grok).to include(
|
102
|
+
"exim_msgid"=>"1j1Z2g-00Faoy-Uh",
|
103
|
+
"exim_sender_email"=>"example@strawberry.active-ns.com",
|
104
|
+
"exim_flags"=>"<=",
|
105
|
+
"protocol"=>"local",
|
106
|
+
"exim_subject"=>"\"[Examples Galore] Please moderate: \\\"Hello world!\\\"\""
|
107
|
+
)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'message arrival with quoted hostname' do
|
114
|
+
|
115
|
+
let(:message) do
|
116
|
+
'2013-03-20 12:44:02 1UIIN7-0004t9-8R <= root@example.com ' +
|
117
|
+
'H=localhost (hostname.example.com) [127.0.0.1] ' +
|
118
|
+
'P=esmtps X=TLSv1:DHE-RSA-AES256-SHA:256 S=811 id=201303201244.r2KCi11V018784@hostname.example.com'
|
119
|
+
end
|
120
|
+
|
121
|
+
it "matches" do
|
122
|
+
expect(grok).to include("timestamp"=>"2013-03-20 12:44:02")
|
123
|
+
|
124
|
+
if ecs_compatibility?
|
125
|
+
expect(grok).to include("exim"=>{"log"=>hash_including(
|
126
|
+
"sender"=>{ "email"=>"root@example.com" },
|
127
|
+
"message"=>{ "id"=>"1UIIN7-0004t9-8R", "size"=>811 },
|
128
|
+
"header_id"=>"201303201244.r2KCi11V018784@hostname.example.com",
|
129
|
+
"remote_address"=>"hostname.example.com")})
|
130
|
+
expect(grok).to include("source"=>{"address"=>"localhost", "ip"=>"127.0.0.1"})
|
131
|
+
expect(grok).to include("network"=>{"protocol"=>"esmtps"})
|
132
|
+
else
|
133
|
+
expect(grok).to include(
|
134
|
+
"exim_msgid"=>"1UIIN7-0004t9-8R",
|
135
|
+
"exim_sender_email"=>"root@example.com",
|
136
|
+
"exim_flags"=>"<=",
|
137
|
+
"protocol"=>"esmtps",
|
138
|
+
"exim_header_id"=>"201303201244.r2KCi11V018784@hostname.example.com"
|
139
|
+
)
|
140
|
+
expect(grok).to include(
|
141
|
+
"remote_host"=>"127.0.0.1",
|
142
|
+
"remote_heloname"=>"hostname.example.com",
|
143
|
+
"remote_hostname"=>"localhost"
|
144
|
+
)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
context 'message arrival with quoted hostname and port' do
|
152
|
+
|
153
|
+
let(:message) do
|
154
|
+
'2014-08-10 11:18:35 [28107] 1gsu1C-003dCu-Hb <= aaron@domain.com ' +
|
155
|
+
'H=localhost (10.5.40.204) [127.0.0.1]:39753 I=[127.0.0.1]:25 ' +
|
156
|
+
'P=esmtpa A=dovecot_plain:aaron@domain.com S=4315 M8S=0 id=d2b648f00f1a1b0813c483d552778dc6@domain.com ' +
|
157
|
+
"T=\"what's up?!? ;-)\" from <aaron@domain.com> for aaron+forward@domain.com"
|
158
|
+
end
|
159
|
+
|
160
|
+
it "matches" do
|
161
|
+
if ecs_compatibility?
|
162
|
+
expect(grok).to include("exim"=>{"log"=>hash_including(
|
163
|
+
"message"=>hash_including("id"=>"1gsu1C-003dCu-Hb", "subject"=>"what's up?!? ;-)"),
|
164
|
+
)})
|
165
|
+
expect(grok).to include("destination"=>{"ip"=>"127.0.0.1", "port"=>25})
|
166
|
+
expect(grok).to include("exim"=>{"log"=>hash_including(
|
167
|
+
"sender"=>{"email"=>"aaron@domain.com", 'original'=>'aaron@domain.com'}
|
168
|
+
)})
|
169
|
+
expect(grok).to include("exim"=>{"log"=>hash_including("recipient"=>{"email"=>"aaron+forward@domain.com"})})
|
170
|
+
expect(grok).to include("source"=>{"address"=>"localhost", "ip"=>"127.0.0.1", "port"=>39753})
|
171
|
+
expect(grok).to include("exim"=>{"log" => hash_including("remote_address"=>'10.5.40.204')})
|
172
|
+
else
|
173
|
+
expect(grok).to include(
|
174
|
+
"exim_msgid"=>"1gsu1C-003dCu-Hb",
|
175
|
+
"exim_sender_email"=>"aaron@domain.com",
|
176
|
+
"exim_flags"=>"<=",
|
177
|
+
"protocol"=>"esmtpa"
|
178
|
+
)
|
179
|
+
expect(grok).to include(
|
180
|
+
"remote_host"=>"127.0.0.1", "remote_port"=>"39753",
|
181
|
+
"remote_heloname"=>"10.5.40.204",
|
182
|
+
"remote_hostname"=>"localhost"
|
183
|
+
)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'delivery failed' do
|
190
|
+
|
191
|
+
let(:message) do
|
192
|
+
'2020-02-11 17:09:47 1j1Z2g-00Faoy-Uh ** admin@example.net R=virtual_aliases: No such person at this address.'
|
193
|
+
end
|
194
|
+
|
195
|
+
it "does not parse" do # matching not implemented
|
196
|
+
expect(grok['tags']).to include("_grokparsefailure")
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
@@ -2,94 +2,185 @@
|
|
2
2
|
require "spec_helper"
|
3
3
|
require "logstash/patterns/core"
|
4
4
|
|
5
|
-
|
5
|
+
CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES = ['event', 'cisco', 'observer', 'source', 'destination'].freeze
|
6
6
|
|
7
|
+
describe_pattern "CISCOFW104001", ['legacy', 'ecs-v1'] do
|
7
8
|
|
8
|
-
let(:
|
9
|
+
let(:message) { "(Secondary) Switching to ACTIVE - Service card in other unit has failed" }
|
9
10
|
|
10
|
-
|
11
|
+
include_examples 'top-level namespaces', ['event'], if: -> { ecs_compatibility? }
|
11
12
|
|
12
|
-
|
13
|
+
it { expect(subject).to include("switch_reason" => "Service card in other unit has failed") unless ecs_compatibility? }
|
13
14
|
|
14
|
-
|
15
|
+
it "keeps message field" do
|
16
|
+
expect(subject["message"]).to eql message
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe_pattern "CISCOFW106001", ['legacy', 'ecs-v1'] do
|
15
22
|
|
16
|
-
|
23
|
+
let(:message) { "ASA-2-106001: Inbound TCP connection denied from 192.168.2.2/43803 to 10.10.10.10/14322 flags SYN on interface out111" }
|
17
24
|
|
18
|
-
|
19
|
-
|
25
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
26
|
+
|
27
|
+
it 'matches' do
|
28
|
+
if ecs_compatibility?
|
29
|
+
expect(subject).to include "source"=>{"ip"=>"192.168.2.2", "port"=>43803}
|
30
|
+
expect(subject).to include "destination"=>{"ip"=>"10.10.10.10", "port"=>14322}
|
31
|
+
expect(subject).to include "observer"=>{"egress"=>{"interface"=>{"name"=>"out111"}}}
|
32
|
+
expect(subject).to include "cisco"=>{"asa"=>hash_including("network"=>{"transport"=>"TCP", "direction"=>"Inbound"}, "tcp_flags"=>"SYN")}
|
33
|
+
else
|
34
|
+
expect(subject).to include("src_ip"=>"192.168.2.2", "src_port"=>'43803')
|
20
35
|
end
|
21
36
|
end
|
22
|
-
|
23
|
-
let(:pattern106015) { "CISCOFW106015" }
|
24
37
|
|
25
|
-
|
38
|
+
it "keeps message field" do
|
39
|
+
expect(subject["message"]).to eql message
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
26
43
|
|
27
|
-
|
44
|
+
describe_pattern "CISCOFW106006_106007_106010", ['legacy', 'ecs-v1'] do
|
28
45
|
|
29
|
-
|
46
|
+
let(:message) { "ASA-2-106006: Deny inbound UDP from 192.168.2.2/65020 to 10.10.10.10/65021 on interface fw111" }
|
30
47
|
|
31
|
-
|
48
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
32
49
|
|
33
|
-
|
34
|
-
|
50
|
+
it 'matches' do
|
51
|
+
if ecs_compatibility?
|
52
|
+
expect(subject).to include "cisco" => {"asa"=>{"network"=>{"direction"=>"inbound", "transport"=>"UDP"}, "outcome"=>"Deny"}}
|
53
|
+
expect(subject).to include "source"=>{"ip"=>"192.168.2.2", "port"=>65020}
|
54
|
+
expect(subject).to include "destination"=>{"ip"=>"10.10.10.10", "port"=>65021}
|
55
|
+
expect(subject).to include "observer"=>{"egress"=>{"interface"=>{"name"=>"fw111"}}}
|
56
|
+
else
|
57
|
+
expect(subject).to include("src_ip"=>"192.168.2.2", "src_port"=>'65020')
|
35
58
|
end
|
36
59
|
end
|
37
60
|
|
38
|
-
|
61
|
+
it "keeps message field" do
|
62
|
+
expect(subject["message"]).to eql message
|
63
|
+
end
|
39
64
|
|
40
|
-
|
65
|
+
end
|
41
66
|
|
42
|
-
|
67
|
+
describe_pattern "CISCOFW106014", ['legacy', 'ecs-v1'] do
|
43
68
|
|
44
|
-
|
69
|
+
let(:message) { "ASA-3-106014: Deny inbound icmp src fw111:10.10.10.10 dst fw111:10.10.10.11(type 8, code 0)" }
|
45
70
|
|
46
|
-
|
71
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
47
72
|
|
48
|
-
|
49
|
-
|
73
|
+
it 'matches' do
|
74
|
+
if ecs_compatibility?
|
75
|
+
expect(subject).to include "source"=>{"ip"=>"10.10.10.10"}
|
76
|
+
expect(subject).to include "destination"=>{"ip"=>"10.10.10.11"}
|
77
|
+
expect(subject).to include "cisco"=>{"asa"=>{"outcome"=>"Deny", "network"=>{"transport"=>"icmp", "direction"=>"inbound"}, "icmp_code"=>0, "icmp_type"=>8}}
|
78
|
+
expect(subject).to include "observer"=>{"ingress"=>{"interface"=>{"name"=>"fw111"}}, "egress"=>{"interface"=>{"name"=>"fw111"}}}
|
79
|
+
else
|
80
|
+
# NOTE: does not match due expecting space: "10.10.10.11 (type 8, code 0)"
|
50
81
|
end
|
51
82
|
end
|
52
83
|
|
53
|
-
|
84
|
+
it "keeps message field" do
|
85
|
+
expect(subject["message"]).to eql message
|
86
|
+
end
|
54
87
|
|
55
|
-
|
88
|
+
end
|
56
89
|
|
57
|
-
|
90
|
+
describe_pattern "CISCOFW106015", ['legacy', 'ecs-v1'] do
|
58
91
|
|
59
|
-
|
92
|
+
let(:message) { "Deny TCP (no connection) from 192.168.150.65/2278 to 64.101.128.83/80 flags RST on interface eth0" }
|
60
93
|
|
61
|
-
|
94
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
62
95
|
|
63
|
-
|
64
|
-
|
96
|
+
it 'matches' do
|
97
|
+
if ecs_compatibility?
|
98
|
+
expect(subject).to include "observer"=>{"egress"=>{"interface"=>{"name"=>"eth0"}}}
|
99
|
+
else
|
100
|
+
expect(subject).to include("interface" => "eth0")
|
65
101
|
end
|
66
102
|
end
|
67
103
|
|
68
|
-
|
104
|
+
it "keeps message field" do
|
105
|
+
expect(subject["message"]).to eql message
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
69
109
|
|
70
|
-
|
110
|
+
describe_pattern "CISCOFW106021", ['legacy', 'ecs-v1'] do
|
71
111
|
|
72
|
-
|
112
|
+
let(:message) { "ASA-4-106021: Deny TCP reverse path check from 192.168.2.2 to 10.10.10.10 on interface fw111" }
|
73
113
|
|
74
|
-
|
114
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
75
115
|
|
76
|
-
|
77
|
-
|
78
|
-
expect(subject
|
79
|
-
expect(subject
|
80
|
-
expect(subject
|
116
|
+
it 'matches' do
|
117
|
+
if ecs_compatibility?
|
118
|
+
expect(subject).to include "source"=>{"ip"=>"192.168.2.2"}, "destination"=>{"ip"=>"10.10.10.10"}
|
119
|
+
expect(subject).to include "cisco"=>{"asa"=>{"network"=>{"transport"=>"TCP"}, "outcome"=>"Deny"}}
|
120
|
+
expect(subject).to include "observer"=>{"egress"=>{"interface"=>{"name"=>"fw111"}}}
|
121
|
+
else
|
122
|
+
expect(subject).to include("interface" => "fw111")
|
81
123
|
end
|
82
124
|
end
|
83
125
|
|
84
|
-
|
126
|
+
it "keeps message field" do
|
127
|
+
expect(subject["message"]).to eql message
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
describe_pattern "CISCOFW106100", ['legacy', 'ecs-v1'] do
|
85
133
|
|
86
|
-
|
134
|
+
let(:message) { "access-list inside permitted tcp inside/10.10.123.45(51763) -> outside/192.168.67.89(80) hit-cnt 1 first hit [0x62c4905, 0x0]" }
|
87
135
|
|
88
|
-
|
136
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
89
137
|
|
90
|
-
|
138
|
+
it 'matches' do
|
139
|
+
if ecs_compatibility?
|
140
|
+
expect(subject).to include("cisco"=>{"asa"=>hash_including("rule_name" => "inside")})
|
141
|
+
else
|
142
|
+
expect(subject).to include("policy_id" => "inside")
|
143
|
+
end
|
144
|
+
end
|
91
145
|
|
92
|
-
|
146
|
+
it "keeps message field" do
|
147
|
+
expect(subject["message"]).to eql message
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
describe_pattern "CISCOFW106100", ['legacy', 'ecs-v1'] do
|
153
|
+
|
154
|
+
let(:message) { "access-list outside-entry permitted tcp outside/10.11.12.13(54726) -> inside/192.168.17.18(80) hit-cnt 1 300-second interval [0x32b3835, 0x0]" }
|
155
|
+
|
156
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
157
|
+
|
158
|
+
it 'matches' do
|
159
|
+
if ecs_compatibility?
|
160
|
+
expect(subject).to include("cisco"=>{"asa"=>hash_including("rule_name" => "outside-entry")})
|
161
|
+
else
|
162
|
+
expect(subject).to include("policy_id" => "outside-entry")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
it "keeps message field" do
|
167
|
+
expect(subject["message"]).to eql message
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
describe_pattern "CISCOFW106023", ['legacy', 'ecs-v1'] do
|
173
|
+
|
174
|
+
let(:message) { 'Deny tcp src outside:192.168.1.1/50240 dst inside:192.168.1.2/23 by access-group "S_OUTSIDE_TO_INSIDE" [0x54c7fa80, 0x0]' }
|
175
|
+
|
176
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
177
|
+
|
178
|
+
it 'matches' do
|
179
|
+
if ecs_compatibility?
|
180
|
+
expect(subject).to include "source"=>{"ip"=>"192.168.1.1", "port"=>50240}
|
181
|
+
expect(subject).to include "observer"=>{"egress"=>{"interface"=>{"name"=>"inside"}}, "ingress"=>{"interface"=>{"name"=>"outside"}}}
|
182
|
+
expect(subject).to include "cisco"=>{"asa"=>{"outcome"=>"Deny", "network"=>{"transport"=>"tcp"}, "rule_name"=>"S_OUTSIDE_TO_INSIDE"}}
|
183
|
+
else
|
93
184
|
expect(subject['action']).to eq('Deny')
|
94
185
|
expect(subject['src_interface']).to eq('outside')
|
95
186
|
expect(subject['dst_interface']).to eq('inside')
|
@@ -100,37 +191,549 @@ describe "FIREWALLS" do
|
|
100
191
|
end
|
101
192
|
end
|
102
193
|
|
103
|
-
context "
|
194
|
+
context "a message with a protocol number" do
|
195
|
+
|
196
|
+
let(:message) { 'Deny protocol 103 src outside:192.168.1.1/50240 dst inside:192.168.1.2/23 by access-group "S_OUTSIDE_TO_INSIDE" [0x54c7fa80, 0x0]' }
|
197
|
+
|
198
|
+
it 'matches' do
|
199
|
+
if ecs_compatibility?
|
200
|
+
expect(subject).to include "destination"=>{"ip"=>"192.168.1.2", "port"=>23},
|
201
|
+
"cisco"=>{"asa"=>{"outcome"=>"Deny", "network"=>{"transport"=>"103"}, "rule_name"=>"S_OUTSIDE_TO_INSIDE"}}
|
202
|
+
else
|
203
|
+
expect(subject['action']).to eq('Deny')
|
204
|
+
expect(subject['src_interface']).to eq('outside')
|
205
|
+
expect(subject['dst_interface']).to eq('inside')
|
206
|
+
expect(subject['protocol']).to eq('103')
|
207
|
+
expect(subject['src_ip']).to eq('192.168.1.1')
|
208
|
+
expect(subject['dst_ip']).to eq('192.168.1.2')
|
209
|
+
expect(subject['policy_id']).to eq('S_OUTSIDE_TO_INSIDE')
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
104
213
|
|
105
|
-
let(:value) { 'Deny protocol 103 src outside:192.168.1.1/50240 dst inside:192.168.1.2/23 by access-group "S_OUTSIDE_TO_INSIDE" [0x54c7fa80, 0x0]' }
|
106
214
|
|
107
|
-
|
215
|
+
context "a message with a hostname" do
|
216
|
+
|
217
|
+
let(:message) { 'Deny tcp src outside:192.168.1.1/50240 dst inside:www.example.com/23 by access-group "S_OUTSIDE_TO_INSIDE" [0x54c7fa80, 0x0]' }
|
218
|
+
|
219
|
+
it 'matches' do
|
220
|
+
if ecs_compatibility?
|
221
|
+
expect(subject).to include "destination"=>{"port"=>23, "address"=>"www.example.com"}
|
222
|
+
expect(subject).to include "source"=>{"port"=>50240, "ip"=>"192.168.1.1"}
|
223
|
+
expect(subject).to include "observer"=>{"ingress"=>{"interface"=>{"name"=>"outside"}}, "egress"=>{"interface"=>{"name"=>"inside"}}}
|
224
|
+
else
|
225
|
+
expect(subject['action']).to eq('Deny')
|
226
|
+
expect(subject['src_interface']).to eq('outside')
|
227
|
+
expect(subject['dst_interface']).to eq('inside')
|
228
|
+
expect(subject['protocol']).to eq('tcp')
|
229
|
+
expect(subject['src_ip']).to eq('192.168.1.1')
|
230
|
+
expect(subject['dst_ip']).to eq('www.example.com')
|
231
|
+
expect(subject['policy_id']).to eq('S_OUTSIDE_TO_INSIDE')
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
108
235
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
236
|
+
end
|
237
|
+
|
238
|
+
describe_pattern "CISCOFW304001", ['legacy', 'ecs-v1'] do
|
239
|
+
|
240
|
+
let(:message) { "10.20.30.40(DOMAIN\\login) Accessed URL 10.11.12.13:http://example.org/" }
|
241
|
+
|
242
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES + ['url'], if: -> { ecs_compatibility? }
|
243
|
+
|
244
|
+
it 'matches' do
|
245
|
+
if ecs_compatibility?
|
246
|
+
expect(subject).to include "source"=>{"ip"=>"10.20.30.40", "user"=>{"name"=>"DOMAIN\\login"}}
|
247
|
+
expect(subject).to include "url"=>{"original"=>"http://example.org/"}
|
248
|
+
else
|
249
|
+
expect(subject['src_ip']).to eq('10.20.30.40')
|
250
|
+
expect(subject['src_fwuser']).to eq('DOMAIN\\login')
|
251
|
+
expect(subject['dst_ip']).to eq('10.11.12.13')
|
252
|
+
expect(subject['dst_url']).to eq('http://example.org/')
|
117
253
|
end
|
118
254
|
end
|
119
255
|
|
120
|
-
|
256
|
+
end
|
257
|
+
|
258
|
+
describe_pattern "CISCOFW110002", ['legacy', 'ecs-v1'] do
|
121
259
|
|
122
|
-
|
260
|
+
let(:message) { "ASA-6-110002: Failed to locate egress interface for TCP from sourceInterfaceName:91.240.17.178/7777 to 192.168.2.2/123412" }
|
123
261
|
|
124
|
-
|
262
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
125
263
|
|
126
|
-
|
127
|
-
|
128
|
-
expect(subject
|
129
|
-
expect(subject
|
130
|
-
expect(subject
|
131
|
-
expect(subject
|
132
|
-
expect(subject
|
133
|
-
|
264
|
+
it 'matches' do
|
265
|
+
if ecs_compatibility?
|
266
|
+
expect(subject).to include "event"=>{"reason"=>"Failed to locate egress interface"}
|
267
|
+
expect(subject).to include "cisco"=>{"asa"=>{"network"=>{"transport"=>"TCP"}}}
|
268
|
+
expect(subject).to include "source"=>{"port"=>7777, "ip"=>"91.240.17.178"}
|
269
|
+
expect(subject).to include "observer"=>{"ingress"=>{"interface"=>{"name"=>"sourceInterfaceName"}}}
|
270
|
+
expect(subject).to include "destination"=>{"port"=>123412, "ip"=>"192.168.2.2"}
|
271
|
+
else
|
272
|
+
expect(subject['src_ip']).to eq('91.240.17.178')
|
273
|
+
expect(subject['dst_ip']).to eq('192.168.2.2')
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
end
|
278
|
+
|
279
|
+
describe_pattern "CISCOFW302013_302014_302015_302016", ['legacy', 'ecs-v1'] do
|
280
|
+
|
281
|
+
let(:message) { "ASA-6-302013: Built outbound TCP connection 11757 for outside:100.66.205.104/80 (100.66.205.104/80) to inside:172.31.98.44/1772 (172.31.98.44/1772)" }
|
282
|
+
|
283
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
284
|
+
|
285
|
+
it 'matches' do
|
286
|
+
if ecs_compatibility?
|
287
|
+
expect(subject).to include "source"=>{"ip"=>"100.66.205.104", "port"=>80, "nat"=>{"ip"=>"100.66.205.104", "port"=>80}}
|
288
|
+
expect(subject).to include "cisco"=>{"asa"=>{"network"=>{"direction"=>"outbound", "transport"=>"TCP"}, "outcome"=>"Built", "connection_id"=>"11757"}}
|
289
|
+
expect(subject).to include "observer"=>{"egress"=>{"interface"=>{"name"=>"inside"}}, "ingress"=>{"interface"=>{"name"=>"outside"}}}
|
290
|
+
else
|
291
|
+
expect(subject['src_ip']).to eq('100.66.205.104')
|
292
|
+
expect(subject['dst_ip']).to eq('172.31.98.44')
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
end
|
297
|
+
|
298
|
+
describe_pattern "CISCOFW302020_302021", ['legacy', 'ecs-v1'] do
|
299
|
+
|
300
|
+
let(:message) { "302020: Built inbound ICMP connection for faddr 10.137.200.251/18425 gaddr 10.137.10.1/0 laddr 10.137.10.10/0" }
|
301
|
+
|
302
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
303
|
+
|
304
|
+
it 'matches' do
|
305
|
+
if ecs_compatibility?
|
306
|
+
expect(subject).to include("cisco"=>{"asa"=>{
|
307
|
+
"outcome"=>"Built", "icmp_seq"=>18425, "network"=>{"direction"=>"inbound", "transport"=>"ICMP"}, "icmp_type"=>0
|
308
|
+
}})
|
309
|
+
expect(subject).to include("source"=>{"nat"=>{"ip"=>"10.137.10.1"}, "ip"=>"10.137.10.10"}, "destination"=>{"ip"=>"10.137.200.251"})
|
310
|
+
else
|
311
|
+
expect(subject['src_ip']).to eq('10.137.10.10')
|
312
|
+
expect(subject['dst_ip']).to eq('10.137.200.251')
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
context '302021' do
|
317
|
+
|
318
|
+
let(:message) { "6|Nov 28 2014 12:59:03|302021: Teardown ICMP connection for faddr 10.137.200.251/18425 gaddr 10.137.10.1/0 laddr 10.137.10.10/0" }
|
319
|
+
|
320
|
+
it 'matches' do
|
321
|
+
if ecs_compatibility?
|
322
|
+
expect(subject).to include "cisco"=>{"asa"=>{"outcome"=>"Teardown", "network"=>{"transport"=>"ICMP"}, "icmp_seq"=>18425, "icmp_type"=>0}}
|
323
|
+
expect(subject).to include "source"=>{"nat"=>{"ip"=>"10.137.10.1"}, "ip"=>"10.137.10.10"}, "destination"=>{"ip"=>"10.137.200.251"}
|
324
|
+
else
|
325
|
+
expect(subject['src_ip']).to eq('10.137.10.10')
|
326
|
+
expect(subject['dst_ip']).to eq('10.137.200.251')
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
end
|
331
|
+
|
332
|
+
end
|
333
|
+
|
334
|
+
describe_pattern "CISCOFW305011", ['legacy', 'ecs-v1'] do
|
335
|
+
|
336
|
+
let(:message) { "Built dynamic TCP translation from inside:172.31.98.44/1772 to outside:100.66.98.44/8256" }
|
337
|
+
|
338
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
339
|
+
|
340
|
+
it 'matches' do
|
341
|
+
if ecs_compatibility?
|
342
|
+
expect(subject).to include "source"=>{"ip"=>"172.31.98.44", "port"=>1772}
|
343
|
+
expect(subject).to include "destination"=>{"ip"=>"100.66.98.44", "port"=>8256}
|
344
|
+
expect(subject).to include "observer"=>{"ingress"=>{"interface"=>{"name"=>"inside"}}, "egress"=>{"interface"=>{"name"=>"outside"}}}
|
345
|
+
expect(subject).to include "cisco"=>{"asa"=>{"network"=>{"transport"=>"TCP"}, "outcome"=>"Built"}}
|
346
|
+
else
|
347
|
+
expect(subject['src_ip']).to eq('172.31.98.44')
|
348
|
+
expect(subject['src_xlated_ip']).to eq('100.66.98.44')
|
349
|
+
expect(subject).to include "src_xlated_interface"=>"outside", "src_interface"=>"inside"
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
end
|
354
|
+
|
355
|
+
describe_pattern "CISCOFW313001_313004_313008", ['legacy', 'ecs-v1'] do
|
356
|
+
|
357
|
+
let(:message) { "ASA-3-313001: Denied ICMP type=3, code=3 from 10.2.3.5 on interface Outside" }
|
358
|
+
|
359
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
360
|
+
|
361
|
+
it 'matches' do
|
362
|
+
if ecs_compatibility?
|
363
|
+
expect(subject).to include "source"=>{"ip"=>"10.2.3.5"}
|
364
|
+
expect(subject).to include "cisco"=>{"asa"=>{"outcome"=>"Denied", "network"=>{"transport"=>"ICMP"}, "icmp_type"=>3, "icmp_code"=>3}}
|
365
|
+
else
|
366
|
+
expect(subject['src_ip']).to eq('10.2.3.5')
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
end
|
371
|
+
|
372
|
+
describe_pattern "CISCOFW313005", ['legacy', 'ecs-v1'] do
|
373
|
+
|
374
|
+
let(:message) do
|
375
|
+
"No matching connection for ICMP error message: icmp src fw111:10.192.33.100 dst fw111:192.18.4.1 (type 3, code 3) " +
|
376
|
+
"on fw111 interface. Original IP payload: udp src 192.18.4.1/53 dst 8.8.8.8/10872."
|
377
|
+
end
|
378
|
+
|
379
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
380
|
+
|
381
|
+
it 'matches' do
|
382
|
+
if ecs_compatibility?
|
383
|
+
expect(subject).to include "event"=>{"reason"=>"No matching connection"}
|
384
|
+
expect(subject).to include "source"=>{"ip"=>"10.192.33.100"}, "destination"=>{"ip"=>"192.18.4.1"}
|
385
|
+
expect(subject).to include "observer"=>{"ingress"=>{"interface"=>{"name"=>"fw111"}}, "egress"=>{"interface"=>{"name"=>"fw111"}}}
|
386
|
+
|
387
|
+
expect(subject).to include("cisco"=>{"asa"=>{
|
388
|
+
"icmp_type"=>3, "icmp_code"=>3, "network"=>{"transport"=>"ICMP"},
|
389
|
+
"original_ip_payload"=>{
|
390
|
+
"destination"=>{"ip"=>"8.8.8.8", "port"=>10872},
|
391
|
+
"network"=>{"transport"=>"udp"},
|
392
|
+
"source"=>{"ip"=>"192.18.4.1", "port"=>53}
|
393
|
+
}
|
394
|
+
}})
|
395
|
+
else
|
396
|
+
# YAY, fails to match!
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
end
|
401
|
+
|
402
|
+
describe_pattern "CISCOFW402117", ['legacy', 'ecs-v1'] do
|
403
|
+
|
404
|
+
let(:message) do
|
405
|
+
"%ASA-4-402117: IPSEC: Received a non-IPSec packet (protocol= ICMP) from 10.5.1.127 to 192.168.6.102."
|
406
|
+
end
|
407
|
+
|
408
|
+
include_examples 'top-level namespaces', ['cisco', 'source', 'destination'], if: -> { ecs_compatibility? }
|
409
|
+
|
410
|
+
it 'matches' do
|
411
|
+
if ecs_compatibility?
|
412
|
+
expect(subject).to include("cisco"=>{"asa"=>{"network"=>{"transport"=>"ICMP", "type"=>"IPSEC"}}},
|
413
|
+
"source"=>{"ip"=>"10.5.1.127"}, "destination"=>{"ip"=>"192.168.6.102"})
|
414
|
+
|
415
|
+
else
|
416
|
+
expect(subject).to include "src_ip"=>"10.5.1.127", "orig_protocol"=>"ICMP", "protocol"=>"IPSEC", "dst_ip"=>"192.168.6.102"
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
end
|
421
|
+
|
422
|
+
describe_pattern "CISCOFW402119", ['legacy', 'ecs-v1'] do
|
423
|
+
|
424
|
+
let(:message) do
|
425
|
+
"%ASA-4-402119: IPSEC: Received an ESP packet (SPI= 0x1B86506B, sequence number= 0x28B) from 68.18.122.4 (user= Bangalo) to 10.10.1.1 that failed anti-replay checking."
|
426
|
+
end
|
427
|
+
|
428
|
+
include_examples 'top-level namespaces', ['cisco', 'source', 'destination'], if: -> { ecs_compatibility? }
|
429
|
+
|
430
|
+
it 'matches' do
|
431
|
+
if ecs_compatibility?
|
432
|
+
expect(subject).to include "destination"=>{"ip"=>"10.10.1.1"},
|
433
|
+
"cisco"=>{"asa"=>{
|
434
|
+
"ipsec"=>{"spi"=>"0x1B86506B", "protocol"=>"ESP", "seq_num"=>"0x28B"},
|
435
|
+
"network"=>{"type"=>"IPSEC"}
|
436
|
+
}},
|
437
|
+
"source"=>{"ip"=>"68.18.122.4", "user"=>{"name"=>"Bangalo"}}
|
438
|
+
else
|
439
|
+
expect(subject).to include "dst_ip"=>"10.10.1.1", "src_ip"=>"68.18.122.4",
|
440
|
+
"spi"=>"0x1B86506B", "seq_num"=>"0x28B",
|
441
|
+
"protocol"=>"IPSEC", "orig_protocol"=>"ESP",
|
442
|
+
"user"=>"Bangalo"
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
end
|
447
|
+
|
448
|
+
describe_pattern "CISCOFW419001", ['legacy', 'ecs-v1'] do
|
449
|
+
|
450
|
+
let(:message) do
|
451
|
+
"%ASA-4-419001: Dropping TCP packet from outside:65.55.184.155/80 to inside:192.168.10.11/49043, reason: MSS exceeded, MSS 1380, data 1460"
|
452
|
+
end
|
453
|
+
|
454
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
455
|
+
|
456
|
+
it 'matches' do
|
457
|
+
if ecs_compatibility?
|
458
|
+
expect(subject).to include("source"=>{"port"=>80, "ip"=>"65.55.184.155"},
|
459
|
+
"destination"=>{"port"=>49043, "ip"=>"192.168.10.11"},
|
460
|
+
"cisco"=>{"asa"=>{
|
461
|
+
"outcome"=>"Dropping", "network"=>{"transport"=>"TCP"}
|
462
|
+
}},
|
463
|
+
"observer"=>{
|
464
|
+
"ingress"=>{"interface"=>{"name"=>"outside"}},
|
465
|
+
"egress"=>{"interface"=>{"name"=>"inside"}}
|
466
|
+
})
|
467
|
+
expect(subject).to include "event"=>{"reason"=>"MSS exceeded, MSS 1380, data 1460"}
|
468
|
+
else
|
469
|
+
expect(subject).to include "src_ip"=>"65.55.184.155", "src_port"=>"80", "src_interface"=>"outside",
|
470
|
+
"dst_ip"=>"192.168.10.11", "dst_port"=>"49043", "dst_interface"=>"inside",
|
471
|
+
"protocol"=>"TCP", "action"=>"Dropping",
|
472
|
+
"reason"=>"MSS exceeded, MSS 1380, data 1460"
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
end
|
477
|
+
|
478
|
+
describe_pattern "CISCOFW419002", ['legacy', 'ecs-v1'] do
|
479
|
+
|
480
|
+
let(:message) do
|
481
|
+
"%ASA-4-419002: Duplicate TCP SYN from OUTSIDE:10.10.66.2/65087 to INSIDE:10.10.1.6/443 with different initial sequence number."
|
482
|
+
end
|
483
|
+
|
484
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
485
|
+
|
486
|
+
it 'matches' do
|
487
|
+
if ecs_compatibility?
|
488
|
+
expect(subject).to include "event"=>{"reason"=>"Duplicate TCP SYN"},
|
489
|
+
"source"=>{"port"=>65087, "ip"=>"10.10.66.2"},
|
490
|
+
"destination"=>{"port"=>443, "ip"=>"10.10.1.6"},
|
491
|
+
"observer"=>{"egress"=>{"interface"=>{"name"=>"INSIDE"}}, "ingress"=>{"interface"=>{"name"=>"OUTSIDE"}}}
|
492
|
+
else
|
493
|
+
expect(subject).to include "src_ip"=>"10.10.66.2", "src_port"=>"65087", "src_interface"=>"OUTSIDE",
|
494
|
+
"dst_ip"=>"10.10.1.6", "dst_port"=>"443", "dst_interface"=>"INSIDE",
|
495
|
+
"reason"=>"Duplicate TCP SYN"
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
end
|
500
|
+
|
501
|
+
describe_pattern "CISCOFW602303_602304", ['legacy', 'ecs-v1'] do
|
502
|
+
|
503
|
+
let(:message) do
|
504
|
+
"%ASA-6-602303: IPSEC: An outbound LAN-to-LAN SA (SPI= 0xF81283) between 91.240.17.178 and 192.168.2.2 (user= admin) has been created."
|
505
|
+
end
|
506
|
+
|
507
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
508
|
+
|
509
|
+
it 'matches' do
|
510
|
+
if ecs_compatibility?
|
511
|
+
expect(subject).to include("cisco"=>{"asa"=>{
|
512
|
+
"network"=>{"direction"=>"outbound", "type"=>"IPSEC"},
|
513
|
+
"outcome"=>"created",
|
514
|
+
"ipsec"=>{"spi"=>"0xF81283", "tunnel_type"=>"LAN-to-LAN"}}},
|
515
|
+
"destination"=>{"ip"=>"192.168.2.2"},
|
516
|
+
"source"=>{"ip"=>"91.240.17.178", "user"=>{"name"=>"admin"}})
|
517
|
+
else
|
518
|
+
expect(subject).to include "protocol"=>"IPSEC", "direction"=>"outbound", "tunnel_type"=>"LAN-to-LAN",
|
519
|
+
"src_ip"=>"91.240.17.178", "dst_ip"=>"192.168.2.2",
|
520
|
+
"spi"=>"0xF81283", "user"=>"admin", "action"=>"created"
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
end
|
525
|
+
|
526
|
+
describe_pattern "CISCOFW710001_710002_710003_710005_710006", ['legacy', 'ecs-v1'] do
|
527
|
+
|
528
|
+
let(:message) do
|
529
|
+
"%PIX-7-710001: TCP access requested from 192.168.1.2/2354 to inside:192.168.1.1/443"
|
530
|
+
end
|
531
|
+
|
532
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
533
|
+
|
534
|
+
it 'matches' do
|
535
|
+
if ecs_compatibility?
|
536
|
+
expect(subject).to include("source"=>{"ip"=>"192.168.1.2", "port"=>2354})
|
537
|
+
expect(subject).to include("destination"=>{"ip"=>"192.168.1.1", "port"=>443})
|
538
|
+
expect(subject).to include("observer"=>{"egress"=>{"interface"=>{"name"=>"inside"}}},
|
539
|
+
"cisco"=>{"asa"=>{"outcome"=>"requested", "network"=>{"transport"=>"TCP"}}})
|
540
|
+
else
|
541
|
+
expect(subject).to include "src_ip"=>"192.168.1.2", "src_port"=>"2354",
|
542
|
+
"dst_ip"=>"192.168.1.1", "dst_port"=>"443", "dst_interface"=>"inside",
|
543
|
+
"action"=>"requested"
|
134
544
|
end
|
135
545
|
end
|
546
|
+
|
547
|
+
end
|
548
|
+
|
549
|
+
describe_pattern "CISCOFW713172", ['legacy', 'ecs-v1'] do
|
550
|
+
|
551
|
+
let(:message) do
|
552
|
+
"%ASA-6-713172: Group = 212.9.5.245, IP = 212.9.5.245, Automatic NAT Detection Status: " +
|
553
|
+
"Remote end is NOT behind a NAT device This end IS behind a NAT device"
|
554
|
+
end
|
555
|
+
|
556
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
557
|
+
|
558
|
+
it 'matches' do
|
559
|
+
if ecs_compatibility?
|
560
|
+
expect(subject).to include("source"=>{"ip"=>"212.9.5.245"}, "cisco"=>{"asa"=>{"source"=>{"group"=>"212.9.5.245"}}})
|
561
|
+
expect(event.get('@metadata')).to include "cisco"=>{"asa"=>{"local_nat"=>"IS", "remote_nat"=>"is NOT"}} # needs processing
|
562
|
+
else
|
563
|
+
expect(subject).to include("group"=>"212.9.5.245", "src_ip"=>"212.9.5.245",
|
564
|
+
"is_local_natted"=>"IS", "is_remote_natted"=>"is NOT")
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
end
|
569
|
+
|
570
|
+
describe_pattern "CISCOFW733100", ['legacy', 'ecs-v1'] do
|
571
|
+
|
572
|
+
let(:message) do
|
573
|
+
"%ASA-4-733100: [192.168.2.2] drop rate-1 exceeded. Current burst rate is 0 per second, max configured rate is -4; " +
|
574
|
+
"Current average rate is 7 per second, max configured rate is -5; Cumulative total count is 9063"
|
575
|
+
end
|
576
|
+
|
577
|
+
include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
|
578
|
+
|
579
|
+
it 'matches' do
|
580
|
+
if ecs_compatibility?
|
581
|
+
expect(subject).to include "cisco"=>{"asa"=>{"burst"=>{
|
582
|
+
"object"=>"192.168.2.2", "id"=>"rate-1",
|
583
|
+
"configured_rate"=>-4, "current_rate"=>0,
|
584
|
+
"avg_rate"=>7, "configured_avg_rate"=>-5,
|
585
|
+
"cumulative_count"=>9063}}}
|
586
|
+
else
|
587
|
+
expect(subject).to include "drop_type"=>"192.168.2.2", "drop_rate_id"=>"rate-1",
|
588
|
+
"drop_rate_current_avg"=>"7",
|
589
|
+
"drop_total_count"=>"9063",
|
590
|
+
"drop_rate_current_burst"=>"0",
|
591
|
+
"drop_rate_max_burst"=>"-4",
|
592
|
+
"drop_rate_max_avg"=>"-5"
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
136
596
|
end
|
597
|
+
|
598
|
+
|
599
|
+
describe_pattern 'SFW2', ['legacy', 'ecs-v1'] do
|
600
|
+
|
601
|
+
let(:message) do
|
602
|
+
"Jan 29 00:00:28 myth kernel: SFW2-INext-DROP-DEFLT IN=ppp0 OUT= MAC= SRC=24.64.208.134 DST=216.58.112.55 LEN=512 TOS=0x00 PREC=0x00 TTL=70 ID=55012 PROTO=UDP SPT=24128 DPT=1026 LEN=492"
|
603
|
+
end
|
604
|
+
|
605
|
+
it 'matches' do
|
606
|
+
# NOTE: we do not match the second LEN=492 which is the length of the wrapped (UDP in this case) packet
|
607
|
+
# iptables.length (IP packet length) 512 = 492 (UDP/TCP packet length) + 20 (IPv4 header length = 20 bytes)
|
608
|
+
if ecs_compatibility?
|
609
|
+
expect(grok).to include(
|
610
|
+
"timestamp"=>"Jan 29 00:00:28",
|
611
|
+
"observer"=>{"hostname"=>"myth", "ingress"=>{"interface"=>{"name"=>"ppp0"}}},
|
612
|
+
"suse"=>{"firewall"=>{"action"=>"DROP-DEFLT", "log_prefix"=>"SFW2-INext-DROP-DEFLT"}},
|
613
|
+
"source"=>{"ip"=>"24.64.208.134", "port"=>24128},
|
614
|
+
"destination"=>{"ip"=>"216.58.112.55", "port"=>1026},
|
615
|
+
"iptables"=>{
|
616
|
+
"length"=>512, # IP packet length
|
617
|
+
"id"=>"55012",
|
618
|
+
"ttl"=>70,
|
619
|
+
"tos"=>"00",
|
620
|
+
"precedence_bits"=>"00"
|
621
|
+
},
|
622
|
+
"network"=>{"transport"=>"UDP"}
|
623
|
+
)
|
624
|
+
else
|
625
|
+
expect(grok).to include(
|
626
|
+
"nf_action"=>"DROP-DEFLT",
|
627
|
+
"nf_in_interface"=>"ppp0",
|
628
|
+
"nf_src_ip"=>"24.64.208.134",
|
629
|
+
"nf_dst_ip"=>"216.58.112.55",
|
630
|
+
"nf_protocol"=>"UDP"
|
631
|
+
)
|
632
|
+
end
|
633
|
+
end
|
634
|
+
|
635
|
+
context 'long message' do
|
636
|
+
|
637
|
+
let(:message) do
|
638
|
+
'Mar 8 20:16:44 black kernel: [20474.050964] SFW2-INext-ACC-TCP IN=eth0 OUT= MAC=28:45:a7:f3:18:00:00:22:15:67:6a:25:08:00 SRC=192.168.0.101 DST=192.168.0.100 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=6429 DF PROTO=TCP SPT=59282 DPT=631 WINDOW=14600 RES=0x00 SYN URGP=0 OPT (020405B40402080A00825F5D0000000001030307)'
|
639
|
+
end
|
640
|
+
|
641
|
+
it 'matches' do
|
642
|
+
if ecs_compatibility?
|
643
|
+
expect(grok).to include(
|
644
|
+
"timestamp"=>"Mar 8 20:16:44",
|
645
|
+
"observer"=>{"hostname"=>"black", "ingress"=>{"interface"=>{"name"=>"eth0"}}},
|
646
|
+
"suse"=>{"firewall"=>{"action"=>"ACC-TCP", "log_prefix"=>"SFW2-INext-ACC-TCP"}},
|
647
|
+
"source"=>{"mac"=>"00:22:15:67:6a:25", "ip"=>"192.168.0.101", "port"=>59282},
|
648
|
+
"destination"=>{"mac"=>"28:45:a7:f3:18:00", "ip"=>"192.168.0.100", "port"=>631},
|
649
|
+
"iptables"=>{
|
650
|
+
"length"=>60,
|
651
|
+
"id"=>"6429",
|
652
|
+
"tos"=>"00", "fragment_flags"=>"DF",
|
653
|
+
"ttl"=>64,
|
654
|
+
"precedence_bits"=>"00",
|
655
|
+
"tcp"=>{"flags"=>"SYN ", "window"=>14600},
|
656
|
+
"tcp_reserved_bits"=>"00"
|
657
|
+
},
|
658
|
+
"network"=>{"transport"=>"TCP"}
|
659
|
+
)
|
660
|
+
else
|
661
|
+
expect(grok).to include(
|
662
|
+
"nagios_epoch"=>"20474.050964", # YAY!
|
663
|
+
"nf_action"=>"ACC-TCP",
|
664
|
+
"nf_in_interface"=>"eth0",
|
665
|
+
"nf_dst_port"=>"631",
|
666
|
+
|
667
|
+
"nf_dst_mac"=>"28:45:a7:f3:18:00",
|
668
|
+
"nf_src_mac"=>"00:22:15:67:6a:25",
|
669
|
+
"nf_dst_ip"=>"192.168.0.100",
|
670
|
+
"nf_src_ip"=>"192.168.0.101",
|
671
|
+
"nf_src_port"=>"59282",
|
672
|
+
|
673
|
+
"nf_protocol"=>"TCP"
|
674
|
+
)
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
end
|
679
|
+
|
680
|
+
context 'alternate log-prefixes' do
|
681
|
+
|
682
|
+
describe 'SuSE-FW-DROP-DEFAULT' do # by default we only match SFW2-INext-*
|
683
|
+
|
684
|
+
let(:message) do
|
685
|
+
"Mar 8 22:35:42 linux kernel: SuSE-FW-DROP-DEFAULT IN=ppp0 OUT= MAC= SRC=202.175.181.4 DST=64.238.136.187 LEN=48 TOS=0x00 PREC=0x00 TTL=113 ID=31151 DF PROTO=TCP SPT=3360 DPT=3127 WINDOW=65340 RES=0x00 SYN URGP=0 OPT (020405AC01010402)"
|
686
|
+
end
|
687
|
+
|
688
|
+
it 'does not match' do
|
689
|
+
expect(grok['tags']).to include('_grokparsefailure')
|
690
|
+
end
|
691
|
+
|
692
|
+
end
|
693
|
+
|
694
|
+
describe 'SFW2-IN-ACC-RELATED' do
|
695
|
+
|
696
|
+
let(:message) do
|
697
|
+
"Jan 15 11:21:13 IKCSWeb kernel: SFW2-IN-ACC-RELATED IN=eth1 OUT= MAC=00:19:bb:2e:85:42:00:17:c5:d8:2e:2c:08:00 SRC=59.64.166.81 DST=207.194.99.122 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=48949 DF PROTO=TCP SPT=24093 DPT=22 WINDOW=137 RES=0x00 ACK URGP=0"
|
698
|
+
end
|
699
|
+
|
700
|
+
it 'does not match' do
|
701
|
+
expect(grok['tags']).to include('_grokparsefailure')
|
702
|
+
end
|
703
|
+
|
704
|
+
end
|
705
|
+
|
706
|
+
end
|
707
|
+
|
708
|
+
context 'IPv6 message' do
|
709
|
+
|
710
|
+
let(:message) do
|
711
|
+
"Jan 15 11:21:13 IKCS-Web kernel: SFW2-INext-ACC-RELATED IN=eth0 OUT=eth1 MAC= SRC=fe80:0000:0000:0000:16da:e9ff:feec:a04d DST=ff02:0000:0000:0000:0000:0000:0000:00fb LEN=527 TC=0 HOPLIMIT=255 FLOWLBL=804001 PROTO=UDP SPT=5353 DPT=5353 LEN=487"
|
712
|
+
end
|
713
|
+
|
714
|
+
it 'matches' do
|
715
|
+
if ecs_compatibility?
|
716
|
+
iptables = grok['iptables']
|
717
|
+
expect(iptables).to include("flow_label"=>"804001")
|
718
|
+
expect(iptables['ttl'].to_s).to eql('255')
|
719
|
+
expect(iptables['length'].to_s).to eql('527')
|
720
|
+
expect(grok).to include("observer"=>{"hostname"=>"IKCS-Web", "ingress"=>{"interface"=>{"name"=>"eth0"}}, "egress"=>{"interface"=>{"name"=>"eth1"}}})
|
721
|
+
expect(grok).to include(
|
722
|
+
"source"=>{"ip"=>"fe80:0000:0000:0000:16da:e9ff:feec:a04d", "port"=>5353},
|
723
|
+
"destination"=>{"ip"=>"ff02:0000:0000:0000:0000:0000:0000:00fb", "port"=>5353},
|
724
|
+
"network"=>{"transport"=>"UDP"}
|
725
|
+
)
|
726
|
+
pending
|
727
|
+
# TODO hitting a grok type-casting issue https://github.com/logstash-plugins/logstash-filter-grok/issues/165
|
728
|
+
expect(iptables).to include("ttl"=>255, "flow_label"=>"804001", "length"=>527)
|
729
|
+
else
|
730
|
+
expect(grok).to include("nf_src_ip"=>"fe80:0000:0000:0000:16da:e9ff:feec:a04d",
|
731
|
+
"nf_dst_ip"=>"ff02:0000:0000:0000:0000:0000:0000:00fb",
|
732
|
+
"nf_protocol"=>"UDP")
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
end
|
737
|
+
|
738
|
+
end
|
739
|
+
|