class Chef::Knife::SslCheck
Public Class Methods
new(*args)
click to toggle source
Calls superclass method
Chef::Knife::new
# File lib/chef/knife/ssl_check.rb, line 39 def initialize(*args) @host = nil @verify_peer_socket = nil @ssl_policy = HTTP::DefaultSSLPolicy super end
Public Instance Methods
configuration()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 243 def configuration Chef::Config end
debug_chef_ssl_config()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 236 def debug_chef_ssl_config ui.err "#{ChefUtils::Dist::Infra::PRODUCT} 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_X509(cert_debug_msg)
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 150 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 # @TODO: ^ needs URL once documentation is posted. end
debug_invalid_cert()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 179 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 #{ChefUtils::Dist::Infra::PRODUCT} 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()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 207 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_ssl_settings()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 229 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()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 53 def given_uri (name_args[0] || Chef::Config.chef_server_url) end
host()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 57 def host uri.host end
invalid_uri!()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 73 def invalid_uri! ui.error("Given URI: `#{given_uri}' is invalid") show_usage exit 1 end
noverify_peer_ssl_context()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 104 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()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 97 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()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 61 def port uri.port end
run()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 247 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()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 46 def uri @uri ||= begin Chef::Log.trace("Checking SSL cert on #{given_uri}") URI.parse(given_uri) end end
validate_uri()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 65 def validate_uri unless host && port invalid_uri! end rescue URI::Error invalid_uri! end
verify_X509()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 113 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 # Maybe the bad certs won't hurt... end
verify_cert()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 129 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.trace e.message debug_invalid_cert false end
verify_cert_host()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 140 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.trace(e) debug_invalid_host false end
verify_peer_socket()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 79 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()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 88 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
Private Instance Methods
check_X509_certificate(cert_file)
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 268 def check_X509_certificate(cert_file) store = OpenSSL::X509::Store.new cert = OpenSSL::X509::Certificate.new(IO.read(File.expand_path(cert_file))) begin store.add_cert(cert) # test if the store can verify the cert we just added unless store.verify(cert) # true if verified, false if not return store.error_string end rescue OpenSSL::X509::StoreError => e return e.message end nil end
trusted_certificates()
click to toggle source
# File lib/chef/knife/ssl_check.rb, line 259 def trusted_certificates if configuration.trusted_certs_dir && Dir.exist?(configuration.trusted_certs_dir) glob_dir = ChefConfig::PathHelper.escape_glob_dir(configuration.trusted_certs_dir) Dir.glob(File.join(glob_dir, "*.{crt,pem}")) else [] end end