kube_auto_analyzer 0.0.16 → 0.0.17

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c660dfe01e6def5a3b1dd095f7adaabb69d008969cc74a324cdfd70dc0dcf6b0
4
- data.tar.gz: 53caa82754a21d6f5f999edb74c9220581b19a2d8eaf3fa9c33614506dd0cbfc
3
+ metadata.gz: eea761191dd513070aa5d9ffc5167caa1ad52843859e123b1df799ea477200ee
4
+ data.tar.gz: ceb2d2e971cdd7d7dc64540cdd94bffbf23ae4a14889b5101532ccac7ceaf6c7
5
5
  SHA512:
6
- metadata.gz: cbb9fb819e5bc084e46f02326984968117a0b735aeac4e0f2719990f80214510f3faeaccc5c634fbf22397d7c4f831d80de23deb075bdecd9199e63bc1c6351b
7
- data.tar.gz: 5aada0ec4b8d64e05b665c105faef30502c34bfcc7d2902a10624fd8abb5d429faa985ca278a26e8c7bc1db2991b5aafdf731ae245c1f38129f53bff870564ba
6
+ metadata.gz: 7ead0e68c63947bec56b073ce0099702354a86bb52994168d7527596202b483ea7bcbf8b8b52c6881823679e83b2de7a4ce8cf0fedd8b295d6cc8381e77751ee
7
+ data.tar.gz: b34fe9a061933d9fa3f073f1dc16df34608d94989c211183492dc1a0bec7ded5f40ef40afeafd1cc7d1c3a96286fa71e47bc8f71bac062951ac4949faf2de23c
@@ -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 = false
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
@@ -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
- test_api_server
126
- test_scheduler
127
- test_controller_manager
128
- test_etcd
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
- check_files
136
- check_kubelet_process
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
- @results[target]['evidence']['API Server'] = api_server_command_line
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
- @html_report_file.puts '<br><br><div class="master-node"><h2>Master Node Results</h2><br>'
84
- #Charting setup counts for the passes and fails
85
- api_server_pass = 0
86
- api_server_fail = 0
87
- @results[@options.target_server]['api_server'].each do |test, result|
88
- if result == "Pass"
89
- api_server_pass = api_server_pass + 1
90
- elsif result == "Fail"
91
- api_server_fail = api_server_fail + 1
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
- #Not a lot of point in scheduler when there's only one check...
96
- #scheduler_pass = 0
97
- #scheduler_fail = 0
98
- #@results[@options.target_server]['scheduler'].each do |test, result|
99
- # if result == "Pass"
100
- # scheduler_pass = scheduler_pass + 1
101
- # elsif result == "Fail"
102
- # scheduler_fail = scheduler_fail + 1
103
- # end
104
- #end
105
-
106
- controller_manager_pass = 0
107
- controller_manager_fail = 0
108
- @results[@options.target_server]['controller_manager'].each do |test, result|
109
- if result == "Pass"
110
- controller_manager_pass = controller_manager_pass + 1
111
- elsif result == "Fail"
112
- controller_manager_fail = controller_manager_fail + 1
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
- etcd_pass = 0
117
- etcd_fail = 0
118
- @results[@options.target_server]['etcd'].each do |test, result|
119
- if result == "Pass"
120
- etcd_pass = etcd_pass + 1
121
- elsif result == "Fail"
122
- etcd_fail = etcd_fail + 1
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
- #Start of Chart Divs
127
- @html_report_file.puts '<div class="container">'
128
- #API Server Chart
129
- @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>'
130
- @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>'
131
- #Scheduler Chart
132
- #@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>'
133
- #@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>'
134
- #Controller Manager Chart
135
- @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>'
136
- @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>'
137
- #etcd Chart
138
- @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>'
139
- @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>'
140
- #End of Chart Divs
141
- @html_report_file.puts '</div>'
142
- @html_report_file.puts "<h2>API Server</h2>"
143
- @html_report_file.puts "<table><thead><tr><th>Check</th><th>result</th></tr></thead>"
144
- @results[@options.target_server]['api_server'].each do |test, result|
145
- if result == "Fail"
146
- result = '<span style="color:red;">Fail</span>'
147
- elsif result == "Pass"
148
- result = '<span style="color:green;">Pass</span>'
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 "<tr><td>#{test}</td><td>#{result}</td></tr>"
151
- end
152
- @html_report_file.puts "</table>"
153
- @html_report_file.puts "<br><br>"
154
- @html_report_file.puts "<br><br><h2>Scheduler</h2>"
155
- @html_report_file.puts "<table><thead><tr><th>Check</th><th>result</th></tr></thead>"
156
- @results[@options.target_server]['scheduler'].each do |test, result|
157
- if result == "Fail"
158
- result = '<span style="color:red;">Fail</span>'
159
- elsif result == "Pass"
160
- result = '<span style="color:green;">Pass</span>'
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 "<tr><td>#{test}</td><td>#{result}</td></tr>"
163
- end
164
- @html_report_file.puts "</table>"
165
+ @html_report_file.puts "</table>"
165
166
 
166
- @html_report_file.puts "<br><br>"
167
- @html_report_file.puts "<br><br><h2>Controller Manager</h2>"
168
- @html_report_file.puts "<table><thead><tr><th>Check</th><th>result</th></tr></thead>"
169
- @results[@options.target_server]['controller_manager'].each do |test, result|
170
- if result == "Fail"
171
- result = '<span style="color:red;">Fail</span>'
172
- elsif result == "Pass"
173
- result = '<span style="color:green;">Pass</span>'
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 "<tr><td>#{test}</td><td>#{result}</td></tr>"
176
- end
177
- @html_report_file.puts "</table>"
178
+ @html_report_file.puts "</table>"
178
179
 
179
- @html_report_file.puts "<br><br>"
180
- @html_report_file.puts "<br><br><h2>etcd</h2>"
181
- @html_report_file.puts "<table><thead><tr><th>Check</th><th>result</th></tr></thead>"
182
- @results[@options.target_server]['etcd'].each do |test, result|
183
- if result == "Fail"
184
- result = '<span style="color:red;">Fail</span>'
185
- elsif result == "Pass"
186
- result = '<span style="color:green;">Pass</span>'
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 "<tr><td>#{test}</td><td>#{result}</td></tr>"
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]['api_server']['CIS 1.1.2 - Ensure that the --basic-auth-file argument is not set'] == "Fail"
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]['api_server']['CIS 1.1.20 - Ensure that the --token-auth-file argument is not set'] == "Fail"
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]['api_server']['CIS 1.1.29 - Ensure that the --client-ca-file argument is set as appropriate'] == "Pass"
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]['evidence']['API Server'].index{|line| line =~ /--oidc-issuer-url/}
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]['evidence']['API Server'].index{|line| line =~ /--authentication-token-webhook-config-file/}
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]['evidence']['API Server'].index{|line| line =~ /--requestheader-username-headers/}
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]['evidence']['API Server'].index{|line| line =~ /--authorization-mode\S*RBAC/}
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]['evidence']['API Server'].index{|line| line =~ /--authorization-mode\S*ABAC/}
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]['evidence']['API Server'].index{|line| line =~ /--authorization-mode\S*Webhook/}
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>"
@@ -1,3 +1,3 @@
1
1
  module KubeAutoAnalyzer
2
- VERSION = "0.0.16"
2
+ VERSION = "0.0.17"
3
3
  end
@@ -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.16
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: 2018-06-18 00:00:00.000000000 Z
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: 2.7.7
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