Chef-provisioning configuration for winrm w/ ssl-transport (and self signed certs)

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.

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, and it
seems no combination of knife ssl fetch/check works, but let’s talk
about knife in a different thread:
http://lists.opscode.com/sympa/arc/chef/2015-09/msg00289.html

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:

‘’'user_data

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

’’’

‘’'
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
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® 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:
mMpNuqSphbwA+Ry/ZPDPKQ+v4s5fhTwh7O42Toaw18aWNUzkVh4+++MQ0hLrT6BR2YKsODMElJOshqE+yMxEUM/xr8pgP1ihOAHn/QT1o5qDzeBBByXQxx90/FtxM6OmcxdtxbGfJE4FK54uGB52ao9IlMBSY1LFq/+ipoDY+rpw+owHtEaFE666I8+wSD6Ys4MNZ+It18DigsnjTH+hYU22HeXHKt6cMkgGV7YkhAmb99H0teFzHxtjvtWRIxKliZisbfFH6Cay29q/S1LQvSjE8r3RKQXVLHUste89Di32Qwzjpj7GKl4/8mOevoEmtOgT2s0hWjvyFBng6zHRAw==

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® 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
’’’

In order for ssl to work, we need to tell ssl that it’s ok that
ssl_subject CN doesn’t match the ip.
Any thoughts on how to proceed?

https://github.com/ii/chef-provisioning-aws/pull/2/files#r40951990

#[19] pry(#Chef::Provisioning::AWSDriver::Driver)>
endpoint.split(’/’)[2].split(’:’).first

=> “10.113.70.104”

[20] pry(#Chef::Provisioning::AWSDriver::Driver)>

machine_spec.reference[:winrm_ssl_subject]

=> “IP-0A714668”

[1] pry(#Chef::Provisioning::AWSDriver::Driver)>

Chef::Provisioning::Transport::WinRM.new("#{endpoint}", type,
winrm_options, {}).execute(‘hostname’)

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error:

certificate verify failed

from /home/hh/.rvm/gems/ruby-2.2.0/gems/httpclient-2.6.0.1/lib/httpclient/session.rb:307:in

`connect’

[2] pry(#Chef::Provisioning::AWSDriver::Driver)> wtf!

Exception: OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0

state=error: certificate verify failed

0: /home/hh/.rvm/gems/ruby-2.2.0/gems/httpclient-2.6.0.1/lib/httpclient/session.rb:307:in

`connect’

1: /home/hh/.rvm/gems/ruby-2.2.0/gems/httpclient-2.6.0.1/lib/httpclient/session.rb:307:in

`ssl_connect’

2: /home/hh/.rvm/gems/ruby-2.2.0/gems/httpclient-2.6.0.1/lib/httpclient/session.rb:755:in

`block in connect’

3: /home/hh/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/timeout.rb:89:in

`block in timeout’

4: /home/hh/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/timeout.rb:99:in `call’

5: /home/hh/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/timeout.rb:99:in `timeout’

6: /home/hh/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/timeout.rb:125:in `timeout’

8: /home/hh/.rvm/gems/ruby-2.2.0/gems/httpclient-2.6.0.1/lib/httpclient/session.rb:612:in

`query’

9: /home/hh/.rvm/gems/ruby-2.2.0/gems/httpclient-2.6.0.1/lib/httpclient/session.rb:164:in

`query’

[3] pry(#Chef::Provisioning::AWSDriver::Driver)> winrm_options

=> {:user=>“Administrator”,

:pass=>"(xntd8f=-HNnuJ3",

:disable_sspi=>false,

:basic_auth_only=>false,

:no_ssl_peer_verification=>false,

:ca_trust_path=>"/home/hh/provisioning/.chef/trusted_certs/base-2012-hardened-6.crt"}