kube_auto_analyzer 0.0.16 → 0.0.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/kubeautoanalyzer +7 -2
- data/lib/kube_auto_analyzer.rb +14 -6
- data/lib/kube_auto_analyzer/api_checks/authentication_checker.rb +54 -0
- data/lib/kube_auto_analyzer/api_checks/authorization_checker.rb +34 -0
- data/lib/kube_auto_analyzer/api_checks/master_node.rb +1 -2
- data/lib/kube_auto_analyzer/reporting.rb +114 -112
- data/lib/kube_auto_analyzer/version.rb +1 -1
- data/lib/kube_auto_analyzer/vuln_checks/api_server.rb +2 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eea761191dd513070aa5d9ffc5167caa1ad52843859e123b1df799ea477200ee
|
4
|
+
data.tar.gz: ceb2d2e971cdd7d7dc64540cdd94bffbf23ae4a14889b5101532ccac7ceaf6c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ead0e68c63947bec56b073ce0099702354a86bb52994168d7527596202b483ea7bcbf8b8b52c6881823679e83b2de7a4ce8cf0fedd8b295d6cc8381e77751ee
|
7
|
+
data.tar.gz: b34fe9a061933d9fa3f073f1dc16df34608d94989c211183492dc1a0bec7ded5f40ef40afeafd1cc7d1c3a96286fa71e47bc8f71bac062951ac4949faf2de23c
|
data/bin/kubeautoanalyzer
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
options.report_directory = Dir.pwd
|
9
9
|
options.report_file = 'kube-parse-report'
|
10
10
|
options.target_server = 'http://127.0.0.1:8080'
|
11
|
-
options.html_report =
|
11
|
+
options.html_report = true
|
12
12
|
options.json_report = false
|
13
13
|
options.token = ''
|
14
14
|
options.token_file = ''
|
@@ -19,12 +19,13 @@
|
|
19
19
|
options.nosslverify = false
|
20
20
|
options.dump_config = false
|
21
21
|
options.audit_rbac = false
|
22
|
+
options.cluster_version = '1.11'
|
23
|
+
options.cis_audit = false
|
22
24
|
|
23
25
|
opts = OptionParser.new do |opts|
|
24
26
|
opts.banner = "Kubernetes Auto Analyzer #{KubeAutoAnalyzer::VERSION}"
|
25
27
|
|
26
28
|
|
27
|
-
|
28
29
|
#TODO: Need options for different authentication mechanisms
|
29
30
|
opts.on("-c", "--config [CONFIG]", "kubeconfig file to load") do |file|
|
30
31
|
options.config_file = file
|
@@ -58,6 +59,10 @@
|
|
58
59
|
options.token = token
|
59
60
|
end
|
60
61
|
|
62
|
+
opts.on("-a", "--audit [AUDIT]", "CIS Audit against 1.8 Standard") do |audit|
|
63
|
+
options.cis_audit = true
|
64
|
+
end
|
65
|
+
|
61
66
|
opts.on("-j", "--json", "Create a JSON report") do |json|
|
62
67
|
options.json_report = true
|
63
68
|
end
|
data/lib/kube_auto_analyzer.rb
CHANGED
@@ -4,6 +4,8 @@ module KubeAutoAnalyzer
|
|
4
4
|
require "kube_auto_analyzer/api_checks/master_node"
|
5
5
|
require "kube_auto_analyzer/api_checks/config_dumper"
|
6
6
|
require "kube_auto_analyzer/api_checks/rbac_auditor"
|
7
|
+
require "kube_auto_analyzer/api_checks/authentication_checker"
|
8
|
+
require "kube_auto_analyzer/api_checks/authorization_checker"
|
7
9
|
require "kube_auto_analyzer/reporting"
|
8
10
|
require "kube_auto_analyzer/agent_checks/file_checks"
|
9
11
|
require "kube_auto_analyzer/agent_checks/process_checks"
|
@@ -122,18 +124,24 @@ module KubeAutoAnalyzer
|
|
122
124
|
puts "to see what's going wrong."
|
123
125
|
exit
|
124
126
|
end
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
127
|
+
if @options.cis_audit
|
128
|
+
test_api_server
|
129
|
+
test_scheduler
|
130
|
+
test_controller_manager
|
131
|
+
test_etcd
|
132
|
+
end
|
133
|
+
check_authn
|
134
|
+
check_authz
|
129
135
|
test_unauth_kubelet_external
|
130
136
|
test_insecure_api_external
|
131
137
|
if @options.agent_checks
|
132
138
|
test_unauth_kubelet_internal
|
133
139
|
test_insecure_api_internal
|
134
140
|
test_service_token_internal
|
135
|
-
|
136
|
-
|
141
|
+
if @options.cis_audit
|
142
|
+
check_files
|
143
|
+
check_kubelet_process
|
144
|
+
end
|
137
145
|
check_amicontained
|
138
146
|
end
|
139
147
|
if @options.dump_config
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module KubeAutoAnalyzer
|
2
|
+
def self.check_authn
|
3
|
+
@log.debug("Entering the Authentication Checker")
|
4
|
+
target = @options.target_server
|
5
|
+
@log.debug("Checking enabled Authentication Options on #{target}")
|
6
|
+
@results[target][:authn] = Hash.new
|
7
|
+
@results[target]['evidence'] = Hash.new
|
8
|
+
pods = @client.get_pods
|
9
|
+
pods.each do |pod|
|
10
|
+
if pod['metadata']['name'] =~ /kube-apiserver/
|
11
|
+
@api_server = pod
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
api_server_command_line = @api_server['spec']['containers'][0]['command']
|
16
|
+
if api_server_command_line.index{|line| line =~ /--basic-auth-file/}
|
17
|
+
@results[target][:authn][:basic] = true
|
18
|
+
else
|
19
|
+
@results[target][:authn][:basic] = false
|
20
|
+
end
|
21
|
+
|
22
|
+
if api_server_command_line.index{|line| line =~ /--token-auth-file/}
|
23
|
+
@results[target][:authn][:token] = true
|
24
|
+
else
|
25
|
+
@results[target][:authn][:token] = false
|
26
|
+
end
|
27
|
+
|
28
|
+
if api_server_command_line.index{|line| line =~ /--client-ca-file/}
|
29
|
+
@results[target][:authn][:certificate] = true
|
30
|
+
else
|
31
|
+
@results[target][:authn][:certificate] = false
|
32
|
+
end
|
33
|
+
|
34
|
+
if api_server_command_line.index{|line| line =~ /--oidc-issuer-url/}
|
35
|
+
@results[target][:authn][:oidc] = true
|
36
|
+
else
|
37
|
+
@results[target][:authn][:oidc] = false
|
38
|
+
end
|
39
|
+
|
40
|
+
if api_server_command_line.index{|line| line =~ /--authentication-token-webhook-config-file/}
|
41
|
+
@results[target][:authn][:webhook] = true
|
42
|
+
else
|
43
|
+
@results[target][:authn][:webhook] = false
|
44
|
+
end
|
45
|
+
|
46
|
+
if api_server_command_line.index{|line| line =~ /--requestheader-username-headers/}
|
47
|
+
@results[target][:authn][:proxy] = true
|
48
|
+
else
|
49
|
+
@results[target][:authn][:proxy] = false
|
50
|
+
end
|
51
|
+
#Gather evidence for the API server
|
52
|
+
@results[target]['evidence']['API Server'] = api_server_command_line
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module KubeAutoAnalyzer
|
2
|
+
def self.check_authz
|
3
|
+
@log.debug("Entering the authorization checker")
|
4
|
+
target = @options.target_server
|
5
|
+
@log.debug("Checking enabled authorization options on #{target}")
|
6
|
+
@results[target][:authz] = Hash.new
|
7
|
+
pods = @client.get_pods
|
8
|
+
pods.each do |pod|
|
9
|
+
if pod['metadata']['name'] =~ /kube-apiserver/
|
10
|
+
@api_server = pod
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
api_server_command_line = @api_server['spec']['containers'][0]['command']
|
15
|
+
if api_server_command_line.index{|line| line =~ /--authorization-mode\S*RBAC/}
|
16
|
+
@results[target][:authz][:rbac] = true
|
17
|
+
|
18
|
+
else
|
19
|
+
@results[target][:authz][:rbac] = false
|
20
|
+
end
|
21
|
+
|
22
|
+
if api_server_command_line.index{|line| line =~ /--authorization-mode\S*ABAC/}
|
23
|
+
@results[target][:authz][:abac] = true
|
24
|
+
else
|
25
|
+
@results[target][:authz][:abac] = false
|
26
|
+
end
|
27
|
+
|
28
|
+
if api_server_command_line.index{|line| line =~ /--authorization-mode\S*Webhook/}
|
29
|
+
@results[target][:authz][:webhook] = true
|
30
|
+
else
|
31
|
+
@results[target][:authz][:webhook] = false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -5,7 +5,6 @@ module KubeAutoAnalyzer
|
|
5
5
|
target = @options.target_server
|
6
6
|
@log.debug("target is #{target}")
|
7
7
|
@results[target]['api_server'] = Hash.new
|
8
|
-
@results[target]['evidence'] = Hash.new
|
9
8
|
pods = @client.get_pods
|
10
9
|
pods.each do |pod|
|
11
10
|
#Ok this is a bit naive as a means of hitting the API server but hey it's a start
|
@@ -246,7 +245,7 @@ module KubeAutoAnalyzer
|
|
246
245
|
|
247
246
|
#1.1.37 This one is dubious for a pass/fail test as the value should be evaluated against the relity of the cluster.
|
248
247
|
|
249
|
-
|
248
|
+
|
250
249
|
end
|
251
250
|
|
252
251
|
def self.test_scheduler
|
@@ -71,125 +71,127 @@ module KubeAutoAnalyzer
|
|
71
71
|
<body>
|
72
72
|
|
73
73
|
'
|
74
|
-
chartkick_path = File.join(__dir__, "js_files/chartkick.js")
|
75
|
-
chartkick = File.open(chartkick_path).read
|
76
|
-
highcharts_path = File.join(__dir__, "js_files/highcharts.js")
|
77
|
-
highcharts = File.open(highcharts_path).read
|
78
|
-
@html_report_file.puts "<script>#{chartkick}</script>"
|
79
|
-
@html_report_file.puts "<script>#{highcharts}</script>"
|
80
74
|
@html_report_file.puts '<img width="100" height="100" align="right"' + " src=#{logo} />"
|
81
75
|
@html_report_file.puts "<h1>Kubernetes Auto Analyzer</h1>"
|
82
76
|
@html_report_file.puts "<br><b>Server Reviewed : </b> #{@options.target_server}"
|
83
|
-
@
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
77
|
+
if @options.cis_audit
|
78
|
+
chartkick_path = File.join(__dir__, "js_files/chartkick.js")
|
79
|
+
chartkick = File.open(chartkick_path).read
|
80
|
+
highcharts_path = File.join(__dir__, "js_files/highcharts.js")
|
81
|
+
highcharts = File.open(highcharts_path).read
|
82
|
+
@html_report_file.puts "<script>#{chartkick}</script>"
|
83
|
+
@html_report_file.puts "<script>#{highcharts}</script>"
|
84
|
+
@html_report_file.puts '<br><br><div class="master-node"><h2>Master Node Results</h2><br>'
|
85
|
+
#Charting setup counts for the passes and fails
|
86
|
+
api_server_pass = 0
|
87
|
+
api_server_fail = 0
|
88
|
+
@results[@options.target_server]['api_server'].each do |test, result|
|
89
|
+
if result == "Pass"
|
90
|
+
api_server_pass = api_server_pass + 1
|
91
|
+
elsif result == "Fail"
|
92
|
+
api_server_fail = api_server_fail + 1
|
93
|
+
end
|
92
94
|
end
|
93
|
-
end
|
94
95
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
96
|
+
#Not a lot of point in scheduler when there's only one check...
|
97
|
+
#scheduler_pass = 0
|
98
|
+
#scheduler_fail = 0
|
99
|
+
#@results[@options.target_server]['scheduler'].each do |test, result|
|
100
|
+
# if result == "Pass"
|
101
|
+
# scheduler_pass = scheduler_pass + 1
|
102
|
+
# elsif result == "Fail"
|
103
|
+
# scheduler_fail = scheduler_fail + 1
|
104
|
+
# end
|
105
|
+
#end
|
106
|
+
|
107
|
+
controller_manager_pass = 0
|
108
|
+
controller_manager_fail = 0
|
109
|
+
@results[@options.target_server]['controller_manager'].each do |test, result|
|
110
|
+
if result == "Pass"
|
111
|
+
controller_manager_pass = controller_manager_pass + 1
|
112
|
+
elsif result == "Fail"
|
113
|
+
controller_manager_fail = controller_manager_fail + 1
|
114
|
+
end
|
113
115
|
end
|
114
|
-
end
|
115
116
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
117
|
+
etcd_pass = 0
|
118
|
+
etcd_fail = 0
|
119
|
+
@results[@options.target_server]['etcd'].each do |test, result|
|
120
|
+
if result == "Pass"
|
121
|
+
etcd_pass = etcd_pass + 1
|
122
|
+
elsif result == "Fail"
|
123
|
+
etcd_fail = etcd_fail + 1
|
124
|
+
end
|
123
125
|
end
|
124
|
-
end
|
125
126
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
127
|
+
#Start of Chart Divs
|
128
|
+
@html_report_file.puts '<div class="container">'
|
129
|
+
#API Server Chart
|
130
|
+
@html_report_file.puts '<div class="fixed" id="chart-1" style="height: 300px; width: 300px; text-align: center; color: #999; line-height: 300px; font-size: 14px;font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;"></div>'
|
131
|
+
@html_report_file.puts '<script>new Chartkick.PieChart("chart-1", {"pass": ' + api_server_pass.to_s + ', "fail": ' + api_server_fail.to_s + '}, {"colors":["green","red"], "library":{"title":{"text":"API Server Results"},"chart":{"backgroundColor":"#F5F5F5"}}})</script>'
|
132
|
+
#Scheduler Chart
|
133
|
+
#@html_report_file.puts '<div class="flex-item" id="chart-2" style="height: 300px; width: 300px; text-align: center; color: #999; line-height: 300px; font-size: 14px;font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;"></div>'
|
134
|
+
#@html_report_file.puts '<script>new Chartkick.PieChart("chart-2", {"pass": ' + scheduler_pass.to_s + ', "fail": ' + scheduler_fail.to_s + '}, {"colors":["green","red"], "library":{"title":{"text":"Scheduler Results"},"chart":{"backgroundColor":"#F5F5F5"}}})</script>'
|
135
|
+
#Controller Manager Chart
|
136
|
+
@html_report_file.puts '<div class="fixed" id="chart-2" style="height: 300px; width: 300px; text-align: center; color: #999; line-height: 300px; font-size: 14px;font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;"></div>'
|
137
|
+
@html_report_file.puts '<script>new Chartkick.PieChart("chart-2", {"pass": ' + controller_manager_pass.to_s + ', "fail": ' + controller_manager_fail.to_s + '}, {"colors":["green","red"], "library":{"title":{"text":"Controller Manager Results"},"chart":{"backgroundColor":"#F5F5F5"}}})</script>'
|
138
|
+
#etcd Chart
|
139
|
+
@html_report_file.puts '<div class="fixed" id="chart-3" style="height: 300px; width: 300px; text-align: center; color: #999; line-height: 300px; font-size: 14px;font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;"></div>'
|
140
|
+
@html_report_file.puts '<script>new Chartkick.PieChart("chart-3", {"pass": ' + etcd_pass.to_s + ', "fail": ' + etcd_fail.to_s + '}, {"colors":["green","red"], "library":{"title":{"text":"etcd Results"},"chart":{"backgroundColor":"#F5F5F5"}}})</script>'
|
141
|
+
#End of Chart Divs
|
142
|
+
@html_report_file.puts '</div>'
|
143
|
+
@html_report_file.puts "<h2>API Server</h2>"
|
144
|
+
@html_report_file.puts "<table><thead><tr><th>Check</th><th>result</th></tr></thead>"
|
145
|
+
@results[@options.target_server]['api_server'].each do |test, result|
|
146
|
+
if result == "Fail"
|
147
|
+
result = '<span style="color:red;">Fail</span>'
|
148
|
+
elsif result == "Pass"
|
149
|
+
result = '<span style="color:green;">Pass</span>'
|
150
|
+
end
|
151
|
+
@html_report_file.puts "<tr><td>#{test}</td><td>#{result}</td></tr>"
|
149
152
|
end
|
150
|
-
@html_report_file.puts "
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
153
|
+
@html_report_file.puts "</table>"
|
154
|
+
@html_report_file.puts "<br><br>"
|
155
|
+
@html_report_file.puts "<br><br><h2>Scheduler</h2>"
|
156
|
+
@html_report_file.puts "<table><thead><tr><th>Check</th><th>result</th></tr></thead>"
|
157
|
+
@results[@options.target_server]['scheduler'].each do |test, result|
|
158
|
+
if result == "Fail"
|
159
|
+
result = '<span style="color:red;">Fail</span>'
|
160
|
+
elsif result == "Pass"
|
161
|
+
result = '<span style="color:green;">Pass</span>'
|
162
|
+
end
|
163
|
+
@html_report_file.puts "<tr><td>#{test}</td><td>#{result}</td></tr>"
|
161
164
|
end
|
162
|
-
@html_report_file.puts "
|
163
|
-
end
|
164
|
-
@html_report_file.puts "</table>"
|
165
|
+
@html_report_file.puts "</table>"
|
165
166
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
167
|
+
@html_report_file.puts "<br><br>"
|
168
|
+
@html_report_file.puts "<br><br><h2>Controller Manager</h2>"
|
169
|
+
@html_report_file.puts "<table><thead><tr><th>Check</th><th>result</th></tr></thead>"
|
170
|
+
@results[@options.target_server]['controller_manager'].each do |test, result|
|
171
|
+
if result == "Fail"
|
172
|
+
result = '<span style="color:red;">Fail</span>'
|
173
|
+
elsif result == "Pass"
|
174
|
+
result = '<span style="color:green;">Pass</span>'
|
175
|
+
end
|
176
|
+
@html_report_file.puts "<tr><td>#{test}</td><td>#{result}</td></tr>"
|
174
177
|
end
|
175
|
-
@html_report_file.puts "
|
176
|
-
end
|
177
|
-
@html_report_file.puts "</table>"
|
178
|
+
@html_report_file.puts "</table>"
|
178
179
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
180
|
+
@html_report_file.puts "<br><br>"
|
181
|
+
@html_report_file.puts "<br><br><h2>etcd</h2>"
|
182
|
+
@html_report_file.puts "<table><thead><tr><th>Check</th><th>result</th></tr></thead>"
|
183
|
+
@results[@options.target_server]['etcd'].each do |test, result|
|
184
|
+
if result == "Fail"
|
185
|
+
result = '<span style="color:red;">Fail</span>'
|
186
|
+
elsif result == "Pass"
|
187
|
+
result = '<span style="color:green;">Pass</span>'
|
188
|
+
end
|
189
|
+
@html_report_file.puts "<tr><td>#{test}</td><td>#{result}</td></tr>"
|
187
190
|
end
|
188
|
-
@html_report_file.puts "
|
191
|
+
@html_report_file.puts "</table>"
|
192
|
+
#Close the master Node Div
|
193
|
+
@html_report_file.puts "</table></div>"
|
189
194
|
end
|
190
|
-
@html_report_file.puts "</table>"
|
191
|
-
#Close the master Node Div
|
192
|
-
@html_report_file.puts "</table></div>"
|
193
195
|
|
194
196
|
|
195
197
|
if @options.agent_checks
|
@@ -378,35 +380,35 @@ module KubeAutoAnalyzer
|
|
378
380
|
@html_report_file.puts "<br><br><h1>Kubernetes Cluster Information</h1>"
|
379
381
|
@html_report_file.puts "<br><br><h2>Kubernetes Authentication Options</h2>"
|
380
382
|
@html_report_file.puts "<table><thead><tr><th>Authentication Option</th><th>Enabled?</th></tr></thead>"
|
381
|
-
if @results[@options.target_server][
|
383
|
+
if @results[@options.target_server][:authn][:basic] == true
|
382
384
|
@html_report_file.puts "<tr><td>Basic Authentication</td><td>Enabled</td></tr>"
|
383
385
|
else
|
384
386
|
@html_report_file.puts "<tr><td>Basic Authentication</td><td>Disabled</td></tr>"
|
385
387
|
end
|
386
|
-
if @results[@options.target_server][
|
388
|
+
if @results[@options.target_server][:authn][:token] == true
|
387
389
|
@html_report_file.puts "<tr><td>Token Authentication</td><td>Enabled</td></tr>"
|
388
390
|
else
|
389
391
|
@html_report_file.puts "<tr><td>Token Authentication</td><td>Disabled</td></tr>"
|
390
392
|
end
|
391
|
-
if @results[@options.target_server][
|
393
|
+
if @results[@options.target_server][:authn][:certificate] == true
|
392
394
|
@html_report_file.puts "<tr><td>Client Certificate Authentication</td><td>Enabled</td></tr>"
|
393
395
|
else
|
394
396
|
@html_report_file.puts "<tr><td>Client Certificate Authentication</td><td>Disabled</td></tr>"
|
395
397
|
end
|
396
398
|
|
397
|
-
if @results[@options.target_server][
|
399
|
+
if @results[@options.target_server][:authn][:oidc] == true
|
398
400
|
@html_report_file.puts "<tr><td>OpenID Connect Authentication</td><td>Enabled</td></tr>"
|
399
401
|
else
|
400
402
|
@html_report_file.puts "<tr><td>OpenID Connect Authentication</td><td>Disabled</td></tr>"
|
401
403
|
end
|
402
404
|
|
403
|
-
if @results[@options.target_server][
|
405
|
+
if @results[@options.target_server][:authn][:webhook] == true
|
404
406
|
@html_report_file.puts "<tr><td>Webhook Authentication</td><td>Enabled</td></tr>"
|
405
407
|
else
|
406
408
|
@html_report_file.puts "<tr><td>Webhook Authentication</td><td>Disabled</td></tr>"
|
407
409
|
end
|
408
410
|
|
409
|
-
if @results[@options.target_server][
|
411
|
+
if @results[@options.target_server][:authn][:proxy] == true
|
410
412
|
@html_report_file.puts "<tr><td>Proxy Authentication</td><td>Enabled</td></tr>"
|
411
413
|
else
|
412
414
|
@html_report_file.puts "<tr><td>Proxy Authentication</td><td>Disabled</td></tr>"
|
@@ -419,19 +421,19 @@ module KubeAutoAnalyzer
|
|
419
421
|
@html_report_file.puts "<br><br><h2>Kubernetes Authorization Options</h2>"
|
420
422
|
@html_report_file.puts "<table><thead><tr><th>Authorization Option</th><th>Enabled?</th></tr></thead>"
|
421
423
|
|
422
|
-
if @results[@options.target_server][
|
424
|
+
if @results[@options.target_server][:authz][:rbac] == true
|
423
425
|
@html_report_file.puts "<tr><td>Role Based Authorization</td><td>Enabled</td></tr>"
|
424
426
|
else
|
425
427
|
@html_report_file.puts "<tr><td>Role Based Authorization</td><td>Disabled</td></tr>"
|
426
428
|
end
|
427
429
|
|
428
|
-
if @results[@options.target_server][
|
430
|
+
if @results[@options.target_server][:authz][:abac] == true
|
429
431
|
@html_report_file.puts "<tr><td>Attribute Based Authorization</td><td>Enabled</td></tr>"
|
430
432
|
else
|
431
433
|
@html_report_file.puts "<tr><td>Attribute Based Authorization</td><td>Disabled</td></tr>"
|
432
434
|
end
|
433
435
|
|
434
|
-
if @results[@options.target_server][
|
436
|
+
if @results[@options.target_server][:authz][:webhook] == true
|
435
437
|
@html_report_file.puts "<tr><td>Webhook Authorization</td><td>Enabled</td></tr>"
|
436
438
|
else
|
437
439
|
@html_report_file.puts "<tr><td>Webhook Authorization</td><td>Disabled</td></tr>"
|
@@ -18,6 +18,8 @@ module KubeAutoAnalyzer
|
|
18
18
|
pods_resp = RestClient::Request.execute(:url => "http://#{nod}:8080/api",:method => :get)
|
19
19
|
rescue RestClient::Forbidden
|
20
20
|
pods_resp = "Not Vulnerable - Request Forbidden"
|
21
|
+
rescue RestClient::NotFound
|
22
|
+
pods_resp = "Not Vulnerable - Request Not Found"
|
21
23
|
end
|
22
24
|
@results[target]['vulns']['insecure_api_external'][nod] = pods_resp
|
23
25
|
else
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kube_auto_analyzer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rory McCune
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -67,6 +67,8 @@ files:
|
|
67
67
|
- lib/kube_auto_analyzer.rb
|
68
68
|
- lib/kube_auto_analyzer/agent_checks/file_checks.rb
|
69
69
|
- lib/kube_auto_analyzer/agent_checks/process_checks.rb
|
70
|
+
- lib/kube_auto_analyzer/api_checks/authentication_checker.rb
|
71
|
+
- lib/kube_auto_analyzer/api_checks/authorization_checker.rb
|
70
72
|
- lib/kube_auto_analyzer/api_checks/config_dumper.rb
|
71
73
|
- lib/kube_auto_analyzer/api_checks/master_node.rb
|
72
74
|
- lib/kube_auto_analyzer/api_checks/rbac_auditor.rb
|
@@ -101,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
103
|
version: '0'
|
102
104
|
requirements: []
|
103
105
|
rubyforge_project:
|
104
|
-
rubygems_version:
|
106
|
+
rubygems_version: 3.0.0.beta3
|
105
107
|
signing_key:
|
106
108
|
specification_version: 4
|
107
109
|
summary: A Gem which provides a script and class analyze the security of a Kubernetes
|