Skip to content

Commit

Permalink
Implement a post-renewal hook script
Browse files Browse the repository at this point in the history
Sometimes, after a certificate is renewed, you may want to do something
with the new certificate. For example, you may want to restart a web
server or reload a configuration file.

This change allows for a renewal script to be created by specifying
commands in the `step_acme_cert_post_renewal_commands` variable.

An example of this is for provisioning a certificate for UniFi's
Controller. The following configuration will update unifi's jks and
restart the service after the certificate is renewed:

```yaml
step_acme_cert_post_renewal_commands:
  - openssl pkcs12 -export -in "${CERT_FILE}" -inkey "${KEY_FILE}" -out /etc/ssl/cert.p12 -name unifi -password pass:aircontrolenterprise
  - keytool -importkeystore -deststorepass aircontrolenterprise -destkeypass aircontrolenterprise -destkeystore /usr/lib/unifi/data/keystore -srckeystore /etc/ssl/cert.p12 -srcstoretype PKCS12 -srcstorepass aircontrolenterprise -alias unifi
  - systemctl restart unifi
```

`systemctl try-reload-or-restart {{step_acme_cert_renewal_reload_services}}`
has been removed from the `ExecStart` command in the systemd unit file,
and is appended to the end of this post-renewal hook script. In the
example above, I am using `systemctl restart unifi` as the last command,
because I have experienced issues with `systemctl try-reload-or-restart`
for this specific service. For a 'more normal' service, the following
should work:

```yaml
step_acme_cert_post_renewal_commands:
  - do_something ${CERT_FILE} ${KEY_FILE}
step_acme_cert_renewal_reload_services:
  - some_service
```

The variables ${STEP_CLI}, ${CERT_FILE}, and ${KEY_FILE} are all exported
in the script by default, and are available for use in the commands.

This change is backwards compatible, and will not break existing
configurations.

Signed-off-by: Tom Whitwell <[email protected]>
  • Loading branch information
whi-tw committed Sep 14, 2022
1 parent 7113e87 commit 584128f
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 1 deletion.
2 changes: 2 additions & 0 deletions roles/step_acme_cert/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ step_acme_cert_keyfile_defaults:

step_acme_cert_renewal_service: step-renew
#step_acme_cert_renewal_when: 8h
step_acme_cert_post_renewal_shell: "/bin/sh"
step_acme_cert_post_renewal_commands: []
step_acme_cert_renewal_reload_services: []
8 changes: 8 additions & 0 deletions roles/step_acme_cert/tasks/renewal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
changed_when: no
check_mode: no

- name: Post renewal hook script is present
template:
src: step-post-renew-hook.sh.j2
dest: "{{step_cli_steppath}}/{{ step_acme_cert_renewal_service }}_post.sh"
owner: root
group: root
mode: 0744

- name: Renewal service is installed
template:
src: step-renew.service.j2
Expand Down
12 changes: 12 additions & 0 deletions roles/step_acme_cert/templates/step-post-renew-hook.sh.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!{{ step_acme_cert_post_renewal_shell }}
####### added by ansible: maxhoesel.smallstep.step_acme_cert - changes will be overwritten #######
set -eu
export STEP_CLI="{{ step_cli_executable_absolute.stdout }}"
export CERT_FILE="{{ step_acme_cert_certfile_full.path }}"
export KEY_FILE="{{ step_acme_cert_keyfile_full.path }}"
{% for command in step_acme_cert_post_renewal_commands -%}
{{ command }}
{% endfor -%}
{% if step_acme_cert_renewal_reload_services -%}
systemctl try-reload-or-restart {{ step_acme_cert_renewal_reload_services | join(' ') }}
{% endif -%}
2 changes: 1 addition & 1 deletion roles/step_acme_cert/templates/step-renew.service.j2
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Type=simple
Restart=always
RestartSec=1
Environment=STEPPATH={{ step_cli_steppath }}
ExecStart={{ step_cli_executable_absolute.stdout }} ca renew {{ step_acme_cert_certfile_full.path }} {{ step_acme_cert_keyfile_full.path }} --daemon --force{% if step_acme_cert_renewal_when is defined %} --expires-in {{ step_acme_cert_renewal_when }}{% endif %}{% if step_acme_cert_renewal_reload_services %} --exec "systemctl try-reload-or-restart {{ step_acme_cert_renewal_reload_services | join(' ') }}"{% endif %}
ExecStart={{ step_cli_executable_absolute.stdout }} ca renew {{ step_acme_cert_certfile_full.path }} {{ step_acme_cert_keyfile_full.path }} --daemon --force{% if step_acme_cert_renewal_when is defined %} --expires-in {{ step_acme_cert_renewal_when }}{% endif %}{% if step_acme_cert_post_renewal_commands or step_acme_cert_renewal_reload_services %} --exec "{{ step_acme_cert_post_renewal_shell }} {{ step_cli_steppath }}/{{ step_acme_cert_renewal_service }}_post.sh"{% endif %}

[Install]
WantedBy=multi-user.target

0 comments on commit 584128f

Please sign in to comment.