chef-boneyard / chef-provisioning

A library for creating machines and infrastructures idempotently in Chef.
Apache License 2.0
524 stars 164 forks source link

trusted_certs directory not copied to provisioning node #237

Open ghost opened 9 years ago

ghost commented 9 years ago

Hello,

When using a Private Chef server instance + self-signed certificate, the provisioning node reports the following certificate verification failure:

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

I believe this is due to the trusted_certs directory not being copied to the provisioning node during the chef run.

Additionally, I'm using @andrewelizondo's fork of chef-provisioning, which fixes #232 .

Thank you!

figadore commented 9 years ago

Any update on this? Or workarounds to use for now?

wardviaene commented 9 years ago

I'm experiencing the same issue. Any updates or workarounds?

squaresurf commented 9 years ago

You could specify the certs explicitly like so:

machine 'server' do
  file '/etc/chef/trusted_certs/cert_name.crt', '/local/path/to/cert/cert_name.crt'
end
wardviaene commented 9 years ago

thanks @squaresurf, that works!

squaresurf commented 9 years ago

Glad to help :smile:

joelwilson commented 9 years ago

I really hope this gets implemented!

jkeiser commented 9 years ago

Looks 1.0-worthy to me, for multiple reasons.

jslusher commented 9 years ago

+1 on getting the crt file to the client as part of the provisioning. Thanks @squaresurf for the workaround. That does the trick!

nhudacin commented 8 years ago

+1 here too... Just started using chef-provisioning and immediately hit this because our chef server is private hosted with a self signed cert.

bwmcbride commented 8 years ago

I wonder if I'm having a related problem. I have a chef server (version 11.1.5 so not new) with a self signed certificate. I'm running a simple provision of a single (aws) machine. The provisioning machine is my laptop and the provisioner is running with chef zero. The machine resource is set to use my chef server - the one with the self signed certificate.

The machine resource is failing to retrieve the node object for the machine it is trying to create. Looking at the nginx logs on the chef server, I can see the request for the node object, but it is routed to the webui and then redirected to the login page on the webui and that returns a 500 error. Here are the nginx log entries:

213.123.52.202 - - [07/Apr/2016:14:57:23 +0000] "GET /nodes/mario-aws HTTP/1.1" 302 "0.003" 128 "-" "Chef Knife/12.3.0 (ruby-2.1.5-p273; ohai-8.3.0; x86_64-linux; +http://opscode.com)" "127.0.0.1:9462" "302" "0.003" "12.3.0" "-" "-" "-" "-" 354
213.123.52.202 - - [07/Apr/2016:14:57:24 +0000] "GET /users/login HTTP/1.1" 500 "0.005" 11 "-" "Chef Knife/12.3.0 (ruby-2.1.5-p273; ohai-8.3.0; x86_64-linux; +http://opscode.com)" "127.0.0.1:9462" "500" "0.005" "12.3.0" "-" "-" "-" "-" 350

Knife works fine:

"GET /nodes HTTP/1.1" 200 "0.006" 620 "-" "Chef Knife/12.3.0 (ruby-2.1.5-p273; ohai-8.3.0; x86_64-linux; +http://opscode.com)" "127.0.0.1:8000" "200" "0.006" "12.3.0" "algorithm=sha1;version=1.0;" "epimorph" "2016-04-07T14:58:56Z" "2jmj7l5rSw0yVb/vlWAYkK/YBwk=" 996

I notice there is a different port number in the log entries.

The UI logs contain

2016-04-07_13:56:03.98509 Started GET "/nodes/mario-aws" for 213.123.52.202 at 2016-04-07 13:56:03 +0000
2016-04-07_13:56:03.98510 Processing by NodesController#show as JSON
2016-04-07_13:56:03.98511 Parameters: {"id"=>"mario-aws"}
2016-04-07_13:56:03.98511 Redirected to https://foo.net/users/login

after running chef-client. I've tried the workarounds mentioned here, but no change.

Getting a bit stumped, so any help appreciated.

chazzly commented 8 years ago

+1 on this. I'm having this same issue, but the work-around above suggested by @squaresurf isn't working for me, however. I'm creating a Windows box and it will transfer the file if I point it to c:\chef, but I can't get it to create the trusted_certs directory. I've been looking for a similar method to create the directory first, but I'm not finding one. Any suggestions welcome.

stuartpreston commented 8 years ago

@chassly I had a similar issue working with a customer through this today, we ended up doing something like (from memory):

machine 'machine1' do
  action :allocate
end

machine_execute 'mkdir c:\\chef\\trusted_certs'
  machine 'machine1'
end

machine 'machine1' do
  files 'c:\\chef\\trusted_certs\myfqdn_mydomain_com.crt' => '/etc/chef/trusted_certs/myfqdn.mydomain.com',
        'c:\\chef\\trusted_certs\myca.crt' => '/etc/chef/trusted_certs/myca.crt',
        'c:\\chef\\trusted_certs\myroot.crt' => '/etc/chef/trusted_certs/myroot.crt'
  action :converge
end

I also noticed that the individual file copy operations silently failed and think they shouldn't when the directory doesn't exist, I think a separate issue should be raised for this.

chazzly commented 8 years ago

@stuartpreston, thanks that did the trick, though it does cause a failure on any subsequent runs (which may or may not be an issue depending on your usage).

I also opened #522 for the copy operation silently failing.

chazzly commented 8 years ago

It's also worth noting that I had to change the first machine resource to :setup rather than :allocate.

pozieblo commented 8 years ago

Inspired by the fix presented by @stuartpreston I did some research and ended up fixing the ssh driver by appending few lines to the original ready_machine method.

require 'chef/provisioning/ssh_driver/driver'

class Chef
  module Provisioning
    module SshDriver
      class Driver < Chef::Provisioning::Driver
        alias_method :super_ready_machine, :ready_machine
        attr_accessor :cert_names
        # Find all local SSL trusted certificates to be uploaded
        @@cert_names = []
        Dir.foreach(Chef::Config['trusted_certs_dir']) do |item|
          if item.end_with? '.crt'
            @@cert_names << item
          end
        end

        def ready_machine(action_handler, machine_spec, machine_options)
          machine = super_ready_machine(action_handler, machine_spec, machine_options)
          # Upload self-signed SSL certificates to the machine as 'knife bootstrap' would do
          Chef::Log.info('TEMPORARY FIX: remove this code as soon as chef-provisioning-ssh lib is fixed')
          @@cert_names.each do |cert|
            #TODO Set different path on a Windows node
            machine.upload_file(action_handler, "#{Chef::Config['trusted_certs_dir']}/#{cert}", "/etc/chef/trusted_certs/#{cert}", {:ensure_dir => true})
          end
          machine
        end
      end
    end
  end
end

I placed this code in my_cookbook/libraries directory and that way my recipes remain clean. As soon as the fix will be available for the chef-provisioning-ssh lib itself we can just delete this chunk of code.

It seems to work well in different conditions (existing/unexisting directory, recipe launched multiple times etc.) but I am relatively new to Chef and ruby so any critical comments are welcome.