Custom hook scripts
The pki-realm script supports usage of a custom hook scripts located in
the /etc/pki/hooks/ directory. These scripts will be executed in alphabetical
order (see run-parts(8) for more details) within a special environment. You
can use that to perform operations after certain actions like creation of a new
PKI realm, or activation of a new certificate.
Execution environment
The hook scripts will be executed by the root account inside the PKI hook
directory (/etc/pki/hooks/), with a set of $PKI_SCRIPT_* environment
variables:
$PKI_SCRIPT_REALMContains the name of the current PKI realm.
$PKI_SCRIPT_FQDNContains Fully Qualified Domain Name used as the default domain if the realm does not specify one in it's name.
$PKI_SCRIPT_SUBJECTContains the Distinguished Name, or subject of the certificate, each element separated by the
/character, similar to the format of theopenssl req -subjoption.$PKI_SCRIPT_DOMAINSList of apex (root) domains configured for the realm, separated by the
/character.$PKI_SCRIPT_SUBDOMAINSList of subdomains which should be added to each apex domain, each one separated by the
/character. The special_wildcard_name means a wildcard subdomain (*.example.com).$PKI_SCRIPT_PRIVATE_KEYAbsolute path to the private key of the current PKI realm.
$PKI_SCRIPT_DEFAULT_CRTAbsolute path to the current PKI realm certificate chain, expected to be used in the application configuration files.
$PKI_SCRIPT_DEFAULT_KEYAbsolute path to the current PKI realm private key, expected to be used in the application configuration files.
$PKI_SCRIPT_DEFAULT_PEMAbsolute path to the current PKI realm combined private key and certificate chain, expected to be used in the application configuration files.
$PKI_SCRIPT_STATEA list of PKI realm states separated by the
,character. You can inspect this variable to determine the current state of the realm (initialization, activation of new certificates, changed files) and react to it in the script.
Known script states
You can use the $PKI_SCRIPT_STATE variable to check current state of the
PKI realm. This variable should always be non-empty, otherwise hook scripts are
not executed. Each state can repeat multiple times on the list, but you should
avoid multiple execution due to a particular state.
List of known states:
new-realmA new PKI realm has been initialized, there are no private keys or certificates present.
new-private-keyA private key has been generated.
new-internal-requestA new internal CA certificate signing request has been generated.
new-acme-requestA new ACME certificate signing request has been generated.
changed-certificateA new certificate has been activated, or there has been change of the active Certificate Authority (internal, external, acme).
changed-dhparamDiffie-Hellman parameters in the certificate chain have been added/updated.
file-changeA generic file change notification.
file-deletionA file has been deleted.
changed-public-fileSome of the files in
public/directory have been changed/replaced.changed-private-fileSome of the files in
private/directory have been changed/replaced.
Example nginx hook
This is an example hook script which detects if a given PKI realm is currently used by the nginx server and if so, when a certificate change is detected it reloads the nginx daemon so that new certificate can be activated.
#!/bin/bash
# Reload or restart nginx on a certificate state change
set -o nounset -o pipefail -o errexit
nginx_config="/etc/nginx/nginx.conf"
nginx_sites="/etc/nginx/sites-enabled"
nginx_action="reload"
# Check if current PKI realm is used by the 'nginx' webserver
certificate=$(grep -r "${PKI_SCRIPT_DEFAULT_CRT:-}" ${nginx_sites}/* || true)
# Get list of current realm states
states=( $(echo "${PKI_SCRIPT_STATE:-}" | tr "," " ") )
if [ -n "${certificate}" -a "${#states[@]}" -gt 0 ] ; then
for state in "${states[@]}" ; do
if [ "${state}" = "changed-certificate" -o "${state}" = "changed-dhparam" ] ; then
# Check if current init is systemd
if $(pidof systemd > /dev/null 2>&1) ; then
nginx_state="$(systemctl is-active nginx.service)"
if [ ${nginx_state} = "active" ] ; then
if $(/usr/sbin/nginx -c ${nginx_config} -t > /dev/null 2>&1) ; then
systemctl ${nginx_action} nginx.service
fi
fi
else
nginx_pidfile="$(grep -E '^pid\s+' ${nginx_config} | awk '{print $2}' | cut -d\; -f1)"
if $(kill -0 $(<${nginx_pidfile}) > /dev/null 2>&1) ; then
if $(/usr/sbin/nginx -c ${nginx_config} -t > /dev/null 2>&1) ; then
service nginx ${nginx_action}
fi
fi
fi
break
fi
done
fi