Project

General

Profile

« Previous | Next » 

Revision 7697116c

Added by Dominic Cleal over 11 years ago

fixes #2121, #2069 - authenticate to Foreman with SSL certificate

CVE-2013-0171 and CVE-2013-0174 were resolved by verifying client SSL
certificates on Foreman interfaces used by puppetmasters. This change updates
the ENC and report processors to provide and verify certificates by default.

View differences:

manifests/config/enc.pp
$foreman_url = $foreman::params::foreman_url,
$facts = $foreman::params::facts,
$storeconfigs = $foreman::params::storeconfigs,
$puppet_home = $foreman::params::puppet_home
$puppet_home = $foreman::params::puppet_home,
$ssl_ca = $foreman::params::client_ssl_ca,
$ssl_cert = $foreman::params::client_ssl_cert,
$ssl_key = $foreman::params::client_ssl_key
) inherits foreman::params {
File { require => Class['::puppet::server::install'] }
manifests/params.pp
class foreman::params {
# Basic configurations
$foreman_url = "http://${::fqdn}"
$foreman_url = "https://${::fqdn}"
# Should foreman act as an external node classifier (manage puppet class
# assignments)
$enc = true
......
}
}
$puppet_home = '/var/lib/puppet'
# If CA is specified, remote Foreman host will be verified in reports/ENC scripts
$client_ssl_ca = "${puppet_home}/ssl/certs/ca.pem"
# Used to authenticate to Foreman, required if require_ssl_puppetmasters is enabled
$client_ssl_cert = "${puppet_home}/ssl/certs/${fqdn}.pem"
$client_ssl_key = "${puppet_home}/ssl/private_keys/${fqdn}.pem"
}
manifests/puppetmaster.pp
$facts = $foreman::params::facts,
$storeconfigs = $foreman::params::storeconfigs,
$puppet_home = $foreman::params::puppet_home,
$puppet_basedir = $foreman::params::puppet_basedir
$puppet_basedir = $foreman::params::puppet_basedir,
$ssl_ca = $foreman::params::client_ssl_ca,
$ssl_cert = $foreman::params::client_ssl_cert,
$ssl_key = $foreman::params::client_ssl_key
) inherits foreman::params {
if $foreman::params::reports { # foreman reporter
......
facts => $facts,
storeconfigs => $storeconfigs,
puppet_home => $puppet_home,
ssl_ca => $ssl_ca,
ssl_cert => $ssl_cert,
ssl_key => $ssl_key
}
}
}
templates/external_node.rb.erb
:facts => <%= @facts %>,
:storeconfigs => <%= @storeconfigs %>,
:timeout => 3,
# if CA is specified, remote Foreman host will be verified
:ssl_ca => "<%= @ssl_ca -%>",
# ssl_cert and key are required if require_ssl_puppetmasters is enabled in Foreman
:ssl_cert => "<%= @ssl_cert -%>",
:ssl_key => "<%= @ssl_key -%>"
}
### Do not edit below this line
......
req.set_form_data('facts' => fact)
res = Net::HTTP.new(uri.host, uri.port)
res.use_ssl = uri.scheme == 'https'
res.verify_mode = OpenSSL::SSL::VERIFY_NONE if res.use_ssl?
if res.use_ssl?
if SETTINGS[:ssl_ca]
res.ca_file = SETTINGS[:ssl_ca]
res.verify_mode = OpenSSL::SSL::VERIFY_PEER
else
res.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
if SETTINGS[:ssl_cert] and SETTINGS[:ssl_key]
res.cert = OpenSSL::X509::Certificate.new(File.read(SETTINGS[:ssl_cert]))
res.key = OpenSSL::PKey::RSA.new(File.read(SETTINGS[:ssl_key]), nil)
end
end
res.start { |http| http.request(req) }
rescue => e
raise "Could not send facts to Foreman: #{e}"
......
req = Net::HTTP::Get.new(foreman_url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == 'https'
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?
res = http.start { |http| http.request(req) }
if http.use_ssl?
if SETTINGS[:ssl_ca]
http.ca_file = SETTINGS[:ssl_ca]
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
else
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
if SETTINGS[:ssl_cert] and SETTINGS[:ssl_key]
http.cert = OpenSSL::X509::Certificate.new(File.read(SETTINGS[:ssl_cert]))
http.key = OpenSSL::PKey::RSA.new(File.read(SETTINGS[:ssl_key]), nil)
end
end
res = http.start { |http| http.request(req) }
raise "Error retrieving node #{certname}: #{res.class}" unless res.code == "200"
res.body
templates/foreman-report.rb.erb
# URL of your Foreman installation
$foreman_url='<%= @foreman_url %>'
# if CA is specified, remote Foreman host will be verified
$foreman_ssl_ca = "<%= @ssl_ca -%>"
# ssl_cert and key are required if require_ssl_puppetmasters is enabled in Foreman
$foreman_ssl_cert = "<%= @ssl_cert -%>"
$foreman_ssl_key = "<%= @ssl_key -%>"
require 'puppet'
require 'net/http'
......
begin
uri = URI.parse($foreman_url)
http = Net::HTTP.new(uri.host, uri.port)
if uri.scheme == 'https' then
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.use_ssl = uri.scheme == 'https'
if http.use_ssl?
if $foreman_ssl_ca
http.ca_file = $foreman_ssl_ca
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
else
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
if $foreman_ssl_cert
http.cert = OpenSSL::X509::Certificate.new(File.read($foreman_ssl_cert))
http.key = OpenSSL::PKey::RSA.new(File.read($foreman_ssl_key), nil)
end
end
req = Net::HTTP::Post.new("#{uri.path}/reports/create?format=yml")
req.set_form_data({'report' => to_yaml})

Also available in: Unified diff