Class: Chef::Knife::SslCheck
Instance Attribute Summary
Attributes inherited from Chef::Knife
#name_args, #ui
Instance Method Summary
collapse
Methods inherited from Chef::Knife
#api_key, #apply_computed_config, category, chef_config_dir, common_name, #config_file_settings, config_loader, #configure_chef, #create_object, #delete_object, dependency_loaders, deps, #format_rest_error, guess_category, #humanize_exception, #humanize_http_exception, inherited, load_commands, load_config, load_deps, #maybe_setup_fips, #merge_configs, msg, #noauth_rest, #parse_options, reset_config_loader!, reset_subcommands!, #rest, run, #run_with_pretty_exceptions, #server_url, #show_usage, snake_case_name, subcommand_category, subcommand_class_from, subcommand_files, subcommand_loader, subcommands, subcommands_by_category, #test_mandatory_field, ui, unnamed?, use_separate_defaults?, #username
#constantize, #convert_to_class_name, #convert_to_snake_case, #filename_to_qualified_string, #normalize_snake_case_name, #snake_case_basename
#enforce_path_sanity
Constructor Details
#initialize(*args) ⇒ SslCheck
Returns a new instance of SslCheck.
38
39
40
41
42
43
|
# File 'lib/chef/knife/ssl_check.rb', line 38
def initialize(*args)
@host = nil
@verify_peer_socket = nil
@ssl_policy = HTTP::DefaultSSLPolicy
super
end
|
Instance Method Details
#configuration ⇒ Object
242
243
244
|
# File 'lib/chef/knife/ssl_check.rb', line 242
def configuration
Chef::Config
end
|
#debug_chef_ssl_config ⇒ Object
235
236
237
238
239
240
|
# File 'lib/chef/knife/ssl_check.rb', line 235
def debug_chef_ssl_config
ui.err "Chef SSL Configuration:"
ui.err "* ssl_ca_path: #{configuration.ssl_ca_path.inspect}"
ui.err "* ssl_ca_file: #{configuration.ssl_ca_file.inspect}"
ui.err "* trusted_certs_dir: #{configuration.trusted_certs_dir.inspect}"
end
|
#debug_invalid_cert ⇒ Object
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
# File 'lib/chef/knife/ssl_check.rb', line 178
def debug_invalid_cert
noverify_socket.connect
issuer_info = noverify_socket.peer_cert.issuer
ui.msg("Certificate issuer data: #{issuer_info}")
ui.msg("\n#{ui.color("Configuration Info:", :bold)}\n\n")
debug_ssl_settings
debug_chef_ssl_config
ui.err(<<-ADVICE)
#{ui.color("TO FIX THIS ERROR:", :bold)}
If the server you are connecting to uses a self-signed certificate, you must
configure chef to trust that server's certificate.
By default, the certificate is stored in the following location on the host
where your chef-server runs:
/var/opt/opscode/nginx/ca/SERVER_HOSTNAME.crt
Copy that file to your trusted_certs_dir (currently: #{configuration.trusted_certs_dir})
using SSH/SCP or some other secure method, then re-run this command to confirm
that the server's certificate is now trusted.
ADVICE
end
|
#debug_invalid_host ⇒ Object
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
# File 'lib/chef/knife/ssl_check.rb', line 206
def debug_invalid_host
noverify_socket.connect
subject = noverify_socket.peer_cert.subject
cn_field_tuple = subject.to_a.find { |field| field[0] == "CN" }
cn = cn_field_tuple[1]
ui.error("You are attempting to connect to: '#{host}'")
ui.error("The server's certificate belongs to '#{cn}'")
ui.err(<<-ADVICE)
#{ui.color("TO FIX THIS ERROR:", :bold)}
The solution for this issue depends on your networking configuration. If you
are able to connect to this server using the hostname #{cn}
instead of #{host}, then you can resolve this issue by updating chef_server_url
in your configuration file.
If you are not able to connect to the server using the hostname #{cn}
you will have to update the certificate on the server to use the correct hostname.
ADVICE
end
|
#debug_invalid_X509(cert_debug_msg) ⇒ Object
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
# File 'lib/chef/knife/ssl_check.rb', line 149
def debug_invalid_X509(cert_debug_msg)
ui.msg("\n#{ui.color("Configuration Info:", :bold)}\n\n")
debug_ssl_settings
debug_chef_ssl_config
ui.warn(<<-BAD_CERTS)
There are invalid certificates in your trusted_certs_dir.
OpenSSL will not use the following certificates when verifying SSL connections:
#{cert_debug_msg}
#{ui.color("TO FIX THESE WARNINGS:", :bold)}
We are working on documentation for resolving common issues uncovered here.
* If the certificate is generated by the server, you may try redownloading the
server's certificate. By default, the certificate is stored in the following
location on the host where your chef-server runs:
/var/opt/opscode/nginx/ca/SERVER_HOSTNAME.crt
Copy that file to your trusted_certs_dir (currently: #{configuration.trusted_certs_dir})
using SSH/SCP or some other secure method, then re-run this command to confirm
that the server's certificate is now trusted.
BAD_CERTS
end
|
#debug_ssl_settings ⇒ Object
228
229
230
231
232
233
|
# File 'lib/chef/knife/ssl_check.rb', line 228
def debug_ssl_settings
ui.err "OpenSSL Configuration:"
ui.err "* Version: #{OpenSSL::OPENSSL_VERSION}"
ui.err "* Certificate file: #{OpenSSL::X509::DEFAULT_CERT_FILE}"
ui.err "* Certificate directory: #{OpenSSL::X509::DEFAULT_CERT_DIR}"
end
|
#given_uri ⇒ Object
52
53
54
|
# File 'lib/chef/knife/ssl_check.rb', line 52
def given_uri
(name_args[0] || Chef::Config.chef_server_url)
end
|
#host ⇒ Object
56
57
58
|
# File 'lib/chef/knife/ssl_check.rb', line 56
def host
uri.host
end
|
#invalid_uri! ⇒ Object
72
73
74
75
76
|
# File 'lib/chef/knife/ssl_check.rb', line 72
def invalid_uri!
ui.error("Given URI: `#{given_uri}' is invalid")
show_usage
exit 1
end
|
#noverify_peer_ssl_context ⇒ Object
103
104
105
106
107
108
109
110
|
# File 'lib/chef/knife/ssl_check.rb', line 103
def noverify_peer_ssl_context
@noverify_peer_ssl_context ||= begin
noverify_peer_context = OpenSSL::SSL::SSLContext.new
@ssl_policy.apply_to(noverify_peer_context)
noverify_peer_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
noverify_peer_context
end
end
|
#noverify_socket ⇒ Object
96
97
98
99
100
101
|
# File 'lib/chef/knife/ssl_check.rb', line 96
def noverify_socket
@noverify_socket ||= begin
tcp_connection = proxified_socket(host, port)
OpenSSL::SSL::SSLSocket.new(tcp_connection, noverify_peer_ssl_context)
end
end
|
#port ⇒ Object
60
61
62
|
# File 'lib/chef/knife/ssl_check.rb', line 60
def port
uri.port
end
|
#run ⇒ Object
246
247
248
249
250
251
252
253
254
|
# File 'lib/chef/knife/ssl_check.rb', line 246
def run
validate_uri
if verify_X509 && verify_cert && verify_cert_host
ui.msg "Successfully verified certificates from `#{host}'"
else
exit 1
end
end
|
#uri ⇒ Object
45
46
47
48
49
50
|
# File 'lib/chef/knife/ssl_check.rb', line 45
def uri
@uri ||= begin
Chef::Log.debug("Checking SSL cert on #{given_uri}")
URI.parse(given_uri)
end
end
|
#validate_uri ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/chef/knife/ssl_check.rb', line 64
def validate_uri
unless host && port
invalid_uri!
end
rescue URI::Error
invalid_uri!
end
|
#verify_cert ⇒ Object
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/chef/knife/ssl_check.rb', line 128
def verify_cert
ui.msg("Connecting to host #{host}:#{port}")
verify_peer_socket.connect
true
rescue OpenSSL::SSL::SSLError => e
ui.error "The SSL certificate of #{host} could not be verified"
Chef::Log.debug e.message
debug_invalid_cert
false
end
|
#verify_cert_host ⇒ Object
139
140
141
142
143
144
145
146
147
|
# File 'lib/chef/knife/ssl_check.rb', line 139
def verify_cert_host
verify_peer_socket.post_connection_check(host)
true
rescue OpenSSL::SSL::SSLError => e
ui.error "The SSL cert is signed by a trusted authority but is not valid for the given hostname"
Chef::Log.debug(e)
debug_invalid_host
false
end
|
#verify_peer_socket ⇒ Object
78
79
80
81
82
83
84
85
|
# File 'lib/chef/knife/ssl_check.rb', line 78
def verify_peer_socket
@verify_peer_socket ||= begin
tcp_connection = proxified_socket(host, port)
ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_connection, verify_peer_ssl_context)
ssl_client.hostname = host
ssl_client
end
end
|
#verify_peer_ssl_context ⇒ Object
87
88
89
90
91
92
93
94
|
# File 'lib/chef/knife/ssl_check.rb', line 87
def verify_peer_ssl_context
@verify_peer_ssl_context ||= begin
verify_peer_context = OpenSSL::SSL::SSLContext.new
@ssl_policy.apply_to(verify_peer_context)
verify_peer_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
verify_peer_context
end
end
|
#verify_X509 ⇒ Object
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
# File 'lib/chef/knife/ssl_check.rb', line 112
def verify_X509
cert_debug_msg = ""
trusted_certificates.each do |cert_name|
message = check_X509_certificate(cert_name)
unless message.nil?
cert_debug_msg << File.expand_path(cert_name) + ": " + message + "\n"
end
end
unless cert_debug_msg.empty?
debug_invalid_X509(cert_debug_msg)
end
true end
|