logstash-patterns-core 4.1.2 → 4.3.2

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.
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
+