forked from ungleich-public/cdist
Rewrite __letsencrypt_cert type
This commit adds the following features: * Ability to expand existing certificate * Ability to manage object state * Ability to obtain test certificate * Ability to promote test certificate to production * Ability to specify custom certificate name * Ability to specify multiple domains per certificate * Ability to use Certbot in standalone mode * Messaging This commit also introduces the following behavioral changes: * Attempt to install Certbot only when it is not installed already * Installation of the cron job has to be enabled using `--automatic-renewal` parameter **Note:** Object ID is now treated as certificate name and new required parameter `--domain` was added.
This commit is contained in:
parent
543bc8fed9
commit
22d570ae60
14 changed files with 239 additions and 105 deletions
3
cdist/conf/type/__letsencrypt_cert/explorer/certbot-path
Executable file
3
cdist/conf/type/__letsencrypt_cert/explorer/certbot-path
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
command -v certbot 2>/dev/null || true
|
4
cdist/conf/type/__letsencrypt_cert/explorer/certificate-domains
Executable file
4
cdist/conf/type/__letsencrypt_cert/explorer/certificate-domains
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
certbot certificates --cert-name "${__object_id:?}" | grep ' Domains: ' | \
|
||||
cut -d ' ' -f 6- | tr ' ' '\n'
|
7
cdist/conf/type/__letsencrypt_cert/explorer/certificate-exists
Executable file
7
cdist/conf/type/__letsencrypt_cert/explorer/certificate-exists
Executable file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
if certbot certificates | grep -q " Certificate Name: ${__object_id:?}$"; then
|
||||
echo yes
|
||||
else
|
||||
echo no
|
||||
fi
|
8
cdist/conf/type/__letsencrypt_cert/explorer/certificate-is-test
Executable file
8
cdist/conf/type/__letsencrypt_cert/explorer/certificate-is-test
Executable file
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
if certbot certificates --cert-name "${__object_id:?}" | \
|
||||
grep -q 'INVALID: TEST_CERT'; then
|
||||
echo yes
|
||||
else
|
||||
echo no
|
||||
fi
|
|
@ -1,5 +0,0 @@
|
|||
domain=$__object_id
|
||||
|
||||
if [ -f "/etc/letsencrypt/live/$domain/fullchain.pem" ]; then
|
||||
echo yes
|
||||
fi
|
85
cdist/conf/type/__letsencrypt_cert/gencode-remote
Normal file → Executable file
85
cdist/conf/type/__letsencrypt_cert/gencode-remote
Normal file → Executable file
|
@ -1,18 +1,75 @@
|
|||
domain="$__object_id"
|
||||
#!/bin/sh -e
|
||||
|
||||
exists=$(cat "$__object/explorer/exists")
|
||||
webroot="$(cat "$__object/parameter/webroot")"
|
||||
admin_email="$(cat "$__object/parameter/admin-email")"
|
||||
certificate_exists=$(cat "${__object:?}/explorer/certificate-exists")
|
||||
name="${__object_id:?}"
|
||||
state=$(cat "${__object}/parameter/state")
|
||||
|
||||
if [ -n "$exists" ]; then
|
||||
exit 0
|
||||
fi
|
||||
case "${state}" in
|
||||
absent)
|
||||
if [ "${certificate_exists}" = "no" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
if [ ! -d "$webroot" ]; then
|
||||
mkdir -p "$webroot"
|
||||
fi
|
||||
echo "certbot delete --cert-name '${name}' --quiet"
|
||||
|
||||
certbot certonly -n --agree-tos --email '$admin_email' --quiet --webroot \
|
||||
-w '$webroot' -d '$domain'
|
||||
EOF
|
||||
echo remove >> "${__messages_out:?}"
|
||||
;;
|
||||
present)
|
||||
requested_domains="${__object}/parameter/domain"
|
||||
|
||||
staging=no
|
||||
if [ -f "${__object}/parameter/staging" ]; then
|
||||
staging=yes
|
||||
fi
|
||||
|
||||
if [ "${certificate_exists}" = "yes" ]; then
|
||||
existing_domains="${__object}/explorer/certificate-domains"
|
||||
certificate_is_test=$(cat "${__object}/explorer/certificate-is-test")
|
||||
|
||||
sort -uo "${requested_domains}" "${requested_domains}"
|
||||
sort -uo "${existing_domains}" "${existing_domains}"
|
||||
|
||||
if [ -z "$(comm -23 "${requested_domains}" "${existing_domains}")" ] && \
|
||||
[ "${certificate_is_test}" = "${staging}" ]; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
admin_email="$(cat "$__object/parameter/admin-email")"
|
||||
webroot="$(cat "$__object/parameter/webroot")"
|
||||
|
||||
cat <<-EOF
|
||||
certbot certonly \
|
||||
--agree-tos \
|
||||
--cert-name '${name}' \
|
||||
--email '${admin_email}' \
|
||||
--expand \
|
||||
--non-interactive \
|
||||
--quiet \
|
||||
$(if [ "${staging}" = "yes" ]; then
|
||||
echo "--staging"
|
||||
elif [ "${certificate_is_test}" != "${staging}" ]; then
|
||||
echo "--force-renewal"
|
||||
fi) \
|
||||
$(if [ -z "${webroot}" ]; then
|
||||
echo "--standalone"
|
||||
else
|
||||
echo "--webroot --webroot-path '${webroot}'"
|
||||
fi) \
|
||||
$(while read -r domain; do
|
||||
echo "--domain '${domain}' \\"
|
||||
done < "${requested_domains}")
|
||||
EOF
|
||||
|
||||
if [ "${certificate_exists}" = "no" ]; then
|
||||
echo create >> "${__messages_out}"
|
||||
else
|
||||
echo change >> "${__messages_out}"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported state: ${state}" >&2
|
||||
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -3,54 +3,95 @@ cdist-type__letsencrypt_cert(7)
|
|||
|
||||
NAME
|
||||
----
|
||||
cdist-type__letsencrypt_cert - Get an SSL certificate from Let's Encrypt
|
||||
|
||||
cdist-type__letsencrypt_cert - Get an SSL certificate from Let's Encrypt
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Automatically obtain a Let's Encrypt SSL certificate. Uses certbot's webroot
|
||||
method. You must set up your web server to work with webroot.
|
||||
|
||||
Automatically obtain a Let's Encrypt SSL certificate using Certbot.
|
||||
|
||||
REQUIRED PARAMETERS
|
||||
-------------------
|
||||
webroot
|
||||
The path to your webroot, as set up in your webserver config.
|
||||
|
||||
admin-email
|
||||
Where to send Let's Encrypt emails like "certificate needs renewal".
|
||||
Where to send Let's Encrypt emails like "certificate needs renewal".
|
||||
|
||||
REQUIRED MULTIPLE PARAMETERS
|
||||
----------------------------
|
||||
|
||||
domain
|
||||
A domain to be included in the certificate.
|
||||
|
||||
OPTIONAL PARAMETERS
|
||||
-------------------
|
||||
None.
|
||||
|
||||
state
|
||||
'present' or 'absent', defaults to 'present' where:
|
||||
|
||||
present
|
||||
if the certificate does not exist, it will be obtained
|
||||
absent
|
||||
the certificate will be removed
|
||||
|
||||
webroot
|
||||
The path to your webroot, as set up in your webserver config. If this
|
||||
parameter is not present, Certbot will be run in standalone mode.
|
||||
|
||||
OPTIONAL MULTIPLE PARAMETERS
|
||||
----------------------------
|
||||
|
||||
renew-hook
|
||||
Renew hook command directly passed to certbot in cron job.
|
||||
Renew hook command directly passed to Certbot in cron job.
|
||||
|
||||
BOOLEAN PARAMETERS
|
||||
------------------
|
||||
|
||||
automatic-renewal
|
||||
Install a cron job, which attempts to renew certificates daily.
|
||||
|
||||
staging
|
||||
Obtain a test certificate from a staging server.
|
||||
|
||||
MESSAGES
|
||||
--------
|
||||
|
||||
change
|
||||
Certificte was changed.
|
||||
|
||||
create
|
||||
Certificte was created.
|
||||
|
||||
remove
|
||||
Certificte was removed.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
__letsencrypt_cert example.com --admin-email root@example.com --webroot /data/letsencrypt/root
|
||||
|
||||
__letsencrypt_cert example.com --admin-email root@example.com --webroot /data/letsencrypt/root --renew-hook "service nginx reload"
|
||||
__letsencrypt_cert example.com \
|
||||
--admin-email root@example.com \
|
||||
--automatic-renewal \
|
||||
--domain example.com \
|
||||
--domain foo.example.com \
|
||||
--domain bar.example.com \
|
||||
--renew-hook "service nginx reload" \
|
||||
--webroot /data/letsencrypt/root
|
||||
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
|
||||
| Nico Schottelius <nico-cdist--@--schottelius.org>
|
||||
| Kamila Součková <kamila--@--ksp.sk>
|
||||
| Darko Poljak <darko.poljak--@--gmail.com>
|
||||
|
||||
| Ľubomír Kučera <lubomir.kucera.jr at gmail.com>
|
||||
|
||||
COPYING
|
||||
-------
|
||||
Copyright \(C) 2017 Nico Schottelius, Kamila Součková, Darko Poljak. You can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Copyright \(C) 2017-2018 Nico Schottelius, Kamila Součková, Darko Poljak and
|
||||
Ľubomír Kučera. You can redistribute it and/or modify it under the terms of
|
||||
the GNU General Public License as published by the Free Software Foundation,
|
||||
either version 3 of the License, or (at your option) any later version.
|
||||
|
|
152
cdist/conf/type/__letsencrypt_cert/manifest
Normal file → Executable file
152
cdist/conf/type/__letsencrypt_cert/manifest
Normal file → Executable file
|
@ -1,79 +1,93 @@
|
|||
os=$(cat "$__global/explorer/os")
|
||||
os_version=$(cat "$__global/explorer/os_version")
|
||||
#!/bin/sh
|
||||
|
||||
case "$os" in
|
||||
debian)
|
||||
case "$os_version" in
|
||||
8*)
|
||||
__apt_source jessie-backports \
|
||||
--uri http://http.debian.net/debian \
|
||||
--distribution jessie-backports \
|
||||
--component main
|
||||
certbot_fullpath="$(cat "${__object:?}/explorer/certbot-path")"
|
||||
|
||||
require="__apt_source/jessie-backports" __package_apt python-certbot --target-release jessie-backports
|
||||
require="__apt_source/jessie-backports" __package_apt certbot --target-release jessie-backports
|
||||
# Seems to be a missing dependency on debian 8
|
||||
__package python-ndg-httpsclient
|
||||
;;
|
||||
9*)
|
||||
__apt_source stretch-backports \
|
||||
--uri http://http.debian.net/debian \
|
||||
--distribution stretch-backports \
|
||||
--component main
|
||||
if [ -z "${certbot_fullpath}" ]; then
|
||||
os="$(cat "${__global:?}/explorer/os")"
|
||||
os_version="$(cat "${__global}/explorer/os_version")"
|
||||
|
||||
require="__apt_source/stretch-backports" __package_apt python-certbot --target-release stretch-backports
|
||||
require="__apt_source/stretch-backports" __package_apt certbot --target-release stretch-backports
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported OS version: $os_version" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
case "$os" in
|
||||
debian)
|
||||
case "$os_version" in
|
||||
8*)
|
||||
__apt_source jessie-backports \
|
||||
--uri http://http.debian.net/debian \
|
||||
--distribution jessie-backports \
|
||||
--component main
|
||||
|
||||
certbot_fullpath=/usr/bin/certbot
|
||||
;;
|
||||
devuan)
|
||||
case "$os_version" in
|
||||
jessie)
|
||||
__apt_source jessie-backports \
|
||||
--uri http://auto.mirror.devuan.org/merged \
|
||||
--distribution jessie-backports \
|
||||
--component main
|
||||
require="__apt_source/jessie-backports" __package_apt python-certbot \
|
||||
--target-release jessie-backports
|
||||
require="__apt_source/jessie-backports" __package_apt certbot \
|
||||
--target-release jessie-backports
|
||||
# Seems to be a missing dependency on debian 8
|
||||
__package python-ndg-httpsclient
|
||||
;;
|
||||
9*)
|
||||
__apt_source stretch-backports \
|
||||
--uri http://http.debian.net/debian \
|
||||
--distribution stretch-backports \
|
||||
--component main
|
||||
|
||||
require="__apt_source/jessie-backports" __package_apt python-certbot --target-release jessie-backports
|
||||
require="__apt_source/jessie-backports" __package_apt certbot --target-release jessie-backports
|
||||
# Seems to be a missing dependency on debian 8
|
||||
__package python-ndg-httpsclient
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported OS version: $os_version" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
require="__apt_source/stretch-backports" __package_apt python-certbot \
|
||||
--target-release stretch-backports
|
||||
require="__apt_source/stretch-backports" __package_apt certbot \
|
||||
--target-release stretch-backports
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported OS version: $os_version" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
certbot_fullpath=/usr/bin/certbot
|
||||
;;
|
||||
freebsd)
|
||||
__package py27-certbot
|
||||
certbot_fullpath=/usr/bin/certbot
|
||||
;;
|
||||
devuan)
|
||||
case "$os_version" in
|
||||
jessie)
|
||||
__apt_source jessie-backports \
|
||||
--uri http://auto.mirror.devuan.org/merged \
|
||||
--distribution jessie-backports \
|
||||
--component main
|
||||
|
||||
certbot_fullpath=/usr/local/bin/certbot
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported os: $os" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
require="__apt_source/jessie-backports" __package_apt python-certbot \
|
||||
--target-release jessie-backports
|
||||
require="__apt_source/jessie-backports" __package_apt certbot \
|
||||
--target-release jessie-backports
|
||||
# Seems to be a missing dependency on debian 8
|
||||
__package python-ndg-httpsclient
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported OS version: $os_version" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
renew_hook_param="$__object/parameter/renew-hook"
|
||||
renew_hook=""
|
||||
if [ -f "$renew_hook_param" ]; then
|
||||
while read hook; do
|
||||
renew_hook="$renew_hook --renew-hook \"$hook\""
|
||||
done < "$renew_hook_param"
|
||||
certbot_fullpath=/usr/bin/certbot
|
||||
;;
|
||||
freebsd)
|
||||
__package py27-certbot
|
||||
|
||||
certbot_fullpath=/usr/local/bin/certbot
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported os: $os" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
__cron letsencrypt-certbot \
|
||||
--user root \
|
||||
--command "$certbot_fullpath renew -q $renew_hook" \
|
||||
--hour 0 \
|
||||
--minute 47
|
||||
if [ -f "${__object}/parameter/automatic-renewal" ]; then
|
||||
renew_hook_param="${__object}/parameter/renew-hook"
|
||||
renew_hook=""
|
||||
if [ -f "${renew_hook_param}" ]; then
|
||||
while read hook; do
|
||||
renew_hook="${renew_hook} --renew-hook \"${hook}\""
|
||||
done < "${renew_hook_param}"
|
||||
fi
|
||||
|
||||
__cron letsencrypt-certbot \
|
||||
--user root \
|
||||
--command "${certbot_fullpath} renew -q ${renew_hook}" \
|
||||
--hour 0 \
|
||||
--minute 47
|
||||
fi
|
||||
|
|
2
cdist/conf/type/__letsencrypt_cert/parameter/boolean
Normal file
2
cdist/conf/type/__letsencrypt_cert/parameter/boolean
Normal file
|
@ -0,0 +1,2 @@
|
|||
automatic-renewal
|
||||
staging
|
|
@ -0,0 +1 @@
|
|||
present
|
2
cdist/conf/type/__letsencrypt_cert/parameter/optional
Normal file
2
cdist/conf/type/__letsencrypt_cert/parameter/optional
Normal file
|
@ -0,0 +1,2 @@
|
|||
state
|
||||
webroot
|
|
@ -1,2 +1 @@
|
|||
admin-email
|
||||
webroot
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
domain
|
Loading…
Reference in a new issue