Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

knife ssl verify/fetch should work with self-signed certificates for winrm hosts #284

Open
hh opened this issue Sep 9, 2015 · 6 comments

Comments

@hh
Copy link
Contributor

hh commented Sep 9, 2015

I'm trying to make it so chef-provisioned windows nodes can communicate safely via winrm over ssl and verify the certificate.

chef-boneyard/chef-provisioning-aws@59ebd0e#commitcomment-13137801

The first step would be to make sure that ``knife ssl fetch/check https://windowshost:5966 works, but I'm running into errors around self-signed certificates.

[chef-repo]$ rm .chef/trusted_certs/*  ; knife ssl fetch https://52.25.104.61:5986 ; knife ssl check https://52.25.104.61:5986 
WARNING: Certificates from 52.25.104.61 will be fetched and placed in your trusted_cert
directory (/home/hh/chef-repo/.chef/trusted_certs).

Knife has no means to verify these are the correct certificates. You should
verify the authenticity of these certificates after downloading.

Adding certificate for WIN-LJ3K78KQPMC in /home/hh/chef-repo/.chef/trusted_certs/WIN-LJ3K78KQPMC.crt

Configuration Info:

OpenSSL Configuration:
* Version: OpenSSL 1.0.2a 19 Mar 2015
* Certificate file: /etc/ssl/cert.pem
* Certificate directory: /etc/ssl/certs
Chef SSL Configuration:
* ssl_ca_path: nil
* ssl_ca_file: nil
* trusted_certs_dir: "/home/hh/chef-repo/.chef/trusted_certs"
WARNING: There are invalid certificates in your trusted_certs_dir.
OpenSSL will not use the following certificates when verifying SSL connections:

/home/hh/chef-repo/.chef/trusted_certs/WIN-LJ3K78KQPMC.crt: self signed certificate


TO FIX THESE WARNINGS:

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: /home/hh/chef-repo/.chef/trusted_certs)
using SSH/SCP or some other secure method, then re-run this command to confirm
that the server's certificate is now trusted.

Connecting to host 52.25.104.61:5986
ERROR: The SSL certificate of 52.25.104.61 could not be verified
Certificate issuer data: /CN=WIN-LJ3K78KQPMC

Configuration Info:

OpenSSL Configuration:
* Version: OpenSSL 1.0.2a 19 Mar 2015
* Certificate file: /etc/ssl/cert.pem
* Certificate directory: /etc/ssl/certs
Chef SSL Configuration:
* ssl_ca_path: nil
* ssl_ca_file: nil
* trusted_certs_dir: "/home/hh/chef-repo/.chef/trusted_certs"

TO FIX THIS ERROR:

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: /home/hh/chef-repo/.chef/trusted_certs)
using SSH/SCP or some other secure method, then re-run this command to confirm
that the server's certificate is now trusted.

@hh
Copy link
Contributor Author

hh commented Sep 9, 2015

I'd think that we would want to make this the default for test-ktichen and any other chef-provisioning drivers that support windows, but we'd need to update the equivalent user_data everywhere. I created chef-boneyard/chef-provisioning-aws#317 to for chef-provisioning, might create tickets for knife and test-kitchen as well.

@hh
Copy link
Contributor Author

hh commented Sep 29, 2015

Cross post from http://lists.opscode.com/sympa/arc/chef/2015-09/msg00289.html

My goal is to securely connect to windows boxes from chef-provisioning (aws),
but I thought I'd try and connect via knife first.

I noticed that even after the knife ssl fetch, knife refuses to use
the self-signed-cert.

* trusted_certs_dir: "/home/hh/provisioning/.chef/trusted_certs"
WARNING: There are invalid certificates in your trusted_certs_dir.
OpenSSL will not use the following certificates when verifying SSL 
connections:

/home/hh/provisioning/.chef/trusted_certs/ip-0A7146CD.crt: self signed
certificate

knife ssl check/fetch/check followed by openssl s_client check:

$ knife ssl check https://10.113.70.205:5986
Connecting to host 10.113.70.205:5986
ERROR: The SSL certificate of 10.113.70.205 could not be verified
Certificate issuer data: /CN=ip-0A7146CD

Configuration Info:

OpenSSL Configuration:
* Version: OpenSSL 1.0.2a 19 Mar 2015
* Certificate file: /etc/ssl/cert.pem
* Certificate directory: /etc/ssl/certs
Chef SSL Configuration:
* ssl_ca_path: nil
* ssl_ca_file: nil
* trusted_certs_dir: "/home/hh/provisioning/.chef/trusted_certs"

TO FIX THIS ERROR:

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:
/home/hh/stratalux/lifelock/misc/provisioning/.chef/trusted_certs)
using SSH/SCP or some other secure method, then re-run this command to confirm
that the server's certificate is now trusted.
$ knife ssl fetch https://10.113.70.205:5986
WARNING: Certificates from 10.113.70.205 will be fetched and placed in
your trusted_cert
directory (/home/hh/provisioning/.chef/trusted_certs).

Knife has no means to verify these are the correct certificates. You should
verify the authenticity of these certificates after downloading.

Adding certificate for ip-0A7146CD in
/home/hh/provisioning/.chef/trusted_certs/ip-0A7146CD.crt
$ knife ssl check https://10.113.70.205:5986

Configuration Info:

OpenSSL Configuration:
* Version: OpenSSL 1.0.2a 19 Mar 2015
* Certificate file: /etc/ssl/cert.pem
* Certificate directory: /etc/ssl/certs
Chef SSL Configuration:
* ssl_ca_path: nil
* ssl_ca_file: nil
* trusted_certs_dir: "/home/hh/provisioning/.chef/trusted_certs"
WARNING: There are invalid certificates in your trusted_certs_dir.
OpenSSL will not use the following certificates when verifying SSL 
connections:

/home/hh/provisioning/.chef/trusted_certs/ip-0A7146CD.crt: self signed
certificate


TO FIX THESE WARNINGS:

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:
/home/hh/misc/provisioning/.chef/trusted_certs)
using SSH/SCP or some other secure method, then re-run this command to confirm
that the server's certificate is now trusted.

Connecting to host 10.113.70.205:5986
ERROR: The SSL certificate of 10.113.70.205 could not be verified
Certificate issuer data: /CN=ip-0A7146CD
Configuration Info:

OpenSSL Configuration:
* Version: OpenSSL 1.0.2a 19 Mar 2015
* Certificate file: /etc/ssl/cert.pem
* Certificate directory: /etc/ssl/certs
Chef SSL Configuration:
* ssl_ca_path: nil
* ssl_ca_file: nil
* trusted_certs_dir: "/home/hh/provisioning/.chef/trusted_certs"

TO FIX THIS ERROR:

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:
/home/hh/provisioning/.chef/trusted_certs)
using SSH/SCP or some other secure method, then re-run this command to confirm
that the server's certificate is now trusted.
$ openssl s_client -connect 10.113.70.205:5986 -CAfile
.chef/trusted_certs/ip-0A7146CD.crt -verify_return_error
CONNECTED(00000003)
depth=0 CN = ip-0A7146CD
verify error:num=18:self signed certificate
---
Certificate chain
 0 s:/CN=ip-0A7146CD
   i:/CN=ip-0A7146CD
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIC2jCCAcKgAwIBAgIQYoe1RTcKKbZBnf3F2D8uKTANBgkqhkiG9w0BAQUFADAW
MRQwEgYDVQQDEwtpcC0wQTcxNDZDRDAeFw0xNTA5MjgwOTQxMDZaFw0xNjAzMjkw
OTQxMDZaMBYxFDASBgNVBAMTC2lwLTBBNzE0NkNEMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA3wXVQvW7WMeFyMSG0rW6cKHNLcmrgGENYT7AqLZeAGGk
8DELNAOJ69/4OBuJy79WLapEXhkSvp4W1IvrV44tkYPh427thuuaYMJdETrTtoFy
x+RxON1DWyfxQmXeDt/DKQH5V7S96IJ/5CylqR5+nVYwVQRXq0PkVfZmoJgZGgCT
e84bbdvGc/TZk9iuuMT+Y483tRRY+OtpPWjm+WB3ReJq88p+e2PASqknowHhv9Jk
1M2IRFbDMe9QpPCnb/Ysv/v6wxJlgVAxk5DYcuzH4sjRxbsyIxtcTah/qHZu6y9l
+Wu6o9rGaVb/Zn2zugpU8LQbJCC4qecUT2bNLDJ+2wIDAQABoyQwIjATBgNVHSUE
DDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBDAwDQYJKoZIhvcNAQEFBQADggEBAGUk
aZ6rrVF71QYnY9eKrLH4N/an+UokUf2uroIzioebOskgBmBwgbCHxMf4q2QvFtUw
DTH2J3kc1l7sYIAbOcmbTjCXf+w0jxx0IkNtyGCcXNLCnnjHfGuKM4YAMWHlGyU1
SPm3LmSm5pQUtaw/SULJ7kq0jGmoN3e4OefonNFXWDYMznvq8l7DQgGip2xo8B9O
fb9s1XDxNE7NMBq8YSWvmZMUa7WRuNZ0xP0N25chjkVTE85ZV15Gpsa3MSTMpKby
uPL/1RjalhU0gmFBelHWl2HrLNZ+08V9Y/9NY54CwbgmRn3mMYjeRVKRVR4qeuR0
tDRU7VSnkOWTmCeFR5c=
-----END CERTIFICATE-----
subject=/CN=ip-0A7146CD
issuer=/CN=ip-0A7146CD
---
No client certificate CA names sent
Peer signing digest: SHA1
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 1274 bytes and written 500 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-SHA384
    Session-ID: 
233700001E82A6DBE277D444B7BA326E8F228A5E23C083CB4477C57FBE72EFCF
    Session-ID-ctx:
    Master-Key:
6F5A06DF8BB1E271D078C7BFDFDC04AEAE6914808F305A3876277B89067E5325BFF11ECDE0AC3ECAB977DADAE17AA139
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1443521077
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---

@hh
Copy link
Contributor Author

hh commented Sep 29, 2015

I also put together some info for getting windows to offer up winrm over ssl using the self-signed rdp certificate (cross post http://lists.opscode.com/sympa/arc/chef/2015-09/msg00290.html)

On boot ec2 windows instances print a lot of useful stuff to the aws
console, including the rdp self signed ssl certificate fingerprint.
It's useful to verify that you are connecting to the host you
provisioned (similar to checking an ssh hosts fingerprint). However in
chef we use winrm, so I needed to update the user_data to copy over
the rdp certificate and enable it's use for winrm.

# ec2 console log snippit
2015/09/29 09:41:22Z: RDPCERTIFICATE-SUBJECTNAME: IP-0A7146CD
2015/09/29 09:41:22Z: RDPCERTIFICATE-THUMBPRINT:
112941B4213F118B4E3373520F0DC91F7169E1E8
$ openssl s_client -connect 10.113.70.205:5986 < /dev/null 2>/dev/null
| openssl x509 -fingerprint -noout -in /dev/stdin
SHA1 Fingerprint=11:29:41:B4:21:3F:11:8B:4E:33:73:52:0F:0D:C9:1F:71:69:E1:E8

The instance comes up with knife winrm complaining about certs (Comment above this one at #284 (comment)) , and it
seems no combination of knife ssl fetch/check works.

I'm not sure where I would look in chef-provisioning-aws to
automatically import the certificate (similar to knife ssl fetch) and
check it against the ec2 console fingerprint or how to configure it to
utilize those certs and connect over ssl. Pointers to code or docs
welcome

I include some user_data, chef-provisioning recipe, and console output
for your perusal:

<powershell>
winrm quickconfig -q
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="300"}'
winrm set winrm/config '@{MaxTimeoutms="1800000"}'

netsh advfirewall firewall add rule name="WinRM 5986" protocol=TCP
dir=in localport=5986 action=allow

$SourceStoreScope = 'LocalMachine'
$SourceStorename = 'Remote Desktop'

$SourceStore = New-Object  -TypeName
System.Security.Cryptography.X509Certificates.X509Store  -ArgumentList
$SourceStorename, $SourceStoreScope
$SourceStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly)

$cert = $SourceStore.Certificates | Where-Object  -FilterScript {
    $_.subject -like '*'
}

$DestStoreScope = 'LocalMachine'
$DestStoreName = 'My'

$DestStore = New-Object  -TypeName
System.Security.Cryptography.X509Certificates.X509Store  -ArgumentList
$DestStoreName, $DestStoreScope
$DestStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$DestStore.Add($cert)

$SourceStore.Close()
$DestStore.Close()

winrm create winrm/config/listener?Address=*+Transport=HTTPS
`@`{Hostname=`"($certId)`"`;CertificateThumbprint=`"($cert.Thumbprint)`"`}

net stop winrm
sc config winrm start=auto
net start winrm
</powershell>
with_machine_options bootstrap_options: {
 winrm_transport: {
    https: {
      # This is what I'd prefer not to do, still doesn't connect
      no_ssl_peer_verification: true
    }
  },
  user_data: setup_winrm_ssl_user_data_from_above,
  image_id: 'ami-7bc3e04b'
  # aws-marketplace/CIS Microsoft Windows Server 2012 R2
  # Benchmark v1.1.0-26bb465c-ce26-4da9-afb8-040b2f8c9a7f-ami-7a88f312.2
}

machine_name = 'win-2012-hardened-X'

m = machine "#{machine_name}" do
  action :allocate
end

ruby_block "Security Info on #{machine_name}" do
  block do

    # wait for the machine to be in a ready state
    mr=resources(machine: machine_name).provider_for_action(:ready)
    mr.load_current_resource
    machine=mr.action_ready

    # grab a pointer to the chef-provisioning driver
    # so we can call driver.config and driver.ec2.*
    driver = node.run_state[:chef_provisioning].drivers.values.first

    i=driver.ec2.instances[machine.machine_spec.reference['instance_id']]
    # check for rdp certificate fingerprint
    i.console_output.lines.each do |l|
      Chef::Log.warn l.chomp
    end

    # just to look ot the machine_spec
    machine.machine_spec.reference.pretty_inspect.lines.each do |l|
      Chef::Log.warn l.chomp
    end

    # decrypt the password
    pem = Cheffish.get_private_key(machine.machine_spec.reference['key_name'],
                                   driver.config)
    private_key = OpenSSL::PKey::RSA.new(pem)

    encrypted_admin_password =
driver.wait_for_admin_password(machine.machine_spec)
    decoded = Base64.decode64(encrypted_admin_password)
    decrypted_password = private_key.private_decrypt decoded

   Chef::Log.warn "knife ssl fetch https://#{i.private_ip_address}:5985";
   Chef::Log.warn "rdesktop -u Administrator -p
'#{decrypted_password}' -g 1280x800 #{i.private_ip_address}"
   Chef::Log.warn "knife winrm --winrm-port 5986 --winrm-transport ssl
--winrm-password '#{decrypted_password}' -m #{i.private_ip_address}
hostname"
    # a nice place to rest until we get figure out how to get winrm +
ssl working
    # TRY RUNNING 'knife winrm' HERE **************************************************
    byebug
    # as execution won't work until we configure winrm to actually
communicate to the node

    machine.execute_always('dir "cert:\localmachine\Remote
Desktop"').stdout.lines.each do |l|
      Chef::Log.warn l.chomp
    end
  end
end

# someday!
machine "#{machine_name}" do
  action :converge
end

full ec2-get-console, there is an ec2config issued reboot to get a
unique hostname

2015/09/29 09:39:16Z: Windows sysprep configuration complete.
2015/09/29 09:39:19Z: AMI Origin Version: 2014.12.10
2015/09/29 09:39:19Z: AMI Origin Name:
Windows_Server-2012-R2_RTM-English-64Bit-Base
2015/09/29 09:39:19Z: OsVersion: 6.3
2015/09/29 09:39:19Z: OsServicePack: NotFound
2015/09/29 09:39:19Z: OsProductName: Windows Server 2012 R2 Standard
2015/09/29 09:39:19Z: OsBuildLabEx: 9600.17476.amd64fre.winblue_r5.141029-1500
2015/09/29 09:39:19Z: Language: en-US
2015/09/29 09:39:19Z: EC2 Agent: Ec2Config service v2.2.12.301
2015/09/29 09:39:19Z: EC2 Agent: Ec2Config service fileversion v2.2.12.301
2015/09/29 09:39:48Z: Driver: AWS PV Storage Host Adapter v7.2.4.1
2015/09/29 09:39:48Z: Driver: Intel(R) 82599 Virtual Function v1.0.15.3
2015/09/29 09:39:50Z: Message: Waiting for meta-data accessibility...
2015/09/29 09:39:51Z: Message: Meta-data is now available.
2015/09/29 09:39:53Z: AMI-ID: ami-7bc3e04b
2015/09/29 09:39:53Z: Instance-ID: i-d0b3ec16
2015/09/29 09:39:54Z: Ec2SetPassword: Enabled
2015/09/29 09:39:56Z: Username: Administrator
2015/09/29 09:39:56Z: Password: <Password>
mMpNuqSphbwA+Ry/ZPDPKQ+v4s5fhTwh7O42Toaw18aWNUzkVh4+++MQ0hLrT6BR2YKsODMElJOshqE+yMxEUM/xr8pgP1ihOAHn/QT1o5qDzeBBByXQxx90/FtxM6OmcxdtxbGfJE4FK54uGB52ao9IlMBSY1LFq/+ipoDY+rpw+owHtEaFE666I8+wSD6Ys4MNZ+It18DigsnjTH+hYU22HeXHKt6cMkgGV7YkhAmb99H0teFzHxtjvtWRIxKliZisbfFH6Cay29q/S1LQvSjE8r3RKQXVLHUste89Di32Qwzjpj7GKl4/8mOevoEmtOgT2s0hWjvyFBng6zHRAw==
</Password>
2015/09/29 09:39:58Z: RDPCERTIFICATE-SUBJECTNAME: WIN-PQBS6I717AU
2015/09/29 09:39:58Z: RDPCERTIFICATE-THUMBPRINT:
30DFDDE350CC06379340488EF8FE9F2A34AEA398
2015/09/29 09:40:01Z: Message: Product activation was successful
2015/09/29 09:40:02Z: Message: Ec2Config Service is rebooting the
instance. Please be patient.
2015/09/29 09:41:06Z: Windows sysprep configuration complete.
2015/09/29 09:41:06Z: AMI Origin Version: 2014.12.10
2015/09/29 09:41:06Z: AMI Origin Name:
Windows_Server-2012-R2_RTM-English-64Bit-Base
2015/09/29 09:41:06Z: OsVersion: 6.3
2015/09/29 09:41:06Z: OsServicePack: NotFound
2015/09/29 09:41:06Z: OsProductName: Windows Server 2012 R2 Standard
2015/09/29 09:41:06Z: OsBuildLabEx: 9600.17476.amd64fre.winblue_r5.141029-1500
2015/09/29 09:41:06Z: Language: en-US
2015/09/29 09:41:06Z: EC2 Agent: Ec2Config service v2.2.12.301
2015/09/29 09:41:06Z: EC2 Agent: Ec2Config service fileversion v2.2.12.301
2015/09/29 09:41:22Z: Driver: AWS PV Storage Host Adapter v7.2.4.1
2015/09/29 09:41:22Z: Driver: Intel(R) 82599 Virtual Function v1.0.15.3
2015/09/29 09:41:22Z: Message: Waiting for meta-data accessibility...
2015/09/29 09:41:22Z: Message: Meta-data is now available.
2015/09/29 09:41:22Z: AMI-ID: ami-7bc3e04b
2015/09/29 09:41:22Z: Instance-ID: i-d0b3ec16
2015/09/29 09:41:22Z: Ec2SetPassword: Disabled
2015/09/29 09:41:22Z: RDPCERTIFICATE-SUBJECTNAME: IP-0A7146CD
2015/09/29 09:41:22Z: RDPCERTIFICATE-THUMBPRINT:
112941B4213F118B4E3373520F0DC91F7169E1E8
2015/09/29 09:41:23Z: Message: Windows is Ready to use
2015/09/29 09:41:41Z: Message: Executing User Data with PID: 2652

@hh
Copy link
Contributor Author

hh commented Sep 30, 2015

https://github.com/chef/knife-windows/blob/master/lib/chef/knife/winrm_knife_base.rb#L194 notes that we should use ssl certificates, but we are unable to set it to do so

@hh
Copy link
Contributor Author

hh commented Jan 28, 2016

I think this is similar enough to #298 with --ssl-peer-fingerprint that we should probably just update the documentation to generate the fingerprint to pass to it.

hh added a commit to hh/knife-windows that referenced this issue Jan 28, 2016
Fixes chef#284 by document the resolution of chef#298
@hh
Copy link
Contributor Author

hh commented Jan 28, 2016

We'd have to have a mapping from hosts to fingerprint... which would make sense to just store in the node, so we have either a fingerprint or pem encoded certificate as a particular node attribute?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant