diff --git a/global/overlay/etc/puppet/modules/cdn/files/ca_trust/trust-step-ca b/global/overlay/etc/puppet/modules/cdn/files/ca_trust/trust-step-ca new file mode 100644 index 0000000..5a053c3 --- /dev/null +++ b/global/overlay/etc/puppet/modules/cdn/files/ca_trust/trust-step-ca @@ -0,0 +1,43 @@ +#!/bin/bash + +set -eu + +step_ca_url=$1 +#step_ca_url='https://internal-sto3-test-ca-1.cdn.sunet.se:9000' +expected_root_fp=$2 +root_ca_url="$step_ca_url/root/$expected_root_fp" +root_ca_name='step_ca_root.crt' +root_ca_path="/usr/local/share/ca-certificates/$root_ca_name" +current_root_fp='' + +if [ -f "$root_ca_path" ]; then + current_root_fp=$(openssl x509 -in $root_ca_path -fingerprint -sha256 -noout | awk -F= '{print $2}' | sed 's/://g' | tr '[:upper:]' '[:lower:]') +fi + +if [ -n "$current_root_fp" ] && [ "$current_root_fp" = "$expected_root_fp" ]; then + echo "$root_ca_path: correct fingerprint" + exit 0 +fi + +tmp_dir=$(mktemp -d) + +tmp_root_path=$tmp_dir/$root_ca_name + +# We are deliberatly running curl with -k here. We can not trust the +# connection before we have the root cert, and the goal is to fetch that root +# cert. Security is attained by validating the fingerprint of the downloaded +# cert prior to installing it. +curl -ks $root_ca_url | jq -j .ca > $tmp_root_path + +tmp_fp=$(openssl x509 -in $tmp_root_path -fingerprint -sha256 -noout | awk -F= '{print $2}' | sed 's/://g' | tr '[:upper:]' '[:lower:]') + +if [ "$tmp_fp" = "$expected_root_fp" ]; then + echo "$root_ca_path: installing validated file" + mv -v $tmp_root_path $root_ca_path + + # Make OS pick up the new cert + update-ca-certificates +fi + +# We expect the directory to be empty at this point so rmdir is safer than rm -rf +rmdir -v $tmp_dir diff --git a/global/overlay/etc/puppet/modules/cdn/manifests/ca_trust.pp b/global/overlay/etc/puppet/modules/cdn/manifests/ca_trust.pp new file mode 100644 index 0000000..9ade3d0 --- /dev/null +++ b/global/overlay/etc/puppet/modules/cdn/manifests/ca_trust.pp @@ -0,0 +1,43 @@ +# Configure a SUNET CDN CA server +class cdn::ca_trust( + Hash[String, Hash[String, Hash[String, String]]] $ca_root_fp = { + test => { + url => 'https://internal-sto3-test-ca-1.cdn.sunet.se:9000', + fp => '9c7cb4b835ad1ee2d63f903032208b245c82c38823b02a05c66a5b93c1d5e32d', + }, + } +) +{ + # Files for trusting internal CA + file { '/opt/cdn-ca-trust: + ensure => directory, + owner => 'root', + group => 'root', + mode => '0755', + } + + file { '/opt/cdn-ca-trust/scripts': + ensure => directory, + owner => 'root', + group => 'root', + mode => '0755', + } + + file { '/opt/cdn-ca-trust/scripts/trust-step-ca': + ensure => file, + owner => 'root', + group => 'root', + mode => '0755', + content => file('cdn/ca_trust/trust-step-ca'), + } + + # From https://wiki.sunet.se/display/sunetops/Platform+naming+standards + $my_fqdn = $facts['networking']['fqdn'] + $dot_split = split($my_fqdn, '[.]') + $my_hostname = $dot_split[0] + $dash_split = split($my_hostname,'[-]') + $instance = $dash_split[0] + + exec { "/opt/cdn-ca-trust/scripts/trust-step-ca $ca_root_fp[$instance]['url'] $ca_root_fp[$instance]['fp']": + } +}