logstash-patterns-core 4.1.2 → 4.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +119 -0
  3. data/Gemfile +8 -1
  4. data/LICENSE +199 -10
  5. data/README.md +12 -19
  6. data/lib/logstash/patterns/core.rb +11 -3
  7. data/logstash-patterns-core.gemspec +1 -1
  8. data/patterns/ecs-v1/aws +28 -0
  9. data/patterns/ecs-v1/bacula +53 -0
  10. data/patterns/ecs-v1/bind +13 -0
  11. data/patterns/ecs-v1/bro +30 -0
  12. data/patterns/ecs-v1/exim +26 -0
  13. data/patterns/ecs-v1/firewalls +111 -0
  14. data/patterns/ecs-v1/grok-patterns +95 -0
  15. data/patterns/ecs-v1/haproxy +40 -0
  16. data/patterns/ecs-v1/httpd +17 -0
  17. data/patterns/ecs-v1/java +34 -0
  18. data/patterns/ecs-v1/junos +13 -0
  19. data/patterns/ecs-v1/linux-syslog +16 -0
  20. data/patterns/{maven → ecs-v1/maven} +0 -0
  21. data/patterns/ecs-v1/mcollective +4 -0
  22. data/patterns/ecs-v1/mongodb +7 -0
  23. data/patterns/ecs-v1/nagios +124 -0
  24. data/patterns/ecs-v1/postgresql +2 -0
  25. data/patterns/ecs-v1/rails +13 -0
  26. data/patterns/ecs-v1/redis +3 -0
  27. data/patterns/ecs-v1/ruby +2 -0
  28. data/patterns/ecs-v1/squid +6 -0
  29. data/patterns/ecs-v1/zeek +33 -0
  30. data/patterns/{aws → legacy/aws} +1 -1
  31. data/patterns/{bacula → legacy/bacula} +5 -5
  32. data/patterns/legacy/bind +3 -0
  33. data/patterns/{bro → legacy/bro} +0 -0
  34. data/patterns/{exim → legacy/exim} +8 -2
  35. data/patterns/{firewalls → legacy/firewalls} +2 -2
  36. data/patterns/{grok-patterns → legacy/grok-patterns} +4 -4
  37. data/patterns/{haproxy → legacy/haproxy} +1 -1
  38. data/patterns/{httpd → legacy/httpd} +2 -2
  39. data/patterns/{java → legacy/java} +1 -3
  40. data/patterns/{junos → legacy/junos} +0 -0
  41. data/patterns/{linux-syslog → legacy/linux-syslog} +0 -0
  42. data/patterns/legacy/maven +1 -0
  43. data/patterns/{mcollective → legacy/mcollective} +0 -0
  44. data/patterns/{mcollective-patterns → legacy/mcollective-patterns} +0 -0
  45. data/patterns/{mongodb → legacy/mongodb} +0 -0
  46. data/patterns/{nagios → legacy/nagios} +1 -1
  47. data/patterns/{postgresql → legacy/postgresql} +0 -0
  48. data/patterns/{rails → legacy/rails} +0 -0
  49. data/patterns/{redis → legacy/redis} +0 -0
  50. data/patterns/{ruby → legacy/ruby} +0 -0
  51. data/patterns/legacy/squid +4 -0
  52. data/spec/patterns/aws_spec.rb +395 -0
  53. data/spec/patterns/bacula_spec.rb +367 -0
  54. data/spec/patterns/bind_spec.rb +92 -0
  55. data/spec/patterns/bro_spec.rb +613 -0
  56. data/spec/patterns/core_spec.rb +260 -15
  57. data/spec/patterns/exim_spec.rb +201 -0
  58. data/spec/patterns/firewalls_spec.rb +707 -66
  59. data/spec/patterns/haproxy_spec.rb +253 -28
  60. data/spec/patterns/httpd_spec.rb +248 -86
  61. data/spec/patterns/java_spec.rb +375 -0
  62. data/spec/patterns/junos_spec.rb +101 -0
  63. data/spec/patterns/mcollective_spec.rb +35 -0
  64. data/spec/patterns/mongodb_spec.rb +170 -33
  65. data/spec/patterns/nagios_spec.rb +299 -78
  66. data/spec/patterns/netscreen_spec.rb +123 -0
  67. data/spec/patterns/rails3_spec.rb +87 -29
  68. data/spec/patterns/redis_spec.rb +216 -140
  69. data/spec/patterns/shorewall_spec.rb +85 -74
  70. data/spec/patterns/squid_spec.rb +139 -0
  71. data/spec/patterns/syslog_spec.rb +266 -22
  72. data/spec/spec_helper.rb +83 -5
  73. metadata +70 -31
  74. data/patterns/bind +0 -3
  75. data/patterns/squid +0 -4
  76. data/spec/patterns/bro.rb +0 -126
  77. data/spec/patterns/s3_spec.rb +0 -173
@@ -2,94 +2,185 @@
2
2
  require "spec_helper"
3
3
  require "logstash/patterns/core"
4
4
 
5
- describe "FIREWALLS" do
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(:pattern104001) { "CISCOFW104001" }
9
+ let(:message) { "(Secondary) Switching to ACTIVE - Service card in other unit has failed" }
9
10
 
10
- context "parsing a 104001 message" do
11
+ include_examples 'top-level namespaces', ['event'], if: -> { ecs_compatibility? }
11
12
 
12
- let(:value) { "(Secondary) Switching to ACTIVE - Service card in other unit has failed" }
13
+ it { expect(subject).to include("switch_reason" => "Service card in other unit has failed") unless ecs_compatibility? }
13
14
 
14
- subject { grok_match(pattern104001, value) }
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
- it { should include("switch_reason" => "Service card in other unit has failed") }
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
- it "generates a message field" do
19
- expect(subject["message"]).to include("(Secondary) Switching to ACTIVE - Service card in other unit has failed")
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
- context "parsing a 106015 message" do
38
+ it "keeps message field" do
39
+ expect(subject["message"]).to eql message
40
+ end
41
+
42
+ end
26
43
 
27
- let(:value) { "Deny TCP (no connection) from 192.168.150.65/2278 to 64.101.128.83/80 flags RST on interface inside" }
44
+ describe_pattern "CISCOFW106006_106007_106010", ['legacy', 'ecs-v1'] do
28
45
 
29
- subject { grok_match(pattern106015, value) }
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
- it { should include("interface" => "inside") }
48
+ include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
32
49
 
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")
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
- let(:pattern106100) { "CISCOFW106100" }
61
+ it "keeps message field" do
62
+ expect(subject["message"]).to eql message
63
+ end
39
64
 
40
- context "parsing a 106100 message" do
65
+ end
41
66
 
42
- let(:value) { "access-list inside permitted tcp inside/10.10.123.45(51763) -> outside/192.168.67.89(80) hit-cnt 1 first hit [0x62c4905, 0x0]" }
67
+ describe_pattern "CISCOFW106014", ['legacy', 'ecs-v1'] do
43
68
 
44
- subject { grok_match(pattern106100, value) }
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
- it { should include("policy_id" => "inside") }
71
+ include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
47
72
 
48
- it "generates a message field" do
49
- expect(subject["message"]).to include("access-list inside permitted tcp inside/10.10.123.45(51763) -> outside/192.168.67.89(80) hit-cnt 1 first hit [0x62c4905, 0x0]")
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
- let(:pattern106100) { "CISCOFW106100" }
84
+ it "keeps message field" do
85
+ expect(subject["message"]).to eql message
86
+ end
54
87
 
55
- context "parsing a 106100 message with hypen in acl name" do
88
+ end
56
89
 
57
- let(:value) { "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]" }
90
+ describe_pattern "CISCOFW106015", ['legacy', 'ecs-v1'] do
58
91
 
59
- subject { grok_match(pattern106100, value) }
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
- it { should include("policy_id" => "outside-entry") }
94
+ include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
62
95
 
63
- it "generates a message field" do
64
- expect(subject["message"]).to include("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]")
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
- let(:pattern304001) { "CISCOFW304001" }
104
+ it "keeps message field" do
105
+ expect(subject["message"]).to eql message
106
+ end
69
107
 
70
- context "parsing a 304001 message" do
108
+ end
71
109
 
72
- let(:value) { "10.20.30.40(DOMAIN\\login) Accessed URL 10.11.12.13:http://example.org/" }
110
+ describe_pattern "CISCOFW106021", ['legacy', 'ecs-v1'] do
73
111
 
74
- subject { grok_match(pattern304001, value) }
112
+ let(:message) { "ASA-4-106021: Deny TCP reverse path check from 192.168.2.2 to 10.10.10.10 on interface fw111" }
75
113
 
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/')
114
+ include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
115
+
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
- let(:pattern106023) { "CISCOFW106023" }
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
- context "parsing a 106023 message" do
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
- let(:value) { '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]' }
136
+ include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
137
+
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
145
+
146
+ it "keeps message field" do
147
+ expect(subject["message"]).to eql message
148
+ end
149
+
150
+ end
89
151
 
90
- subject { grok_match(pattern106023, value) }
152
+ describe_pattern "CISCOFW106100", ['legacy', 'ecs-v1'] do
91
153
 
92
- it 'should break the message up into fields' do
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,587 @@ describe "FIREWALLS" do
100
191
  end
101
192
  end
102
193
 
103
- context "parsing a 106023 message with a protocol number" do
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
- subject { grok_match(pattern106023, value) }
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
- it 'should break the message up into fields' do
110
- expect(subject['action']).to eq('Deny')
111
- expect(subject['src_interface']).to eq('outside')
112
- expect(subject['dst_interface']).to eq('inside')
113
- expect(subject['protocol']).to eq('103')
114
- expect(subject['src_ip']).to eq('192.168.1.1')
115
- expect(subject['dst_ip']).to eq('192.168.1.2')
116
- expect(subject['policy_id']).to eq('S_OUTSIDE_TO_INSIDE')
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
- context "parsing a 106023 message with a hostname" do
256
+ end
121
257
 
122
- let(:value) { 'Deny tcp src outside:192.168.1.1/50240 dst inside:www.example.com/23 by access-group "S_OUTSIDE_TO_INSIDE" [0x54c7fa80, 0x0]' }
258
+ describe_pattern "CISCOFW110002", ['legacy', 'ecs-v1'] do
123
259
 
124
- subject { grok_match(pattern106023, value) }
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" }
125
261
 
126
- it 'should break the message up into fields' do
127
- expect(subject['action']).to eq('Deny')
128
- expect(subject['src_interface']).to eq('outside')
129
- expect(subject['dst_interface']).to eq('inside')
130
- expect(subject['protocol']).to eq('tcp')
131
- expect(subject['src_ip']).to eq('192.168.1.1')
132
- expect(subject['dst_ip']).to eq('www.example.com')
133
- expect(subject['policy_id']).to eq('S_OUTSIDE_TO_INSIDE')
262
+ include_examples 'top-level namespaces', CISCOFW_ALLOWED_TOP_LEVEL_NAMESPACES, if: -> { ecs_compatibility? }
263
+
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"
134
443
  end
135
444
  end
445
+
136
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"
544
+ end
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
+
596
+ end
597
+
598
+ describe_pattern "CISCO_TAGGED_SYSLOG", ['legacy', 'ecs-v1'] do
599
+
600
+ let(:message) { "<191>Jan 24 11:28:30.407: %LINEPROTO-5-UPDOWN: Line protocol on Interface GigabitEthernet0/0, changed state to down" }
601
+
602
+ it 'matches' do
603
+ expect(subject).to include("timestamp"=>'Jan 24 11:28:30.407')
604
+ if ecs_compatibility?
605
+ expect(subject).to include('log' => {'syslog' => {'priority' => 191}})
606
+ expect(subject).to include('cisco' => {'asa' => {'tag' => 'LINEPROTO-5-UPDOWN'}})
607
+ else
608
+ expect(subject).to include("syslog_pri"=>'191')
609
+ expect(subject).to include("ciscotag"=>'LINEPROTO-5-UPDOWN')
610
+ end
611
+ end
612
+
613
+ context 'with host' do
614
+
615
+ let(:message) do
616
+ '<191>Aug 1 14:01:20 abc-asa1: %ASA-6-302013: Built outbound TCP connection 906569140 for out-v1101:10.125.126.86/2010 (10.125.126.86/2010) to ent-v1124:100.100.100.111/51444 (10.125.1.11/37785)'
617
+ end
618
+
619
+ it 'matches' do
620
+ expect(subject).to include("timestamp"=>'Aug 1 14:01:20')
621
+ if ecs_compatibility?
622
+ expect(subject).to include('log' => {'syslog' => {'priority' => 191}})
623
+ expect(subject).to include('host' => {'hostname' => 'abc-asa1'})
624
+ expect(subject).to include('cisco' => {'asa' => {'tag' => 'ASA-6-302013'}})
625
+ else
626
+ expect(subject).to include("syslog_pri"=>'191')
627
+ expect(subject).to include("sysloghost"=>'abc-asa1')
628
+ expect(subject).to include("ciscotag"=>'ASA-6-302013')
629
+ end
630
+ end
631
+
632
+ end
633
+
634
+ end
635
+
636
+
637
+ describe_pattern 'SFW2', ['legacy', 'ecs-v1'] do
638
+
639
+ let(:message) do
640
+ "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"
641
+ end
642
+
643
+ it 'matches' do
644
+ # NOTE: we do not match the second LEN=492 which is the length of the wrapped (UDP in this case) packet
645
+ # iptables.length (IP packet length) 512 = 492 (UDP/TCP packet length) + 20 (IPv4 header length = 20 bytes)
646
+ if ecs_compatibility?
647
+ expect(grok).to include(
648
+ "timestamp"=>"Jan 29 00:00:28",
649
+ "observer"=>{"hostname"=>"myth", "ingress"=>{"interface"=>{"name"=>"ppp0"}}},
650
+ "suse"=>{"firewall"=>{"action"=>"DROP-DEFLT", "log_prefix"=>"SFW2-INext-DROP-DEFLT"}},
651
+ "source"=>{"ip"=>"24.64.208.134", "port"=>24128},
652
+ "destination"=>{"ip"=>"216.58.112.55", "port"=>1026},
653
+ "iptables"=>{
654
+ "length"=>512, # IP packet length
655
+ "id"=>"55012",
656
+ "ttl"=>70,
657
+ "tos"=>"00",
658
+ "precedence_bits"=>"00"
659
+ },
660
+ "network"=>{"transport"=>"UDP"}
661
+ )
662
+ else
663
+ expect(grok).to include(
664
+ "nf_action"=>"DROP-DEFLT",
665
+ "nf_in_interface"=>"ppp0",
666
+ "nf_src_ip"=>"24.64.208.134",
667
+ "nf_dst_ip"=>"216.58.112.55",
668
+ "nf_protocol"=>"UDP"
669
+ )
670
+ end
671
+ end
672
+
673
+ context 'long message' do
674
+
675
+ let(:message) do
676
+ '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)'
677
+ end
678
+
679
+ it 'matches' do
680
+ if ecs_compatibility?
681
+ expect(grok).to include(
682
+ "timestamp"=>"Mar 8 20:16:44",
683
+ "observer"=>{"hostname"=>"black", "ingress"=>{"interface"=>{"name"=>"eth0"}}},
684
+ "suse"=>{"firewall"=>{"action"=>"ACC-TCP", "log_prefix"=>"SFW2-INext-ACC-TCP"}},
685
+ "source"=>{"mac"=>"00:22:15:67:6a:25", "ip"=>"192.168.0.101", "port"=>59282},
686
+ "destination"=>{"mac"=>"28:45:a7:f3:18:00", "ip"=>"192.168.0.100", "port"=>631},
687
+ "iptables"=>{
688
+ "length"=>60,
689
+ "id"=>"6429",
690
+ "tos"=>"00", "fragment_flags"=>"DF",
691
+ "ttl"=>64,
692
+ "precedence_bits"=>"00",
693
+ "tcp"=>{"flags"=>"SYN ", "window"=>14600},
694
+ "tcp_reserved_bits"=>"00"
695
+ },
696
+ "network"=>{"transport"=>"TCP"}
697
+ )
698
+ else
699
+ expect(grok).to include(
700
+ "nagios_epoch"=>"20474.050964", # YAY!
701
+ "nf_action"=>"ACC-TCP",
702
+ "nf_in_interface"=>"eth0",
703
+ "nf_dst_port"=>"631",
704
+
705
+ "nf_dst_mac"=>"28:45:a7:f3:18:00",
706
+ "nf_src_mac"=>"00:22:15:67:6a:25",
707
+ "nf_dst_ip"=>"192.168.0.100",
708
+ "nf_src_ip"=>"192.168.0.101",
709
+ "nf_src_port"=>"59282",
710
+
711
+ "nf_protocol"=>"TCP"
712
+ )
713
+ end
714
+ end
715
+
716
+ end
717
+
718
+ context 'alternate log-prefixes' do
719
+
720
+ describe 'SuSE-FW-DROP-DEFAULT' do # by default we only match SFW2-INext-*
721
+
722
+ let(:message) do
723
+ "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)"
724
+ end
725
+
726
+ it 'does not match' do
727
+ expect(grok['tags']).to include('_grokparsefailure')
728
+ end
729
+
730
+ end
731
+
732
+ describe 'SFW2-IN-ACC-RELATED' do
733
+
734
+ let(:message) do
735
+ "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"
736
+ end
737
+
738
+ it 'does not match' do
739
+ expect(grok['tags']).to include('_grokparsefailure')
740
+ end
741
+
742
+ end
743
+
744
+ end
745
+
746
+ context 'IPv6 message' do
747
+
748
+ let(:message) do
749
+ "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"
750
+ end
751
+
752
+ it 'matches' do
753
+ if ecs_compatibility?
754
+ iptables = grok['iptables']
755
+ expect(iptables).to include("flow_label"=>"804001")
756
+ expect(iptables['ttl'].to_s).to eql('255')
757
+ expect(iptables['length'].to_s).to eql('527')
758
+ expect(grok).to include("observer"=>{"hostname"=>"IKCS-Web", "ingress"=>{"interface"=>{"name"=>"eth0"}}, "egress"=>{"interface"=>{"name"=>"eth1"}}})
759
+ expect(grok).to include(
760
+ "source"=>{"ip"=>"fe80:0000:0000:0000:16da:e9ff:feec:a04d", "port"=>5353},
761
+ "destination"=>{"ip"=>"ff02:0000:0000:0000:0000:0000:0000:00fb", "port"=>5353},
762
+ "network"=>{"transport"=>"UDP"}
763
+ )
764
+ pending
765
+ # TODO hitting a grok type-casting issue https://github.com/logstash-plugins/logstash-filter-grok/issues/165
766
+ expect(iptables).to include("ttl"=>255, "flow_label"=>"804001", "length"=>527)
767
+ else
768
+ expect(grok).to include("nf_src_ip"=>"fe80:0000:0000:0000:16da:e9ff:feec:a04d",
769
+ "nf_dst_ip"=>"ff02:0000:0000:0000:0000:0000:0000:00fb",
770
+ "nf_protocol"=>"UDP")
771
+ end
772
+ end
773
+
774
+ end
775
+
776
+ end
777
+