fluent-plugin-jfrog-siem 0.1.1 → 0.1.6
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/README.md +37 -20
- data/elastic.conf +18 -0
- data/fluent-plugin-jfrog-siem.gemspec +3 -1
- data/lib/fluent/plugin/in_jfrog_siem.rb +49 -27
- data/splunk.conf +18 -0
- metadata +32 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a804fe365772166ab8b36207d11e1ffc4b858c3e47a5792240e5d6e1567108bd
|
|
4
|
+
data.tar.gz: f0bc602534f2c109469688fe38b79d78fecc1eb3ed31e9e0b40874cbea0935e4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 39082ce3738d65195ce5c85f7670e7883fc003b9bd853ef9dbb74f4e74f9c2b9a9750a83b90bcc9bb9264a921c06a2548f9bd599794bb4504e78201accbf733c
|
|
7
|
+
data.tar.gz: 05dfcd3fe9e49d94e824f9265cf4b6a301911529520e479d36889328872e92943f876b2bfacc2a25203c6c8de3e0f93e3f7427b5a684687c4ed427c59d6bf5c0
|
data/README.md
CHANGED
|
@@ -19,19 +19,7 @@ bundle install
|
|
|
19
19
|
This will install the gem shown below from source.
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
### RubyGems
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
$ gem install rest-client
|
|
28
|
-
```
|
|
29
|
-
```
|
|
30
|
-
$ gem install thread
|
|
31
|
-
```
|
|
32
|
-
```
|
|
33
|
-
$ gem install fluent-plugin-jfrog-siem
|
|
34
|
-
```
|
|
22
|
+
## Development
|
|
35
23
|
|
|
36
24
|
### Bundler
|
|
37
25
|
|
|
@@ -47,7 +35,7 @@ And then execute:
|
|
|
47
35
|
$ bundle
|
|
48
36
|
```
|
|
49
37
|
|
|
50
|
-
|
|
38
|
+
### Configuration
|
|
51
39
|
|
|
52
40
|
You can generate configuration template:
|
|
53
41
|
|
|
@@ -57,23 +45,52 @@ $ fluent-plugin-config-format input jfrog-siem
|
|
|
57
45
|
|
|
58
46
|
You can copy and paste generated documents here.
|
|
59
47
|
|
|
60
|
-
|
|
48
|
+
## Installation
|
|
61
49
|
|
|
62
|
-
|
|
50
|
+
### RubyGems
|
|
51
|
+
```
|
|
52
|
+
$ gem install rest-client
|
|
53
|
+
```
|
|
54
|
+
```
|
|
55
|
+
$ gem install thread
|
|
56
|
+
```
|
|
57
|
+
```
|
|
58
|
+
$ gem install fluent-plugin-jfrog-siem
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Setup & configuration
|
|
62
|
+
Fluentd is the supported log collector for this integration.
|
|
63
|
+
For Fluentd setup and information, read the JFrog log analytics repository's [README.](https://github.com/jfrog/log-analytics/blob/master/README.md)
|
|
64
|
+
|
|
65
|
+
#### Fluentd Output
|
|
66
|
+
Download fluentd conf for different log-vendors. For example
|
|
67
|
+
Splunk:
|
|
63
68
|
|
|
69
|
+
Splunk setup can be found at [README.](https://github.com/jfrog/log-analytics-splunk/blob/master/README.md)
|
|
70
|
+
````text
|
|
71
|
+
wget https://raw.githubusercontent.com/jfrog/log-analytics/master/fluentd/plugins/input/fluent-plugin-jfrog-siem/splunk.conf
|
|
72
|
+
````
|
|
73
|
+
Elasticsearch:
|
|
74
|
+
|
|
75
|
+
Elasticsearch Kibana setup can be found at [README.](https://github.com/jfrog/log-analytics-elastic/blob/master/README.md)
|
|
76
|
+
````text
|
|
77
|
+
wget https://raw.githubusercontent.com/jfrog/log-analytics/master/fluentd/plugins/input/fluent-plugin-jfrog-siem/elastic.conf
|
|
78
|
+
````
|
|
79
|
+
|
|
80
|
+
#### Configuration parameters
|
|
81
|
+
Integration is done by setting up Xray. Obtain JPD url and access token for API. Configure the source directive parameters specified below
|
|
64
82
|
* **tag** (string) (required): The value is the tag assigned to the generated events.
|
|
65
83
|
* **jpd_url** (string) (required): JPD url required to pull Xray SIEM violations
|
|
66
84
|
* **access_token** (string) (required): [Access token](https://www.jfrog.com/confluence/display/JFROG/Access+Tokens) to authenticate Xray
|
|
67
85
|
* **pos_file** (string) (required): Position file to record last SIEM violation pulled
|
|
68
86
|
* **batch_size** (integer) (optional): Batch size for processing violations
|
|
69
|
-
* Default value: `25
|
|
87
|
+
* Default value: `25`
|
|
70
88
|
* **thread_count** (integer) (optional): Number of workers to process violation records in thread pool
|
|
71
|
-
* Default value: `5
|
|
89
|
+
* Default value: `5`
|
|
72
90
|
* **wait_interval** (integer) (optional): Wait interval between pulling new events
|
|
73
|
-
* Default value: `60
|
|
91
|
+
* Default value: `60`
|
|
74
92
|
|
|
75
93
|
## Copyright
|
|
76
|
-
|
|
77
94
|
* Copyright(c) 2020 - JFrog
|
|
78
95
|
* License
|
|
79
96
|
* Apache License, Version 2.0
|
data/elastic.conf
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<source>
|
|
2
|
+
@type jfrog_siem
|
|
3
|
+
tag elastic_jfrog
|
|
4
|
+
jpd_url <jpd_url>
|
|
5
|
+
access_token <access_token>
|
|
6
|
+
pos_file "elastic_pos.txt"
|
|
7
|
+
</source>
|
|
8
|
+
<match elastic*>
|
|
9
|
+
@type elasticsearch
|
|
10
|
+
@id elasticsearch
|
|
11
|
+
host elasticsearch
|
|
12
|
+
port 9200
|
|
13
|
+
user <username>
|
|
14
|
+
password <password>
|
|
15
|
+
index_name xray_siem
|
|
16
|
+
include_tag_key true
|
|
17
|
+
type_name fluentd
|
|
18
|
+
</match>
|
|
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |spec|
|
|
5
5
|
spec.name = "fluent-plugin-jfrog-siem"
|
|
6
|
-
spec.version = "0.1.
|
|
6
|
+
spec.version = "0.1.6"
|
|
7
7
|
spec.authors = ["John Peterson", "Mahitha Byreddy"]
|
|
8
8
|
spec.email = ["johnp@jfrog.com", "mahithab@jfrog.com"]
|
|
9
9
|
|
|
@@ -24,5 +24,7 @@ Gem::Specification.new do |spec|
|
|
|
24
24
|
spec.add_development_dependency "rake", "~> 12.0"
|
|
25
25
|
spec.add_development_dependency "test-unit", "~> 3.0"
|
|
26
26
|
spec.add_development_dependency "rest-client", "~> 2.0"
|
|
27
|
+
spec.add_development_dependency "thread", "~> 0.2.2"
|
|
28
|
+
spec.add_runtime_dependency "thread", "~> 0.2.2"
|
|
27
29
|
spec.add_runtime_dependency "fluentd", [">= 0.14.10", "< 2"]
|
|
28
30
|
end
|
|
@@ -99,6 +99,7 @@ module Fluent
|
|
|
99
99
|
end
|
|
100
100
|
offset_count=1
|
|
101
101
|
left_violations=0
|
|
102
|
+
waiting_for_violations = false
|
|
102
103
|
xray_json={"filters": { "created_from": last_created_date }, "pagination": {"order_by": "created","limit": @batch_size ,"offset": offset_count } }
|
|
103
104
|
|
|
104
105
|
while true
|
|
@@ -120,8 +121,16 @@ module Fluent
|
|
|
120
121
|
|
|
121
122
|
# Determine if we need to persist this record or not
|
|
122
123
|
persistItem = true
|
|
123
|
-
if
|
|
124
|
-
|
|
124
|
+
if waiting_for_violations
|
|
125
|
+
if created_date <= last_created_date
|
|
126
|
+
# "not persisting it - waiting for violations"
|
|
127
|
+
persistItem = false
|
|
128
|
+
end
|
|
129
|
+
else
|
|
130
|
+
if created_date < last_created_date
|
|
131
|
+
# "persisting everything"
|
|
132
|
+
persistItem = true
|
|
133
|
+
end
|
|
125
134
|
end
|
|
126
135
|
|
|
127
136
|
# Publish the record to fluentd
|
|
@@ -148,20 +157,21 @@ module Fluent
|
|
|
148
157
|
# iterate over url array adding to thread pool each url.
|
|
149
158
|
# limit max workers to thread count to prevent overloading xray.
|
|
150
159
|
thread_pool = Thread.pool(thread_count)
|
|
151
|
-
|
|
152
|
-
|
|
160
|
+
thread_pool.process {
|
|
161
|
+
for xray_violation_url in xray_violation_urls_list do
|
|
153
162
|
pull_violation_details(xray_violation_url, @access_token)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
163
|
+
end
|
|
164
|
+
}
|
|
157
165
|
thread_pool.shutdown
|
|
158
166
|
|
|
159
167
|
# reduce left violations by jump size (not all batches have full item count??)
|
|
160
168
|
left_violations = left_violations - @batch_size
|
|
161
169
|
if left_violations <= 0
|
|
170
|
+
waiting_for_violations = true
|
|
162
171
|
sleep(@wait_interval)
|
|
163
172
|
else
|
|
164
173
|
# Grab the next record to process for the violation details url
|
|
174
|
+
waiting_for_violations = false
|
|
165
175
|
offset_count = offset_count + 1
|
|
166
176
|
xray_json={"filters": { "created_from": last_created_date_string }, "pagination": {"order_by": "created","limit": @batch_size , "offset": offset_count } }
|
|
167
177
|
end
|
|
@@ -227,33 +237,45 @@ module Fluent
|
|
|
227
237
|
# normalizes Xray data according to common information models for all log-vendors
|
|
228
238
|
def data_normalization(detailResp)
|
|
229
239
|
detailResp_json = JSON.parse(detailResp)
|
|
230
|
-
properties = detailResp_json['properties']
|
|
231
240
|
cve = []
|
|
232
241
|
cvss_v2_list = []
|
|
233
242
|
cvss_v3_list = []
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
243
|
+
impacted_artifact_url_list = []
|
|
244
|
+
if detailResp_json.key?('properties')
|
|
245
|
+
properties = detailResp_json['properties']
|
|
246
|
+
for index in 0..properties.length-1 do
|
|
247
|
+
if properties[index].key?('cve')
|
|
248
|
+
cve.push(properties[index]['cve'])
|
|
249
|
+
end
|
|
250
|
+
if properties[index].key?('cvss_v2')
|
|
251
|
+
cvss_v2_list.push(properties[index]['cvss_v2'])
|
|
252
|
+
end
|
|
253
|
+
if properties[index].key?('cvss_v3')
|
|
254
|
+
cvss_v3_list.push(properties[index]['cvss_v3'])
|
|
255
|
+
end
|
|
240
256
|
end
|
|
241
|
-
|
|
242
|
-
|
|
257
|
+
|
|
258
|
+
detailResp_json["cve"] = cve.sort.reverse[0]
|
|
259
|
+
cvss_v2 = cvss_v2_list.sort.reverse[0]
|
|
260
|
+
cvss_v3 = cvss_v3_list.sort.reverse[0]
|
|
261
|
+
if !cvss_v3.nil?
|
|
262
|
+
cvss = cvss_v3
|
|
263
|
+
elsif !cvss_v2.nil?
|
|
264
|
+
cvss = cvss_v2
|
|
243
265
|
end
|
|
266
|
+
cvss_score = cvss[0..2]
|
|
267
|
+
cvss_version = cvss.split(':')[1][0..2]
|
|
268
|
+
detailResp_json["cvss_score"] = cvss_score
|
|
269
|
+
detailResp_json["cvss_version"] = cvss_version
|
|
244
270
|
end
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
cvss = cvss_v2
|
|
271
|
+
|
|
272
|
+
impacted_artifacts = detailResp_json['impacted_artifacts']
|
|
273
|
+
for impacted_artifact in impacted_artifacts do
|
|
274
|
+
matchdata = impacted_artifact.match /default\/(?<repo_name>[^\/]*)\/(?<path>.*)/
|
|
275
|
+
impacted_artifact_url = matchdata['repo_name'] + ":" + matchdata['path'] + " "
|
|
276
|
+
impacted_artifact_url_list.append(impacted_artifact_url)
|
|
252
277
|
end
|
|
253
|
-
|
|
254
|
-
cvss_version = cvss.split(':')[1][0..2]
|
|
255
|
-
detailResp_json["cvss_score"] = cvss_score
|
|
256
|
-
detailResp_json["cvss_version"] = cvss_version
|
|
278
|
+
detailResp_json['impacted_artifacts_url'] = impacted_artifact_url_list
|
|
257
279
|
return detailResp_json
|
|
258
280
|
end
|
|
259
281
|
|
data/splunk.conf
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<source>
|
|
2
|
+
@type jfrog_siem
|
|
3
|
+
tag splunk_jfrog
|
|
4
|
+
jpd_url <jpd_url>
|
|
5
|
+
access_token <access_token>
|
|
6
|
+
pos_file "splunk_pos.txt"
|
|
7
|
+
</source>
|
|
8
|
+
<match splunk*>
|
|
9
|
+
@type splunk_hec
|
|
10
|
+
host HEC_HOST
|
|
11
|
+
port HEC_PORT
|
|
12
|
+
token HEC_TOKEN
|
|
13
|
+
format json
|
|
14
|
+
sourcetype_key log_source
|
|
15
|
+
use_fluentd_time false
|
|
16
|
+
index violations
|
|
17
|
+
flush_interval 10s
|
|
18
|
+
</match>
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fluent-plugin-jfrog-siem
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- John Peterson
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2021-04-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: bundler
|
|
@@ -67,6 +67,34 @@ dependencies:
|
|
|
67
67
|
- - "~>"
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
69
|
version: '2.0'
|
|
70
|
+
- !ruby/object:Gem::Dependency
|
|
71
|
+
name: thread
|
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - "~>"
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: 0.2.2
|
|
77
|
+
type: :development
|
|
78
|
+
prerelease: false
|
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
80
|
+
requirements:
|
|
81
|
+
- - "~>"
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: 0.2.2
|
|
84
|
+
- !ruby/object:Gem::Dependency
|
|
85
|
+
name: thread
|
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
|
87
|
+
requirements:
|
|
88
|
+
- - "~>"
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: 0.2.2
|
|
91
|
+
type: :runtime
|
|
92
|
+
prerelease: false
|
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
94
|
+
requirements:
|
|
95
|
+
- - "~>"
|
|
96
|
+
- !ruby/object:Gem::Version
|
|
97
|
+
version: 0.2.2
|
|
70
98
|
- !ruby/object:Gem::Dependency
|
|
71
99
|
name: fluentd
|
|
72
100
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -100,8 +128,10 @@ files:
|
|
|
100
128
|
- LICENSE
|
|
101
129
|
- README.md
|
|
102
130
|
- Rakefile
|
|
131
|
+
- elastic.conf
|
|
103
132
|
- fluent-plugin-jfrog-siem.gemspec
|
|
104
133
|
- lib/fluent/plugin/in_jfrog_siem.rb
|
|
134
|
+
- splunk.conf
|
|
105
135
|
- test/helper.rb
|
|
106
136
|
- test/plugin/test_in_jfrog_siem.rb
|
|
107
137
|
homepage: https://github.com/jfrog/log-analytics
|