Skip to content

Commit

Permalink
(PIE-1401) Add system cert store SSL validation
Browse files Browse the repository at this point in the history
  • Loading branch information
coreymbe committed Nov 1, 2023
1 parent e46167e commit 9a8f00b
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 54 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file. The format

### Added

The parameter `ignore_system_cert_store` is now named `include_system_cert_store` and defaults to **false**. [#208](https://github.com/puppetlabs/puppetlabs-splunk_hec/pull/208)

Credential data provided to this module is now written to a separate configuration file utilizing the Sensitive data type to ensure redaction from Puppet logs and reports. [#204](https://github.com/puppetlabs/puppetlabs-splunk_hec/pull/204)

Configuration files created by this module are now placed in a `splunk_hec` subdirectory. [#204](https://github.com/puppetlabs/puppetlabs-splunk_hec/pull/204)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ class profile::splunk_hec {
}
```

The certificate provided to the `ssl_ca` parameter is a supplement to the system ca certificates store. By default, the Ruby classes that perform certificate validation will attempt to use the system certificates first, and then if the certificate cannot be validated there, it will load the ca file in `ssl_ca`. Occasionally, the system cert store will cause validation errors prior to checking the file at `ssl_ca`. To avoid this you can set `ignore_system_cert_store` to `true`. This will allow the code to use ONLY the file at `ssl_ca` to perform certificate validation.
**Note**: When `splunk_hec::ssl_ca` is configured it takes precendence over the system certificate store. The report processor will build its own cert store with the provided CA certificate to validate requests against the Splunk HEC endpoint. Alternatively, you can add the Splunk HEC CA to the system certificate store and set `splunk_hec::include_system_cert_store` to `true`. This will allow the code to ONLY use the system default store to perform certificate validation.

## Fact Configuration

Expand Down
10 changes: 4 additions & 6 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ The following parameters are available in the `splunk_hec` class:
- [`pe_console`](#pe_console)
- [`timeout`](#timeout)
- [`ssl_ca`](#ssl_ca)
- [`ignore_system_cert_store`](#ignore_system_cert_store)
- [`include_system_cert_store`](#include_system_cert_store)
- [`fips_crl_check`](#fips_crl_check)
- [`fips_verify_peer`](#fips_verify_peer)
- [`token_summary`](#token_summary)
Expand Down Expand Up @@ -239,14 +239,12 @@ The name of the ca certification/bundle for ssl validation of the splunk_hec end

Default value: `undef`

##### <a name="-splunk_hec--ignore_system_cert_store"></a>`ignore_system_cert_store`
##### <a name="-splunk_hec--include_system_cert_store"></a>`include_system_cert_store`

Data type: `Boolean`

By default, the certificate provided to the ssl_ca parameter is a supplement
to the system ca certificate store. If that cert store contains invalid
certificates, ssl validation could fail. Set this parameter to true to
ignore those certificates and use only the provided file.
By default, the certificates in the local system cert store are ignored. To include
these certificates for ssl validation of the splunk_hec endpoint set to True

Default value: `false`

Expand Down
37 changes: 24 additions & 13 deletions lib/puppet/util/splunk_hec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,33 @@ def create_http(source_type)
http.read_timeout = timeout.to_i
http.use_ssl = @uri.scheme == 'https'
if http.use_ssl?
if settings['ssl_ca'] && !settings['ssl_ca'].empty?
ssl_ca = File.join(Puppet[:confdir], 'splunk_hec', settings['ssl_ca'])
raise Puppet::Error, "CA file #{ssl_ca} does not exist" unless File.exist? ssl_ca
ssl_info_message = "Will verify #{splunk_url} SSL identity"

if settings['ignore_system_cert_store']
http.cert_store = build_ca_store(ssl_ca)
ssl_info_message = "#{ssl_info_message} ignoring system cert store"
else
http.ca_file = ssl_ca
if (settings['ssl_ca'] && !settings['ssl_ca'].empty?) || settings['include_system_cert_store']
ssl_ca_file = if settings['ssl_ca']
File.join(Puppet[:confdir], 'splunk_hec', settings['ssl_ca'])
elsif !settings['ssl_ca'] && Facter.value(:os)['family'].eql?('RedHat')
'/etc/ssl/certs/ca-bundle.crt'
elsif !settings['ssl_ca'] && Facter.value(:os)['family'].eql?('Suse')
'/etc/ssl/ca-bundle.pem'
else
'/etc/ssl/certs/ca-certificates.crt'
end
message = if settings['ssl_ca']
"will verify #{splunk_url} SSL identity against Splunk HEC SSL #{settings['ssl_ca']}"
else
"will verify #{splunk_url} SSL identity against system store"
end

unless File.exist?(ssl_ca_file) && !File.zero?(ssl_ca_file)
raise Puppet::Error,
"CA file #{ssl_ca_file} is an empty file or does not exist"
end

Puppet.info ssl_info_message
ssl_ca = build_ca_store(ssl_ca_file)
http.cert_store = ssl_ca
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
Puppet.warn_once('hec_ssl', 'ssl_ca', message, nil, nil, :info)
else
Puppet.info "Will NOT verify #{splunk_url} SSL identity"
message = "will NOT verify #{splunk_url} SSL identity"
Puppet.warn_once('hec_ssl', 'no_ssl', message, nil, nil, :info)
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
end
Expand Down
10 changes: 4 additions & 6 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,9 @@
# Timeout limit for for both open and read sessions
# @param [Optional[String]] ssl_ca
# The name of the ca certification/bundle for ssl validation of the splunk_hec endpoint
# @param [Boolean] ignore_system_cert_store
# By default, the certificate provided to the ssl_ca parameter is a supplement
# to the system ca certificate store. If that cert store contains invalid
# certificates, ssl validation could fail. Set this parameter to true to
# ignore those certificates and use only the provided file.
# @param [Boolean] include_system_cert_store
# By default, the certificates in the local system cert store are ignored. To include
# these certificates for ssl validation of the splunk_hec endpoint set to True
# @param [Boolean] fips_crl_check
# By default, the Puppet HTTP Client will attempt to check the Splunk CA against the Splunk CRL.
# Unless the Splunk HEC endpoint is configured with a certificate generated by the Puppet CA, set
Expand Down Expand Up @@ -121,7 +119,7 @@
String $pe_console = $settings::report_server,
Optional[Integer] $timeout = undef,
Optional[String] $ssl_ca = undef,
Boolean $ignore_system_cert_store = false,
Boolean $include_system_cert_store = false,
Boolean $fips_crl_check = true,
Boolean $fips_verify_peer = true,
Optional[String] $token_summary = undef,
Expand Down
24 changes: 12 additions & 12 deletions spec/spec_helper_acceptance_local.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def report_dir
@report_dir ||= TARGET_SERVER.run_shell(cmd).stdout.chomp
end

def setup_manifest(disabled: false, ignore_store: true, ssl_ca: nil, url: nil, with_event_forwarding: false)
def setup_manifest(disabled: false, cert_store: false, ssl_ca: nil, url: nil, with_event_forwarding: false)
if url.nil?
# This block is for checking whether we are testing locally or on the CloudCI
# splunk_node.uri will work locally, but bc of the discrepancy of uri and hostname
Expand All @@ -92,15 +92,15 @@ def setup_manifest(disabled: false, ignore_store: true, ssl_ca: nil, url: nil, w

manifest = ''
params = {
url: url,
token: 'abcd1234',
enable_reports: true,
manage_routes: true,
facts_terminus: 'yaml',
record_event: true,
pe_console: 'localhost',
disabled: disabled,
ignore_system_cert_store: ignore_store,
url: url,
token: 'abcd1234',
enable_reports: true,
manage_routes: true,
facts_terminus: 'yaml',
record_event: true,
pe_console: 'localhost',
disabled: disabled,
include_system_cert_store: cert_store,
}

params[:ssl_ca] = ssl_ca unless ssl_ca.nil?
Expand Down Expand Up @@ -140,9 +140,9 @@ def configure_ssl(cert_store: false)
image = LitmusHelpers.facts_from_node(inventory_hash, TARGET_SERVER)
cmd = if cert_store
if image['platform'].include?('ubuntu')
'cp $(puppet config print localcacert) /usr/local/share/ca-certificates/ && update-ca-certificates'
'cp $(puppet config print localcacert) /usr/local/share/ca-certificates/splunk_hec.crt && update-ca-certificates'
else
'cp $(puppet config print localcacert) /etc/pki/ca-trust/source/anchors/ && update-ca-trust'
'cp $(puppet config print localcacert) /etc/pki/ca-trust/source/anchors/splunk_hec.pem && update-ca-trust'
end
else
'cp $(puppet config print localcacert) /etc/puppetlabs/puppet/splunk_hec/'
Expand Down
4 changes: 2 additions & 2 deletions templates/settings.yaml.epp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
<% if $splunk_hec::ssl_ca { -%>
"ssl_ca" : "<%= $splunk_hec::ssl_ca %>"
<% } -%>
<% if $splunk_hec::ignore_system_cert_store { -%>
"ignore_system_cert_store" : "<%= $splunk_hec::ignore_system_cert_store %>"
<% if $splunk_hec::include_system_cert_store { -%>
"include_system_cert_store" : "<%= $splunk_hec::include_system_cert_store %>"
<% } -%>
<% if $splunk_hec::record_event { -%>
"record_event" : "<%= $splunk_hec::record_event %>"
Expand Down
39 changes: 25 additions & 14 deletions templates/util_splunk_hec.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/opt/puppetlabs/puppet/bin/ruby

require 'facter'
require 'fileutils'
require 'net/http'
require 'net/https'
Expand Down Expand Up @@ -52,24 +53,34 @@ def create_http(source_type)
http.read_timeout = timeout.to_i
http.use_ssl = @uri.scheme == 'https'
if http.use_ssl?
if settings['ssl_ca'] && !settings['ssl_ca'].empty?
ssl_ca = File.join(@confdir, 'splunk_hec', settings['ssl_ca'])

raise "CA file #{ssl_ca} does not exist" unless File.exist? ssl_ca

ssl_info_message = "Will verify #{splunk_url} SSL identity"

if settings['ignore_system_cert_store']
http.cert_store = build_ca_store(ssl_ca)
ssl_info_message = "#{ssl_info_message} ignoring system cert store"
else
http.ca_file = ssl_ca
if (settings['ssl_ca'] && !settings['ssl_ca'].empty?) || settings['include_system_cert_store']
ssl_ca_file = if settings['ssl_ca']
File.join(@confdir, settings['ssl_ca'])
elsif !settings['ssl_ca'] && Facter.value(:os)['family'].eql?('RedHat')
'/etc/ssl/certs/ca-bundle.crt'
elsif !settings['ssl_ca'] && Facter.value(:os)['family'].eql?('Suse')
'/etc/ssl/ca-bundle.pem'
else
'/etc/ssl/certs/ca-certificates.crt'
end
message = if settings['ssl_ca']
"Puppet will verify #{splunk_url} SSL identity against Splunk HEC SSL #{settings['ssl_ca']}"
else
"Puppet will verify #{splunk_url} SSL identity against system store"
end

unless File.exist?(ssl_ca_file) && !File.zero?(ssl_ca_file)
raise Puppet::Error,
"CA file #{ssl_ca_file} is an empty file or does not exist"
end

puts ssl_info_message
ssl_ca = build_ca_store(ssl_ca_file)
http.cert_store = ssl_ca
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
puts message
else
puts "Will NOT verify #{splunk_url} SSL identity"
message = "Puppet will NOT verify #{splunk_url} SSL identity"
puts message
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
end
Expand Down

0 comments on commit 9a8f00b

Please sign in to comment.