Class: Puppet::SSL::Host Deprecated
Overview
Use SSLProvider instead.
The class that manages all aspects of our SSL certificates – private keys, public keys, requests, etc.
Constant Summary collapse
- Key =
Yay, ruby’s strange constant lookups.
Puppet::SSL::Key
- CA_NAME =
Puppet::SSL::CA_NAME
- Certificate =
Puppet::SSL::Certificate
- CertificateRequest =
Puppet::SSL::CertificateRequest
Instance Attribute Summary collapse
- #certificate ⇒ Object
-
#certificate_request ⇒ Puppet::SSL::CertificateRequest?
Search for an existing CSR for this host either cached on disk or stored by the CA.
-
#crl_path ⇒ Object
readonly
Returns the value of attribute crl_path.
-
#crl_usage ⇒ Object
writeonly
Sets the attribute crl_usage.
-
#device ⇒ Object
readonly
Returns the value of attribute device.
- #key ⇒ Object
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Class Method Summary collapse
-
.configure_indirection(terminus, cache = nil) ⇒ Object
Configure how our various classes interact with their various terminuses.
- .from_data_hash(data) ⇒ Object
- .localhost ⇒ Object
- .reset ⇒ Object
Instance Method Summary collapse
-
#check_for_certificate_on_disk(cert_name) ⇒ Puppet::SSL::Certificate?
Checks for the requested certificate on disc, at a location determined by this host’s configuration.
-
#clean_params ⇒ Object
The puppet parameters for commands output by the validate_ methods depend upon whether this is an agent or a device.
-
#download_certificate_from_ca(cert_name) ⇒ Puppet::SSL::Certificate?
Attempts to download this host’s certificate from the CA server.
- #download_host_certificate ⇒ Object
-
#generate ⇒ Object
Generate all necessary parts of our ssl host.
-
#generate_certificate_request(options = {}) ⇒ Object
Our certificate request requires the key but that’s all.
-
#generate_key ⇒ Object
This is the private key; we can create it from scratch with no inputs.
-
#initialize(name = nil, device = false) ⇒ Host
constructor
A new instance of Host.
-
#public_key ⇒ Object
Extract the public key from the private key.
- #puppet_params ⇒ Object
-
#save_host_certificate(cert) ⇒ Object
Saves the given certificate to disc, at a location determined by this host’s configuration.
-
#ssl_store(purpose = OpenSSL::X509::PURPOSE_ANY) ⇒ Object
Create/return a store that uses our SSL info to validate connections.
- #use_crl? ⇒ Boolean
- #use_crl_chain? ⇒ Boolean
-
#validate_certificate_with_key(cert) ⇒ Object
Validate that our private key matches the specified certificate.
-
#wait_for_cert(time) ⇒ Object
Attempt to retrieve a cert, if we don’t already have one.
Constructor Details
#initialize(name = nil, device = false) ⇒ Host
Returns a new instance of Host.
228 229 230 231 232 233 234 235 236 |
# File 'lib/puppet/ssl/host.rb', line 228 def initialize(name = nil, device = false) @name = (name || Puppet[:certname]).downcase @device = device Puppet::SSL::Base.validate_certname(@name) @key = @certificate = @certificate_request = nil @crl_usage = Puppet.settings[:certificate_revocation] @crl_path = Puppet.settings[:hostcrl] Puppet.deprecation_warning(_("Puppet::SSL::Host is deprecated and will be removed in a future release of Puppet.")); end |
Instance Attribute Details
#certificate ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/puppet/ssl/host.rb', line 121 def certificate unless @certificate generate_key unless key # get CA and optional CRL sm = Puppet::SSL::StateMachine.new(onetime: true) sm.ensure_ca_certificates cert = get_host_certificate return nil unless cert validate_certificate_with_key(cert) @certificate = cert end @certificate end |
#certificate_request ⇒ Puppet::SSL::CertificateRequest?
Search for an existing CSR for this host either cached on disk or stored by the CA. Returns nil if no request exists.
182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/puppet/ssl/host.rb', line 182 def certificate_request unless @certificate_request csr = load_certificate_request_from_file if csr @certificate_request = csr else csr = download_csr_from_ca if csr @certificate_request = csr end end end @certificate_request end |
#crl_path ⇒ Object (readonly)
Returns the value of attribute crl_path.
21 22 23 |
# File 'lib/puppet/ssl/host.rb', line 21 def crl_path @crl_path end |
#crl_usage=(value) ⇒ Object (writeonly)
Sets the attribute crl_usage
23 24 25 |
# File 'lib/puppet/ssl/host.rb', line 23 def crl_usage=(value) @crl_usage = value end |
#device ⇒ Object (readonly)
Returns the value of attribute device.
21 22 23 |
# File 'lib/puppet/ssl/host.rb', line 21 def device @device end |
#key ⇒ Object
72 73 74 |
# File 'lib/puppet/ssl/host.rb', line 72 def key @key ||= Key.indirection.find(name) end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
21 22 23 |
# File 'lib/puppet/ssl/host.rb', line 21 def name @name end |
Class Method Details
.configure_indirection(terminus, cache = nil) ⇒ Object
Configure how our various classes interact with their various terminuses.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/puppet/ssl/host.rb', line 38 def self.configure_indirection(terminus, cache = nil) Certificate.indirection.terminus_class = terminus CertificateRequest.indirection.terminus_class = terminus if cache # This is weird; we don't actually cache our keys, we # use what would otherwise be the cache as our normal # terminus. Key.indirection.terminus_class = cache else Key.indirection.terminus_class = terminus end if cache Certificate.indirection.cache_class = cache CertificateRequest.indirection.cache_class = cache else # Make sure we have no cache configured. puppet master # switches the configurations around a bit, so it's important # that we specify the configs for absolutely everything, every # time. Certificate.indirection.cache_class = nil CertificateRequest.indirection.cache_class = nil end end |
.from_data_hash(data) ⇒ Object
64 65 66 67 68 69 70 |
# File 'lib/puppet/ssl/host.rb', line 64 def self.from_data_hash(data) instance = new(data["name"]) if data["desired_state"] instance.desired_state = data["desired_state"] end instance end |
.localhost ⇒ Object
25 26 27 28 29 30 31 |
# File 'lib/puppet/ssl/host.rb', line 25 def self.localhost return @localhost if @localhost @localhost = new @localhost.generate unless @localhost.certificate @localhost.key @localhost end |
.reset ⇒ Object
33 34 35 |
# File 'lib/puppet/ssl/host.rb', line 33 def self.reset @localhost = nil end |
Instance Method Details
#check_for_certificate_on_disk(cert_name) ⇒ Puppet::SSL::Certificate?
Checks for the requested certificate on disc, at a location determined by this host’s configuration.
419 420 421 422 423 424 425 426 427 428 |
# File 'lib/puppet/ssl/host.rb', line 419 def check_for_certificate_on_disk(cert_name) file_path = certificate_location(cert_name) if Puppet::FileSystem.exist?(file_path) begin Puppet::SSL::Certificate.from_s(Puppet::FileSystem.read(file_path)) rescue OpenSSL::X509::CertificateError raise Puppet::Error, _("The certificate at %{file_path} is invalid. Could not load.") % { file_path: file_path } end end end |
#clean_params ⇒ Object
The puppet parameters for commands output by the validate_ methods depend upon whether this is an agent or a device.
141 142 143 |
# File 'lib/puppet/ssl/host.rb', line 141 def clean_params @device ? "--target #{Puppet[:certname]}" : '' end |
#download_certificate_from_ca(cert_name) ⇒ Puppet::SSL::Certificate?
Attempts to download this host’s certificate from the CA server. Returns nil if the CA does not yet have a signed cert for this host.
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 |
# File 'lib/puppet/ssl/host.rb', line 437 def download_certificate_from_ca(cert_name) begin cert = Puppet::Rest::Routes.get_certificate( cert_name, Puppet::SSL::SSLContext.new(store: ssl_store) ) begin Puppet::SSL::Certificate.from_s(cert) rescue OpenSSL::X509::CertificateError raise Puppet::Error, _("Response from the CA did not contain a valid certificate for %{cert_name}.") % { cert_name: cert_name } end rescue Puppet::Rest::ResponseError => e if e.response.code.to_i == 404 Puppet.debug _("No certificate for %{cert_name} on CA") % { cert_name: cert_name } nil else raise Puppet::Rest::ResponseError, _("Could not download host certificate: %{message}") % { message: e. } end end end |
#download_host_certificate ⇒ Object
170 171 172 173 174 175 176 177 |
# File 'lib/puppet/ssl/host.rb', line 170 def download_host_certificate cert = download_certificate_from_ca(name) return nil unless cert validate_certificate_with_key(cert) save_host_certificate(cert) cert end |
#generate ⇒ Object
Generate all necessary parts of our ssl host.
198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/puppet/ssl/host.rb', line 198 def generate generate_key unless key existing_request = certificate_request # if CSR downloaded from master, but the local keypair was just generated and # does not match the public key in the CSR, fail hard validate_csr_with_key(existing_request, key) if existing_request generate_certificate_request unless existing_request end |
#generate_certificate_request(options = {}) ⇒ Object
Our certificate request requires the key but that’s all.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/puppet/ssl/host.rb', line 91 def generate_certificate_request( = {}) generate_key unless key # If this CSR is for the current machine... if name == Puppet[:certname].downcase # ...add our configured dns_alt_names if Puppet[:dns_alt_names] and Puppet[:dns_alt_names] != '' [:dns_alt_names] ||= Puppet[:dns_alt_names] end end csr_attributes = Puppet::SSL::CertificateRequestAttributes.new(Puppet[:csr_attributes]) if csr_attributes.load [:csr_attributes] = csr_attributes.custom_attributes [:extension_requests] = csr_attributes.extension_requests end @certificate_request = CertificateRequest.new(name) @certificate_request.generate(key.content, ) begin submit_certificate_request(@certificate_request) save_certificate_request(@certificate_request) rescue @certificate_request = nil raise end true end |
#generate_key ⇒ Object
This is the private key; we can create it from scratch with no inputs.
78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/puppet/ssl/host.rb', line 78 def generate_key @key = Key.new(name) @key.generate begin Key.indirection.save(@key) rescue @key = nil raise end true end |
#public_key ⇒ Object
Extract the public key from the private key.
239 240 241 |
# File 'lib/puppet/ssl/host.rb', line 239 def public_key key.content.public_key end |
#puppet_params ⇒ Object
145 146 147 |
# File 'lib/puppet/ssl/host.rb', line 145 def puppet_params @device ? "device -v --target #{Puppet[:certname]}" : 'agent -t' end |
#save_host_certificate(cert) ⇒ Object
Saves the given certificate to disc, at a location determined by this host’s configuration.
296 297 298 299 300 301 |
# File 'lib/puppet/ssl/host.rb', line 296 def save_host_certificate(cert) file_path = certificate_location(name) Puppet::Util.replace_file(file_path, 0644) do |f| f.write(cert.to_s) end end |
#ssl_store(purpose = OpenSSL::X509::PURPOSE_ANY) ⇒ Object
Create/return a store that uses our SSL info to validate connections.
253 254 255 256 257 258 |
# File 'lib/puppet/ssl/host.rb', line 253 def ssl_store(purpose = OpenSSL::X509::PURPOSE_ANY) if @ssl_store.nil? @ssl_store = build_ssl_store(purpose) end @ssl_store end |
#use_crl? ⇒ Boolean
243 244 245 |
# File 'lib/puppet/ssl/host.rb', line 243 def use_crl? !!@crl_usage end |
#use_crl_chain? ⇒ Boolean
247 248 249 |
# File 'lib/puppet/ssl/host.rb', line 247 def use_crl_chain? @crl_usage == true || @crl_usage == :chain end |
#validate_certificate_with_key(cert) ⇒ Object
Validate that our private key matches the specified certificate.
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/puppet/ssl/host.rb', line 153 def validate_certificate_with_key(cert) raise Puppet::Error, _("No certificate to validate.") unless cert raise Puppet::Error, _("No private key with which to validate certificate with fingerprint: %{fingerprint}") % { fingerprint: cert.fingerprint } unless key unless cert.content.check_private_key(key.content) raise Puppet::Error, _(<<ERROR_STRING) % { fingerprint: cert.fingerprint, cert_name: Puppet[:certname], clean_params: clean_params, puppet_params: puppet_params } The certificate retrieved from the master does not match the agent's private key. Did you forget to run as root? Certificate fingerprint: %{fingerprint} To fix this, remove the certificate from both the master and the agent and then start a puppet run, which will automatically regenerate a certificate. On the master: puppetserver ca clean --certname %{cert_name} On the agent: 1. puppet ssl clean %{clean_params} 2. puppet %{puppet_params} ERROR_STRING end end |
#wait_for_cert(time) ⇒ Object
Attempt to retrieve a cert, if we don’t already have one.
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/puppet/ssl/host.rb', line 261 def wait_for_cert(time) begin return if certificate generate return if certificate rescue StandardError => detail Puppet.log_exception(detail, _("Could not request certificate: %{message}") % { message: detail. }) if time < 1 puts _("Exiting; failed to retrieve certificate and waitforcert is disabled") exit(1) else sleep(time) end retry end if time < 1 puts _("Exiting; no certificate found and waitforcert is disabled") exit(1) end while true sleep time begin break if certificate Puppet.notice _("Did not receive certificate") rescue StandardError => detail Puppet.log_exception(detail, _("Could not request certificate: %{message}") % { message: detail. }) end end end |