From bee364eccce12cb27af9b28543f3a3bef13f5990 Mon Sep 17 00:00:00 2001 From: Fabien COMBERNOUS <fabien.combernous@adullact.org> Date: Fri, 4 Nov 2022 18:48:22 +0100 Subject: [PATCH] add generated crl --- manifests/ca/root.pp | 6 ++-- manifests/init.pp | 56 +++++++++++++++++++++++++++++- spec/acceptance/cfssl_spec.rb | 6 ++++ templates/cfssl-gencrl.service.epp | 9 +++++ templates/cfssl-gencrl.sh.epp | 24 +++++++++++++ templates/cfssl-gencrl.timer.epp | 9 +++++ 6 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 templates/cfssl-gencrl.service.epp create mode 100644 templates/cfssl-gencrl.sh.epp create mode 100644 templates/cfssl-gencrl.timer.epp diff --git a/manifests/ca/root.pp b/manifests/ca/root.pp index cb424f4..b323aa4 100644 --- a/manifests/ca/root.pp +++ b/manifests/ca/root.pp @@ -4,13 +4,13 @@ # # @example # include cfssl::ca::root +# class cfssl::ca::root ( Hash $subject = { 'C' => 'FR', 'L' => 'MONTPELLIER', 'O' => 'EXEMPLE ORG', 'OU' => 'IT Dept' }, String[1] $cn = 'EXEMPLE ROOT CA GEN1', String[1] $expiry = '43800h', Cfssl::Ca::Key $key = { algo => 'rsa', size => 2048 }, ) { - $_rootca_filename = 'ROOT_ca' $_rootca_csr = { cn => $cn, names => [$subject], @@ -21,8 +21,8 @@ class cfssl::ca::root ( exec { "initca ${cn}": path => "/usr/bin:${cfssl::binpath}", - command => "echo '${_rootca_csr_json}' | cfssl gencert -initca - | cfssljson -bare ${cfssl::confdir}/ca/${_rootca_filename}", - creates => "${cfssl::confdir}/ca/${_rootca_filename}-key.pem", + command => "echo '${_rootca_csr_json}' | cfssl gencert -initca - | cfssljson -bare ${cfssl::confdir}/ca/${cfssl::serve_ca}", + creates => "${cfssl::confdir}/ca/${cfssl::serve_ca}-key.pem", user => $cfssl::sysuser, } } diff --git a/manifests/init.pp b/manifests/init.pp index daa922f..506b18f 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -4,6 +4,9 @@ # # @example # include cfssl +# +# @param crl_expiry A value, in seconds, after which the CRL should expire from the moment of the request +# class cfssl ( Hash $rootca_manifest = {}, Stdlib::HTTPSUrl $downloadurl = 'https://github.com/cloudflare/cfssl/releases/download', @@ -23,6 +26,10 @@ class cfssl ( Stdlib::Absolutepath $binpath = '/usr/local/bin', Cfssl::Serveconfig $serve_config = { signing => { 'default' => { expiry => '1h', usages => ['client auth'] } } }, String[1] $serve_ca = 'ROOT_ca', + Boolean $crl_manage = true, + Stdlib::Absolutepath $crldir = '/var/cfssl', + Integer $crl_expiry = 604800, + String[1] $crl_gentimer = '*:00:00', ) { include cfssl::goose include postgresql::server @@ -32,6 +39,8 @@ class cfssl ( $_goose_cfssldbmigrate_path = "/home/${sysuser}/goose-cfssldbmigrate" $_serve_config_json = 'serve-config.json' $_db_config_json = 'db-config.json' + $_systemd_unitdir = '/etc/systemd/system' + $_crlunits = ['cfssl-gencrl.service', 'cfssl-gencrl.timer'] group { $sysgroup : ensure => present, @@ -76,7 +85,7 @@ class cfssl ( } } - file { [$confdir, "${confdir}/ca", $logdir]: + file { [$confdir, "${confdir}/ca", $logdir, $crldir]: ensure => directory, mode => '0700', owner => $sysuser, @@ -163,4 +172,49 @@ class cfssl ( subscribe => Archive["${binpath}/cfssl"], provider => 'systemd', } + + if $cfssl::crl_manage { + ensure_packages(['jq','coreutils'], { ensure => 'present' }) + + file { "${cfssl::binpath}/cfssl-gencrl.sh": + ensure => file, + mode => '0755', + owner => 0, + group => 0, + content => epp('cfssl/cfssl-gencrl.sh.epp'), + } + + $_crlunits.each | String $_crlunit | { + file { "${_systemd_unitdir}/${_crlunit}": + ensure => file, + mode => '0644', + owner => 0, + group => 0, + content => epp("cfssl/${$_crlunit}.epp"), + } + ~> service { $_crlunit: + ensure => 'running', + enable => true, + require => [ + File["${cfssl::binpath}/cfssl-gencrl.sh"], + Service['cfssl'], + ], + provider => 'systemd', + } + } + } else { + $_crlunits.each | String $_crlunit | { + service { $_crlunit: + ensure => 'stopped', + enable => false, + provider => 'systemd', + } + -> file { "${_systemd_unitdir}/${_crlunit}": + ensure => absent, + } + } + file { "${cfssl::binpath}/cfssl-gencrl.sh": + ensure => absent, + } + } } diff --git a/spec/acceptance/cfssl_spec.rb b/spec/acceptance/cfssl_spec.rb index 86ad2d9..fc61303 100644 --- a/spec/acceptance/cfssl_spec.rb +++ b/spec/acceptance/cfssl_spec.rb @@ -20,5 +20,11 @@ describe 'cfssl' do describe command('curl -s -d "{}" -H "Content-Type: application/json" -X POST 127.0.0.1:8080/api/v1/cfssl/info') do its(:stdout) { is_expected.to match %r{BEGIN CERTIFICATE} } end + describe command('openssl crl -in /var/cfssl/crl.pem -text -noout') do + # rubocop:disable RSpec/RepeatedDescription + its(:stdout) { is_expected.to match %r{Certificate Revocation List } } + its(:stdout) { is_expected.to match %r{Issuer: C = FR, L = MONTPELLIER, O = EXEMPLE ORG, OU = IT Dept, CN = EXEMPLE ROOT CA GEN1} } + its(:stdout) { is_expected.to match %r{No Revoked Certificates} } + end end end diff --git a/templates/cfssl-gencrl.service.epp b/templates/cfssl-gencrl.service.epp new file mode 100644 index 0000000..232b1a0 --- /dev/null +++ b/templates/cfssl-gencrl.service.epp @@ -0,0 +1,9 @@ +[Unit] +Description=CloudFlare's PKI CRL generator +Requires=network-online.target +After=cfssl.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=<%= $cfssl::binpath %>/cfssl-gencrl.sh diff --git a/templates/cfssl-gencrl.sh.epp b/templates/cfssl-gencrl.sh.epp new file mode 100644 index 0000000..980a73a --- /dev/null +++ b/templates/cfssl-gencrl.sh.epp @@ -0,0 +1,24 @@ +#!/bin/bash + +TMPFILE="/tmp/crl${$}.pem" + +echo "-----BEGIN X509 CRL-----" > $TMPFILE +curl -s -d '{}' -H "Content-Type: application/json" -X GET <%= $cfssl::binding_ip %>:<%= $cfssl::port %>/api/v1/cfssl/crl?expiry=<%= $cfssl::crl_expiry %>s | jq -r '.result' | fold -w 64 >> $TMPFILE +echo "-----END X509 CRL-----" >> $TMPFILE + +if [ -s $TMPFILE ] +then + if openssl crl -in $TMPFILE -text -noout | grep -qP '^Certificate Revocation List ' + then + # the temp file looks as expected, we move it to crldir + cp $TMPFILE <%= $cfssl::crldir %>/crl.pem + else + echo "gencrl : missing header 'Certificate Revocation List'" + exit 1 + fi +else + echo "gencrl : empty file" + exit 1 +fi + + diff --git a/templates/cfssl-gencrl.timer.epp b/templates/cfssl-gencrl.timer.epp new file mode 100644 index 0000000..61c8970 --- /dev/null +++ b/templates/cfssl-gencrl.timer.epp @@ -0,0 +1,9 @@ +[Unit] +Description=CloudFlare's PKI CRL generator + +[Timer] +OnCalendar=*-*-* <%= $cfssl::crl_gentimer %> +Persistent=true + +[Install] +WantedBy=timers.target -- GitLab