Skip to content

Commit

Permalink
Merge pull request #107 from StatensPensjonskasse/support-distrust-fo…
Browse files Browse the repository at this point in the history
…r-debian

Support distrusting ca's on Debian; Changed ca_cert::ca parameter names and meaning
  • Loading branch information
h-haaks authored Jun 5, 2024
2 parents 91fd25d + 6dd5a4d commit 79cfb7a
Show file tree
Hide file tree
Showing 9 changed files with 327 additions and 322 deletions.
74 changes: 38 additions & 36 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,17 @@

### Classes

* [`ca_cert`](#ca_cert): This module manages the user defined certificate authority (CA)
certificates on the server. On OSes that support a distrusted
folder the module also manages distrusting system default CA certificates.
* [`ca_cert`](#ca_cert): This module manages the shared system-wide truststore.

### Defined types

* [`ca_cert::ca`](#ca_cert--ca): Manage a user defined CA Certificate on a system.
On OSes that support distrusting pre-installed CAs this can be managed as well.
* [`ca_cert::ca`](#ca_cert--ca): Manage a CA Certificate in the the shared system-wide truststore.

## Classes

### <a name="ca_cert"></a>`ca_cert`

This module manages the user defined certificate authority (CA)
certificates on the server. On OSes that support a distrusted
folder the module also manages distrusting system default CA certificates.
This module manages the shared system-wide truststore.

#### Examples

Expand Down Expand Up @@ -60,6 +55,7 @@ The following parameters are available in the `ca_cert` class:
* [`update_cmd`](#-ca_cert--update_cmd)
* [`trusted_cert_dir`](#-ca_cert--trusted_cert_dir)
* [`distrusted_cert_dir`](#-ca_cert--distrusted_cert_dir)
* [`ca_certificates_conf`](#-ca_cert--ca_certificates_conf)
* [`install_package`](#-ca_cert--install_package)
* [`package_ensure`](#-ca_cert--package_ensure)
* [`package_name`](#-ca_cert--package_name)
Expand Down Expand Up @@ -95,6 +91,15 @@ Default provided by Hiera for supported Operating Systems.

Default value: `undef`

##### <a name="-ca_cert--ca_certificates_conf"></a>`ca_certificates_conf`

Data type: `Optional[Stdlib::Absolutepath]`

Some distros use a configuration file to mark distrusted certificates.
Default provided by Hiera for supported Operating Systems.

Default value: `undef`

##### <a name="-ca_cert--install_package"></a>`install_package`

Data type: `Boolean`
Expand Down Expand Up @@ -198,8 +203,7 @@ Default value: `{}`

### <a name="ca_cert--ca"></a>`ca_cert::ca`

Manage a user defined CA Certificate on a system.
On OSes that support distrusting pre-installed CAs this can be managed as well.
Manage a CA Certificate in the the shared system-wide truststore.

#### Examples

Expand All @@ -215,55 +219,53 @@ ca_cert::ca { 'globalsign_org_intermediate':

The following parameters are available in the `ca_cert::ca` defined type:

* [`ca_text`](#-ca_cert--ca--ca_text)
* [`source`](#-ca_cert--ca--source)
* [`ensure`](#-ca_cert--ca--ensure)
* [`verify_https_cert`](#-ca_cert--ca--verify_https_cert)
* [`content`](#-ca_cert--ca--content)
* [`source`](#-ca_cert--ca--source)
* [`allow_insecure_source`](#-ca_cert--ca--allow_insecure_source)
* [`checksum`](#-ca_cert--ca--checksum)
* [`checksum_type`](#-ca_cert--ca--checksum_type)

##### <a name="-ca_cert--ca--ca_text"></a>`ca_text`
##### <a name="-ca_cert--ca--ensure"></a>`ensure`

Data type: `Optional[String]`
Data type: `Enum['present', 'absent', 'trusted', 'distrusted']`

The text of the CA certificate to install. Required if text is the source
(default). If a different source is specified this parameter is ignored.
Whether or not the CA certificate should be on a system or not.
- `present`/`absent` is used to manage local/none default CAs.
- `trusted`/`distrusted` is used to manage system CAs.

Default value: `undef`
Default value: `'present'`

##### <a name="-ca_cert--ca--source"></a>`source`
##### <a name="-ca_cert--ca--content"></a>`content`

Data type: `String`
Data type: `Optional[String[1]]`

Where the CA certificate should be retrieved from. text, http, https, ftp,
file, and puppet protocols/sources are supported. If text, then the ca_text parameter
is also required. Defaults to text.
PEM formatted certificate content
This attribute is mutually exclusive with `source`

Default value: `'text'`
Default value: `undef`

##### <a name="-ca_cert--ca--ensure"></a>`ensure`
##### <a name="-ca_cert--ca--source"></a>`source`

Data type: `Enum['present', 'trusted', 'distrusted', 'absent']`
Data type: `Optional[String[1]]`

Whether or not the CA certificate should be on a system or not. Valid
values are trusted, present, distrusted, and absent. Note: untrusted is
not supported on Debian based systems - using it will log a warning
and treat it the same as absent. (defaults to trusted)
A source certificate, which will be copied into place on the local system.
This attribute is mutually exclusive with `content`
Uri support, see puppet-archive.

Default value: `'trusted'`
Default value: `undef`

##### <a name="-ca_cert--ca--verify_https_cert"></a>`verify_https_cert`
##### <a name="-ca_cert--ca--allow_insecure_source"></a>`allow_insecure_source`

Data type: `Boolean`

When retrieving a certificate whether or not to validate the CA of the
source. (defaults to true)
Wether to allow insecure download or not.

Default value: `true`
Default value: `false`

##### <a name="-ca_cert--ca--checksum"></a>`checksum`

Data type: `Optional[String]`
Data type: `Optional[String[1]]`

The checksum of the file. (defaults to undef)

Expand Down
4 changes: 2 additions & 2 deletions data/Archlinux-family.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
---
ca_cert::update_cmd: 'trust extract-compat'
ca_cert::trusted_cert_dir: '/etc/ca-certificates/trust-source/anchors/'
ca_cert::distrusted_cert_dir: '/etc/ca-certificates/trust-source/blacklist'
ca_cert::trusted_cert_dir: '/etc/ca-certificates/trust-source/anchors'
ca_cert::distrusted_cert_dir: '/etc/ca-certificates/trust-source/blocklist'
5 changes: 3 additions & 2 deletions data/Debian-family.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---
ca_cert::update_cmd: 'update-ca-certificates'
ca_cert::trusted_cert_dir: '/usr/local/share/ca-certificates'
ca_cert::update_cmd: 'update-ca-certificates'
ca_cert::trusted_cert_dir: '/usr/local/share/ca-certificates'
ca_cert::ca_certificates_conf: '/etc/ca-certificates.conf'
2 changes: 2 additions & 0 deletions data/RedHat-family-9.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
ca_cert::distrusted_cert_dir: '/etc/pki/ca-trust/source/blocklist'
141 changes: 62 additions & 79 deletions manifests/ca.pp
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
# @summary
# Manage a user defined CA Certificate on a system.
# On OSes that support distrusting pre-installed CAs this can be managed as well.
# Manage a CA Certificate in the the shared system-wide truststore.
#
# @example
# ca_cert::ca { 'globalsign_org_intermediate':
# source => 'http://secure.globalsign.com/cacert/gsorganizationvalsha2g2r1.crt',
# }
#
# @param ca_text
# The text of the CA certificate to install. Required if text is the source
# (default). If a different source is specified this parameter is ignored.
# @param ensure
# Whether or not the CA certificate should be on a system or not.
# - `present`/`absent` is used to manage local/none default CAs.
# - `trusted`/`distrusted` is used to manage system CAs.
#
# @param source
# Where the CA certificate should be retrieved from. text, http, https, ftp,
# file, and puppet protocols/sources are supported. If text, then the ca_text parameter
# is also required. Defaults to text.
# @param content
# PEM formatted certificate content
# This attribute is mutually exclusive with `source`
#
# @param ensure
# Whether or not the CA certificate should be on a system or not. Valid
# values are trusted, present, distrusted, and absent. Note: untrusted is
# not supported on Debian based systems - using it will log a warning
# and treat it the same as absent. (defaults to trusted)
# @param source
# A source certificate, which will be copied into place on the local system.
# This attribute is mutually exclusive with `content`
# Uri support, see puppet-archive.
#
# @param verify_https_cert
# When retrieving a certificate whether or not to validate the CA of the
# source. (defaults to true)
# @param allow_insecure_source
# Wether to allow insecure download or not.
#
# @param checksum
# The checksum of the file. (defaults to undef)
Expand All @@ -33,99 +30,85 @@
# The type of file checksum. (defauts to undef)
#
define ca_cert::ca (
Enum['present', 'trusted', 'distrusted', 'absent'] $ensure = 'trusted',
String $source = 'text',
Boolean $verify_https_cert = true,
Optional[String] $ca_text = undef,
Optional[String] $checksum = undef,
Enum['present', 'absent', 'trusted', 'distrusted'] $ensure = 'present',
Boolean $allow_insecure_source = false,
Optional[String[1]] $source = undef,
Optional[String[1]] $content = undef,
Optional[String[1]] $checksum = undef,
Optional[String[1]] $checksum_type = undef,
) {
include ca_cert

if ($ensure == 'trusted' or $ensure == 'distrusted') and $source == 'text' and !$ca_text {
fail('ca_text is required if source is set to text')
}

# Since Debian based OSes don't have explicit distrust directories
if $facts['os']['family'] == 'Debian' and $ensure == 'distrusted' {
warning("Cannot explicitly set CA distrust on ${facts['os']['name']}.")
warning("Ensuring that ${name} CA is absent from the trusted list.")
$adjusted_ensure = 'absent'
}
else {
$adjusted_ensure = $ensure
}

# Determine Full Resource Name
$resource_name = "${name}.${ca_cert::ca_file_extension}"

$ca_cert = $adjusted_ensure ? {
'distrusted' => "${ca_cert::distrusted_cert_dir}/${resource_name}",
default => "${ca_cert::trusted_cert_dir}/${resource_name}",
case $ensure {
'present', 'absent': {
$ca_cert = "${ca_cert::trusted_cert_dir}/${resource_name}"
}
'trusted', 'distrusted': {
$ca_cert = "${ca_cert::distrusted_cert_dir}/${resource_name}"
}
default: {}
}

case $adjusted_ensure {
'present', 'trusted', 'distrusted': {
$source_array = split($source, ':')
$protocol_type = $source_array[0]
case $protocol_type {
'puppet': {
file { $resource_name:
ensure => 'file',
source => $source,
path => $ca_cert,
owner => 'root',
group => $ca_cert::ca_file_group,
mode => $ca_cert::ca_file_mode,
notify => Exec['ca_cert_update'],
}
}
'ftp', 'https', 'http': {
# On Debian we trust/distrust Os provided CAs in config
if $facts['os']['family'] == 'Debian' and member(['trusted', 'distrusted'], $ensure) {
if $ensure == 'trusted' {
exec { "trust ca ${resource_name}":
command => "sed -ri \'s|!(.*)${resource_name}|\\1${resource_name}|\' ${ca_cert::ca_certificates_conf}",
onlyif => "grep -q ${resource_name} ${ca_cert::ca_certificates_conf} && grep -q \'^!.*${resource_name}\' ${ca_cert::ca_certificates_conf}",
path => ['/bin','/usr/bin'],
notify => Exec['ca_cert_update'],
}
} else {
exec { "distrust ca ${resource_name}":
command => "sed -ri \'s|(.*)${resource_name}|!\\1${resource_name}|\' ${ca_cert::ca_certificates_conf}",
onlyif => "grep -q ${resource_name} ${ca_cert::ca_certificates_conf} && grep -q \'^[^!].*${resource_name}\' ${ca_cert::ca_certificates_conf}",
path => ['/bin','/usr/bin'],
notify => Exec['ca_cert_update'],
}
}
}
else {
case $ensure {
'present', 'distrusted': {
if $source {
archive { $ca_cert:
ensure => 'present',
source => $source,
checksum => $checksum,
checksum_type => $checksum_type,
allow_insecure => !$verify_https_cert,
allow_insecure => $allow_insecure_source,
notify => Exec['ca_cert_update'],
}
}
'file': {
$source_path = $source_array[1]
file { $resource_name:
-> file { $ca_cert:
ensure => 'file',
source => $source_path,
path => $ca_cert,
owner => 'root',
group => $ca_cert::ca_file_group,
mode => $ca_cert::ca_file_mode,
notify => Exec['ca_cert_update'],
}
}
'text': {
file { $resource_name:
} elsif $content {
file { $ca_cert:
ensure => 'file',
content => $ca_text,
path => $ca_cert,
content => $content,
owner => 'root',
group => $ca_cert::ca_file_group,
mode => $ca_cert::ca_file_mode,
notify => Exec['ca_cert_update'],
}
}
default: {
fail('Protocol must be puppet, file, http, https, ftp, or text.')
} else {
fail('Either `source` or `content` is required')
}
}
}
'absent': {
file { $ca_cert:
ensure => absent,
notify => Exec['ca_cert_update'],
'absent', 'trusted': {
file { $ca_cert:
ensure => absent,
notify => Exec['ca_cert_update'],
}
}
}
default: {
fail("Ca_cert::Ca[${name}] - ensure must be set to present, trusted, distrusted, or absent.")
default: {}
}
}
}
9 changes: 6 additions & 3 deletions manifests/init.pp
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# @summary
# This module manages the user defined certificate authority (CA)
# certificates on the server. On OSes that support a distrusted
# folder the module also manages distrusting system default CA certificates.
# This module manages the shared system-wide truststore.
#
# @example Basic usage
# class { 'ca_cert': }
Expand Down Expand Up @@ -34,6 +32,10 @@
# Absolute directory path to the folder containing distrusted certificates.
# Default provided by Hiera for supported Operating Systems.
#
# @param ca_certificates_conf
# Some distros use a configuration file to mark distrusted certificates.
# Default provided by Hiera for supported Operating Systems.
#
# @param install_package
# Whether or not this module should install the ca_certificates package.
# The package contains the system default (typically Mozilla) CA
Expand Down Expand Up @@ -82,6 +84,7 @@
String[1] $update_cmd,
Stdlib::Absolutepath $trusted_cert_dir,
Optional[Stdlib::Absolutepath] $distrusted_cert_dir = undef,
Optional[Stdlib::Absolutepath] $ca_certificates_conf = undef,
Boolean $install_package = true,
Stdlib::Ensure::Package $package_ensure = 'installed',
String[1] $package_name = 'ca-certificates',
Expand Down
Loading

0 comments on commit 79cfb7a

Please sign in to comment.