diff --git a/files/check_cert.sh b/files/check_cert.sh index 28bbe63..cc653ab 100644 --- a/files/check_cert.sh +++ b/files/check_cert.sh @@ -27,10 +27,10 @@ deploy_cert() { EXISTING_FULLCHAIN_PATH=$8 echo "deploying cert to $EXISTING_CERT_PATH" - echo "$NEWCERT" > $EXISTING_CERT_PATH - echo "$NEWKEY" > $EXISTING_KEY_PATH - echo "$NEWCHAIN" > $EXISTING_CHAIN_PATH - echo "$NEWFULLCHAIN" > $EXISTING_FULLCHAIN_PATH + echo "$NEWCERT" > "$EXISTING_CERT_PATH" + echo "$NEWKEY" > "$EXISTING_KEY_PATH" + echo "$NEWCHAIN" > "$EXISTING_CHAIN_PATH" + echo "$NEWFULLCHAIN" > "$EXISTING_FULLCHAIN_PATH" } @@ -44,10 +44,9 @@ EXISTING_CHAIN_PATH="${EXISTING_CERT_DIR}/chain.pem" EXISTING_FULLCHAIN_PATH="${EXISTING_CERT_DIR}/fullchain.pem" # variables -ONE_WEEK=604800 TODAY=$(date --iso-8601) # use VAULT_BIN if defined, otherwise, assume /usr/local/bin/vault -: ${VAULT_BIN:="/usr/local/bin/vault"} +: "${VAULT_BIN:=/usr/local/bin/vault}" NEWCERT_VAULT_PATH="/secret/letsencrypt/${DOMAIN}/cert.pem" @@ -56,10 +55,10 @@ NEWCHAIN_VAULT_PATH="/secret/letsencrypt/${DOMAIN}/chain.pem" NEWFULLCHAIN_VAULT_PATH="/secret/letsencrypt/${DOMAIN}/fullchain.pem" # Get new cert info -NEWCERT=$($VAULT_BIN kv get -field=value $NEWCERT_VAULT_PATH) || exit -1 -NEWKEY=$($VAULT_BIN kv get -field=value $NEWKEY_VAULT_PATH) || exit -1 -NEWCHAIN=$($VAULT_BIN kv get -field=value $NEWCHAIN_VAULT_PATH) || exit -1 -NEWFULLCHAIN=$($VAULT_BIN kv get -field=value $NEWFULLCHAIN_VAULT_PATH) || exit -1 +NEWCERT=$($VAULT_BIN kv get -field=value "$NEWCERT_VAULT_PATH") || exit 1 +NEWKEY=$($VAULT_BIN kv get -field=value "$NEWKEY_VAULT_PATH") || exit 1 +NEWCHAIN=$($VAULT_BIN kv get -field=value "$NEWCHAIN_VAULT_PATH") || exit 1 +NEWFULLCHAIN=$($VAULT_BIN kv get -field=value "$NEWFULLCHAIN_VAULT_PATH") || exit 1 NEWCERT_FINGERPRINT=$(get_fingerprint "$NEWCERT") NEWCERT_ENDDATE=$(get_enddate "$NEWCERT") @@ -67,7 +66,7 @@ NEWCERT_ENDDATE=$(get_enddate "$NEWCERT") if [ "$NEWCERT_FINGERPRINT" == "" ] then echo "no valid new cert found!" - exit -1 + exit 1 fi #echo "new fingerprint: $NEWCERT_FINGERPRINT" @@ -76,16 +75,16 @@ fi # Get existing cert info if it exists. if it doesn't exist, we don't need to # check it, we can just deploy. -if [ -e $EXISTING_CERT_PATH ] +if [ -e "$EXISTING_CERT_PATH" ] then - EXISTING_CERT=$(cat $EXISTING_CERT_PATH) + EXISTING_CERT=$(cat "$EXISTING_CERT_PATH") EXISTING_CERT_FINGERPRINT=$(get_fingerprint "$EXISTING_CERT") EXISTING_CERT_ENDDATE=$(get_enddate "$EXISTING_CERT") else # create destination dir if needed - if [ ! -d $EXISTING_CERT_DIR ] + if [ ! -d "$EXISTING_CERT_DIR" ] then - mkdir -p $EXISTING_CERT_DIR + mkdir -p "$EXISTING_CERT_DIR" fi deploy_cert "$NEWCERT" "$NEWKEY" "$NEWCHAIN" "$NEWFULLCHAIN" "$EXISTING_CERT_PATH" "$EXISTING_KEY_PATH" "$EXISTING_CHAIN_PATH" "$EXISTING_FULLCHAIN_PATH" exit 0 @@ -99,29 +98,23 @@ fi # if it is the same, exit normally, this will be the common case if [ "$NEWCERT_FINGERPRINT" == "$EXISTING_CERT_FINGERPRINT" ] then - exit -1 + exit 1 fi # check that new cert is newer than current cert if [ "$EXISTING_CERT_ENDDATE" \> "$NEWCERT_ENDDATE" ] then echo "existing cert expiration is older, exiting" - exit -1 + exit 1 fi # check that new cert is not expired if [ "$NEWCERT_ENDDATE" \< "$TODAY" ] then echo "new cert is expired, exiting" - exit -1 + exit 1 fi # if we made it this far, the cert looks good, replace it deploy_cert "$NEWCERT" "$NEWKEY" "$NEWCHAIN" "$NEWFULLCHAIN" "$EXISTING_CERT_PATH" "$EXISTING_KEY_PATH" "$EXISTING_CHAIN_PATH" "$EXISTING_FULLCHAIN_PATH" - - - -#openssl x509 -in <($VAULT_BIN kv get -field=value /secret/apidb.org/cert.pem) -noout -checkend 8640000 - - diff --git a/manifests/common.pp b/manifests/common.pp index ac10934..ff1dd2e 100644 --- a/manifests/common.pp +++ b/manifests/common.pp @@ -1,6 +1,23 @@ -# Common configuration for acme_vault +# acme_vault::common +# +# This class defines the common configuration for the acme_vault module. +# It sets up the necessary user, group, home directory, and environment +# variables for the acme_vault module to interact with Let's Encrypt and +# HashiCorp Vault for certificate management. +# +# @param user The system user for the acme_vault module. +# @param group The system group for the acme_vault module. +# @param group_members Additional group members that require access to the certificates. +# @param home_dir The home directory for the acme_vault user. +# @param contact_email The email address for Let's Encrypt registration and notifications. +# @param domains The list of domain names to request certificates for. +# @param overrides A hash of domain-specific configuration overrides. +# +# @param vault_token The authentication token for accessing HashiCorp Vault. +# @param vault_addr The address of the HashiCorp Vault server. +# @param vault_bin The path to the Vault binary. +# @param vault_prefix The prefix for storing certificates in Vault. # - class acme_vault::common ( $user = $::acme_vault::params::user, $group = $::acme_vault::params::group, @@ -46,9 +63,9 @@ class acme_vault::common ( # that require access to the certs @group { $group: - ensure => present, - system => true, - tag => 'acme_vault_group', + ensure => present, + system => true, + tag => 'acme_vault_group', } # include lines similar to this in your own modules to add members to the @@ -82,7 +99,7 @@ class acme_vault::common ( # renew vault token cron { 'renew vault token': - command => ". \$HOME/.bashrc && $vault_bin token renew > /dev/null", + command => ". \$HOME/.bashrc && ${vault_bin} token renew > /dev/null", user => $user, weekday => 1, hour => 10, @@ -90,4 +107,3 @@ class acme_vault::common ( } } - diff --git a/manifests/deploy.pp b/manifests/deploy.pp index 0d3f1dc..daf32e5 100644 --- a/manifests/deploy.pp +++ b/manifests/deploy.pp @@ -1,6 +1,19 @@ -# Configuration for deploying certs in vault to the filesystem +# acme_vault::deploy +# +# This class configures the deployment of certificates from HashiCorp Vault +# to the filesystem. It sets up the necessary directory structure, scripts, +# and cron jobs to periodically check for and deploy updated certificates +# for the specified domains. +# +# @param user The system user for the acme_vault module. +# @param group The system group for the acme_vault module. +# @param home_dir The home directory for the acme_vault user. +# @param domains The list of domain names for which certificates will be deployed. +# +# @param cert_destination_path The directory where certificates will be deployed on the filesystem. +# @param deploy_scripts The directory where deployment scripts will be stored. +# @param restart_method The command to run after certificate deployment (e.g., to restart dependent services). # - class acme_vault::deploy( $user = $::acme_vault::common::user, $group = $::acme_vault::common::group, diff --git a/manifests/params.pp b/manifests/params.pp index 1997db0..47ccfa5 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -1,29 +1,63 @@ -# params for both common, request, and deploy +# acme_vault::params +# +# This class defines the default parameters for the acme_vault module. +# It includes settings for the acme user, authentication, staging and production URLs, +# repository paths, Namecheap configuration, and deployment settings. +# +# @param user The system user for the acme_vault module. +# @param group The system group for the acme_vault module. +# @param group_members Members of the acme_vault group. +# @param home_dir The home directory for the acme_vault user. +# @param contact_email The contact email address for Let's Encrypt notifications. +# @param domains The list of domain names for which certificates will be requested and managed. +# @param overrides A list of challenge-alias overrides. Defaults to the domain itself. +# +# @param vault_token HashiCorp Vault authentication token. +# @param vault_addr HashiCorp Vault server address. +# @param vault_bin Path to the HashiCorp Vault binary. +# @param vault_prefix The path prefix in Vault where Let's Encrypt secrets are stored. +# +# @param staging Whether to use the Let's Encrypt staging environment. +# @param staging_url Let's Encrypt staging environment API URL. +# @param prod_url Let's Encrypt production environment API URL. +# +# @param acme_revision The revision of the acme.sh script to use. +# @param acme_repo_path The path to the acme.sh repository. +# @param acme_script The path to the acme.sh script within the repository. +# +# @param namecheap_username Namecheap account username for DNS API. +# @param namecheap_api_key Namecheap API key. +# @param namecheap_sourceip The source IP address for Namecheap API requests. +# +# @param cert_destination_path The directory where certificates will be deployed on the filesystem. +# @param deploy_scripts The directory where deployment scripts will be stored. +# @param restart_method The command to run after certificate deployment (e.g., to restart dependent services). +# class acme_vault::params { # settings for acme user - $user = 'acme' - $group = 'acme' - $group_members = [] - $home_dir = '/home/acme_vault' - $contact_email = '' - $domains = undef + $user = 'acme' + $group = 'acme' + $group_members = [] + $home_dir = '/home/acme_vault' + $contact_email = '' + $domains = undef # overrides is a list of challenge-alias overrides. It defaults to the domain itself. # see https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode - $overrides = {} + $overrides = {} # authentication - $vault_token = undef - $vault_addr = undef - $vault_bin = "/usr/local/bin/vault" + $vault_token = undef + $vault_addr = undef + $vault_bin = '/usr/local/bin/vault' $vault_prefix = '/secret/letsencrypt/' # whether to use the letsencrypt staging url, set those urls - $staging = false - $staging_url = 'https://acme-staging-v02.api.letsencrypt.org/directory' - $prod_url = 'https://acme-v02.api.letsencrypt.org/directory' + $staging = false + $staging_url = 'https://acme-staging-v02.api.letsencrypt.org/directory' + $prod_url = 'https://acme-v02.api.letsencrypt.org/directory' - $acme_revision = 'HEAD' + $acme_revision = 'HEAD' $acme_repo_path = "${home_dir}/acme.sh" $acme_script = "${acme_repo_path}/acme.sh" diff --git a/manifests/request.pp b/manifests/request.pp index 5f4be8d..54951fe 100644 --- a/manifests/request.pp +++ b/manifests/request.pp @@ -1,6 +1,27 @@ -# Configuration for requesting a cert from letsencrypt, and storing it in vault. +# acme_vault::request +# +# This class configures the certificate request process from Let's Encrypt, +# and stores the obtained certificates in HashiCorp Vault. +# +# @param user The system user for the acme_vault module. +# @param group The system group for the acme_vault module. +# @param home_dir The home directory for the acme_vault user. +# @param contact_email The contact email address for Let's Encrypt notifications. +# @param domains The list of domain names for which certificates will be requested and managed. +# @param overrides A list of challenge-alias overrides. Defaults to the domain itself. +# +# @param staging Whether to use the Let's Encrypt staging environment. +# @param staging_url Let's Encrypt staging environment API URL. +# @param prod_url Let's Encrypt production environment API URL. +# +# @param acme_revision The revision of the acme.sh script to use. +# @param acme_repo_path The path to the acme.sh repository. +# @param acme_script The path to the acme.sh script within the repository. +# +# @param namecheap_username Namecheap account username for DNS API. +# @param namecheap_api_key Namecheap API key. +# @param namecheap_sourceip The source IP address for Namecheap API requests. # - class acme_vault::request ( $user = $::acme_vault::common::user, $group = $::acme_vault::common::group, @@ -26,11 +47,11 @@ class acme_vault::request ( include acme_vault::common $request_bashrc_template = @(END) -export TLDEXTRACT_CACHE=$HOME/.tld_set -export NAMECHEAP_USERNAME=<%= @namecheap_username %> -export NAMECHEAP_API_KEY=<%= @namecheap_api_key %> -export NAMECHEAP_SOURCEIP=<%= @namecheap_sourceip %> -END + export TLDEXTRACT_CACHE=$HOME/.tld_set + export NAMECHEAP_USERNAME=<%= @namecheap_username %> + export NAMECHEAP_API_KEY=<%= @namecheap_api_key %> + export NAMECHEAP_SOURCEIP=<%= @namecheap_sourceip %> + | END # variables in bashrc concat::fragment { 'request_bashrc': @@ -53,14 +74,14 @@ END owner => $user, group => $group, mode => '0700', - } -> - file { "${home_dir}/.acme.sh/account.conf": + } + -> file { "${home_dir}/.acme.sh/account.conf": ensure => present, owner => $user, group => $group, mode => '0600', - } -> - file_line { ' add email to acme conf': + } + -> file_line { ' add email to acme conf': path => "${home_dir}/.acme.sh/account.conf", line => "ACCOUNT_EMAIL='${contact_email}'", match => '^ACCOUNT_EMAIL=.*$', @@ -86,7 +107,7 @@ END ) } cron { "${domain}_issue": - command => "${home_dir}/${domain}.sh", + command => ". \$HOME/.bashrc && ${home_dir}/${domain}.sh", user => $user, weekday => 1, hour => 11,