From 379ee5dd666609d7933ee93a532f5ef451573d5c Mon Sep 17 00:00:00 2001 From: David Kilias Date: Wed, 10 Feb 2021 23:12:12 +0100 Subject: [PATCH 01/18] add hook template --- roles/dehydrated-domains/templates/hook.sh.j2 | 230 ++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 roles/dehydrated-domains/templates/hook.sh.j2 diff --git a/roles/dehydrated-domains/templates/hook.sh.j2 b/roles/dehydrated-domains/templates/hook.sh.j2 new file mode 100644 index 0000000..28e7fee --- /dev/null +++ b/roles/dehydrated-domains/templates/hook.sh.j2 @@ -0,0 +1,230 @@ +#!/usr/bin/env bash + +deploy_challenge() { + local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}" + + # This hook is called once for every domain that needs to be + # validated, including any alternative names you may have listed. + # + # Parameters: + # - DOMAIN + # The domain name (CN or subject alternative name) being + # validated. + # - TOKEN_FILENAME + # The name of the file containing the token to be served for HTTP + # validation. Should be served by your web server as + # /.well-known/acme-challenge/${TOKEN_FILENAME}. + # - TOKEN_VALUE + # The token value that needs to be served for validation. For DNS + # validation, this is what you want to put in the _acme-challenge + # TXT record. For HTTP validation it is the value that is expected + # be found in the $TOKEN_FILENAME file. + + # Simple example: Use nsupdate with local named + # printf 'server 127.0.0.1\nupdate add _acme-challenge.%s 300 IN TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key + {{ dehydrated_deploy_challenge_hook }} +} + +clean_challenge() { + local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}" + + # This hook is called after attempting to validate each domain, + # whether or not validation was successful. Here you can delete + # files or DNS records that are no longer needed. + # + # The parameters are the same as for deploy_challenge. + + # Simple example: Use nsupdate with local named + # printf 'server 127.0.0.1\nupdate delete _acme-challenge.%s TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key + {{ dehydrated_clean_challenge_hook }} +} + +sync_cert() { + local KEYFILE="${1}" CERTFILE="${2}" FULLCHAINFILE="${3}" CHAINFILE="${4}" REQUESTFILE="${5}" + + # This hook is called after the certificates have been created but before + # they are symlinked. This allows you to sync the files to disk to prevent + # creating a symlink to empty files on unexpected system crashes. + # + # This hook is not intended to be used for further processing of certificate + # files, see deploy_cert for that. + # + # Parameters: + # - KEYFILE + # The path of the file containing the private key. + # - CERTFILE + # The path of the file containing the signed certificate. + # - FULLCHAINFILE + # The path of the file containing the full certificate chain. + # - CHAINFILE + # The path of the file containing the intermediate certificate(s). + # - REQUESTFILE + # The path of the file containing the certificate signing request. + + # Simple example: sync the files before symlinking them + # sync "${KEYFILE}" "${CERTFILE}" "${FULLCHAINFILE}" "${CHAINFILE}" "${REQUESTFILE}" + {{ dehydrated_sync_cert_hook }} +} + +deploy_cert() { + local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="${6}" + + # This hook is called once for each certificate that has been + # produced. Here you might, for instance, copy your new certificates + # to service-specific locations and reload the service. + # + # Parameters: + # - DOMAIN + # The primary domain name, i.e. the certificate common + # name (CN). + # - KEYFILE + # The path of the file containing the private key. + # - CERTFILE + # The path of the file containing the signed certificate. + # - FULLCHAINFILE + # The path of the file containing the full certificate chain. + # - CHAINFILE + # The path of the file containing the intermediate certificate(s). + # - TIMESTAMP + # Timestamp when the specified certificate was created. + + # Simple example: Copy file to nginx config + # cp "${KEYFILE}" "${FULLCHAINFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl + # systemctl reload nginx + {{ dehydrated_deploy_cert_hook }} +} + +deploy_ocsp() { + local DOMAIN="${1}" OCSPFILE="${2}" TIMESTAMP="${3}" + + # This hook is called once for each updated ocsp stapling file that has + # been produced. Here you might, for instance, copy your new ocsp stapling + # files to service-specific locations and reload the service. + # + # Parameters: + # - DOMAIN + # The primary domain name, i.e. the certificate common + # name (CN). + # - OCSPFILE + # The path of the ocsp stapling file + # - TIMESTAMP + # Timestamp when the specified ocsp stapling file was created. + + # Simple example: Copy file to nginx config + # cp "${OCSPFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl + # systemctl reload nginx + {{ dehydrated_deploy_ocsp_hook }} +} + + +unchanged_cert() { + local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" + + # This hook is called once for each certificate that is still + # valid and therefore wasn't reissued. + # + # Parameters: + # - DOMAIN + # The primary domain name, i.e. the certificate common + # name (CN). + # - KEYFILE + # The path of the file containing the private key. + # - CERTFILE + # The path of the file containing the signed certificate. + # - FULLCHAINFILE + # The path of the file containing the full certificate chain. + # - CHAINFILE + # The path of the file containing the intermediate certificate(s). + {{ dehydrated_unchanged_cert_hook }} +} + +invalid_challenge() { + local DOMAIN="${1}" RESPONSE="${2}" + + # This hook is called if the challenge response has failed, so domain + # owners can be aware and act accordingly. + # + # Parameters: + # - DOMAIN + # The primary domain name, i.e. the certificate common + # name (CN). + # - RESPONSE + # The response that the verification server returned + + # Simple example: Send mail to root + # printf "Subject: Validation of ${DOMAIN} failed!\n\nOh noez!" | sendmail root + {{ dehydrated_invalid_challenge_hook }} +} + +request_failure() { + local STATUSCODE="${1}" REASON="${2}" REQTYPE="${3}" HEADERS="${4}" + + # This hook is called when an HTTP request fails (e.g., when the ACME + # server is busy, returns an error, etc). It will be called upon any + # response code that does not start with '2'. Useful to alert admins + # about problems with requests. + # + # Parameters: + # - STATUSCODE + # The HTML status code that originated the error. + # - REASON + # The specified reason for the error. + # - REQTYPE + # The kind of request that was made (GET, POST...) + # - HEADERS + # HTTP headers returned by the CA + + # Simple example: Send mail to root + # printf "Subject: HTTP request failed failed!\n\nA http request failed with status ${STATUSCODE}!" | sendmail root + {{ dehydrated_request_failure_hook }} +} + +generate_csr() { + local DOMAIN="${1}" CERTDIR="${2}" ALTNAMES="${3}" + + # This hook is called before any certificate signing operation takes place. + # It can be used to generate or fetch a certificate signing request with external + # tools. + # The output should be just the certificate signing request formatted as PEM. + # + # Parameters: + # - DOMAIN + # The primary domain as specified in domains.txt. This does not need to + # match with the domains in the CSR, it's basically just the directory name. + # - CERTDIR + # Certificate output directory for this particular certificate. Can be used + # for storing additional files. + # - ALTNAMES + # All domain names for the current certificate as specified in domains.txt. + # Again, this doesn't need to match with the CSR, it's just there for convenience. + + # Simple example: Look for pre-generated CSRs + # if [ -e "${CERTDIR}/pre-generated.csr" ]; then + # cat "${CERTDIR}/pre-generated.csr" + # fi + {{ dehydrated_startup_hook }} + +} + +startup_hook() { + # This hook is called before the cron command to do some initial tasks + # (e.g. starting a webserver). + {{ dehydrated_startup_hook }} + : +} + +exit_hook() { + local ERROR="${1:-}" + # This hook is called at the end of the cron command and can be used to + # do some final (cleanup or other) tasks. + # + # Parameters: + # - ERROR + # Contains error message if dehydrated exits with error + {{ dehydrated_exit_hook }} +} + +HANDLER="$1"; shift +if [[ "${HANDLER}" =~ ^(deploy_challenge|clean_challenge|sync_cert|deploy_cert|deploy_ocsp|unchanged_cert|invalid_challenge|request_failure|generate_csr|startup_hook|exit_hook)$ ]]; then + "$HANDLER" "$@" +fi \ No newline at end of file From 44f03354d26bc98be824f665926dc9bfb25efac3 Mon Sep 17 00:00:00 2001 From: David Kilias Date: Wed, 10 Feb 2021 23:27:06 +0100 Subject: [PATCH 02/18] add hook script template --- roles/dehydrated-domains/templates/hook.sh.j2 | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/roles/dehydrated-domains/templates/hook.sh.j2 b/roles/dehydrated-domains/templates/hook.sh.j2 index 28e7fee..5baa6a7 100644 --- a/roles/dehydrated-domains/templates/hook.sh.j2 +++ b/roles/dehydrated-domains/templates/hook.sh.j2 @@ -22,7 +22,7 @@ deploy_challenge() { # Simple example: Use nsupdate with local named # printf 'server 127.0.0.1\nupdate add _acme-challenge.%s 300 IN TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key - {{ dehydrated_deploy_challenge_hook }} + {{ item.deploy_challenge_hook }} } clean_challenge() { @@ -36,7 +36,7 @@ clean_challenge() { # Simple example: Use nsupdate with local named # printf 'server 127.0.0.1\nupdate delete _acme-challenge.%s TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key - {{ dehydrated_clean_challenge_hook }} + {{ item.clean_challenge_hook }} } sync_cert() { @@ -63,7 +63,7 @@ sync_cert() { # Simple example: sync the files before symlinking them # sync "${KEYFILE}" "${CERTFILE}" "${FULLCHAINFILE}" "${CHAINFILE}" "${REQUESTFILE}" - {{ dehydrated_sync_cert_hook }} + {{ item.sync_cert_hook }} } deploy_cert() { @@ -91,7 +91,7 @@ deploy_cert() { # Simple example: Copy file to nginx config # cp "${KEYFILE}" "${FULLCHAINFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl # systemctl reload nginx - {{ dehydrated_deploy_cert_hook }} + {{ item.deploy_cert_hook }} } deploy_ocsp() { @@ -113,7 +113,7 @@ deploy_ocsp() { # Simple example: Copy file to nginx config # cp "${OCSPFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl # systemctl reload nginx - {{ dehydrated_deploy_ocsp_hook }} + {{ item.deploy_ocsp_hook }} } @@ -135,7 +135,7 @@ unchanged_cert() { # The path of the file containing the full certificate chain. # - CHAINFILE # The path of the file containing the intermediate certificate(s). - {{ dehydrated_unchanged_cert_hook }} + {{ item.unchanged_cert_hook }} } invalid_challenge() { @@ -153,7 +153,7 @@ invalid_challenge() { # Simple example: Send mail to root # printf "Subject: Validation of ${DOMAIN} failed!\n\nOh noez!" | sendmail root - {{ dehydrated_invalid_challenge_hook }} + {{ item.invalid_challenge_hook }} } request_failure() { @@ -176,7 +176,7 @@ request_failure() { # Simple example: Send mail to root # printf "Subject: HTTP request failed failed!\n\nA http request failed with status ${STATUSCODE}!" | sendmail root - {{ dehydrated_request_failure_hook }} + {{ item.request_failure_hook }} } generate_csr() { @@ -202,14 +202,14 @@ generate_csr() { # if [ -e "${CERTDIR}/pre-generated.csr" ]; then # cat "${CERTDIR}/pre-generated.csr" # fi - {{ dehydrated_startup_hook }} + {{ item.startup_hook }} } startup_hook() { # This hook is called before the cron command to do some initial tasks # (e.g. starting a webserver). - {{ dehydrated_startup_hook }} + {{ item.startup_hook }} : } @@ -221,7 +221,7 @@ exit_hook() { # Parameters: # - ERROR # Contains error message if dehydrated exits with error - {{ dehydrated_exit_hook }} + {{ item.exit_hook }} } HANDLER="$1"; shift From 695fcc2d919bcbbd3820ad594534a0c23891d1f3 Mon Sep 17 00:00:00 2001 From: David Kilias Date: Wed, 10 Feb 2021 23:27:17 +0100 Subject: [PATCH 03/18] add tasks for domains role --- roles/dehydrated-domains/tasks/main.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 roles/dehydrated-domains/tasks/main.yml diff --git a/roles/dehydrated-domains/tasks/main.yml b/roles/dehydrated-domains/tasks/main.yml new file mode 100644 index 0000000..10ff537 --- /dev/null +++ b/roles/dehydrated-domains/tasks/main.yml @@ -0,0 +1,19 @@ +--- +- name: Ensure domain directories are present. + file: + name: "{{ dehydrated_certs_dir }}/{{ item.name }}" + state: directory + with_items: dehydrated_domains + +- name: Render hook script templates. + template: + src: hook.sh.j2 + dest: "{{ dehydrated_certs_dir }}/{{ item.name }}/hook.sh" + with_items: dehydrated_domains + +- name: Ensure Domains are in domains.txt + lineinfile: + path: "{{ dehydrated_config_dir }}/domains.txt" + line: "{{ item.name }}" + with_items: dehydrated_domains + notify: dehydrated cron \ No newline at end of file From fcfaf91928696569bf80a816dfae8e942980b4e8 Mon Sep 17 00:00:00 2001 From: David Kilias Date: Thu, 11 Feb 2021 19:26:10 +0100 Subject: [PATCH 04/18] add source to document the source of hook.sh.j2 --- roles/dehydrated-domains/templates/hook.sh.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/roles/dehydrated-domains/templates/hook.sh.j2 b/roles/dehydrated-domains/templates/hook.sh.j2 index 5baa6a7..69b92d6 100644 --- a/roles/dehydrated-domains/templates/hook.sh.j2 +++ b/roles/dehydrated-domains/templates/hook.sh.j2 @@ -1,5 +1,8 @@ #!/usr/bin/env bash +# This Script is copied from https://github.com/dehydrated-io/dehydrated/blob/v0.7.0/docs/examples/hook.sh +# and modified to accept per domain hooks as item.*_hook when using ansible.template + deploy_challenge() { local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}" From ef6adba1a6e8b5cb6829a362e16500747b9d2c7a Mon Sep 17 00:00:00 2001 From: David Kilias Date: Thu, 11 Feb 2021 23:20:48 +0100 Subject: [PATCH 05/18] add default values "" for hook scripts --- roles/dehydrated-domains/templates/hook.sh.j2 | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/roles/dehydrated-domains/templates/hook.sh.j2 b/roles/dehydrated-domains/templates/hook.sh.j2 index 69b92d6..ebd8bbd 100644 --- a/roles/dehydrated-domains/templates/hook.sh.j2 +++ b/roles/dehydrated-domains/templates/hook.sh.j2 @@ -25,7 +25,7 @@ deploy_challenge() { # Simple example: Use nsupdate with local named # printf 'server 127.0.0.1\nupdate add _acme-challenge.%s 300 IN TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key - {{ item.deploy_challenge_hook }} + {{ item.deploy_challenge_hook|default("") }} } clean_challenge() { @@ -39,7 +39,7 @@ clean_challenge() { # Simple example: Use nsupdate with local named # printf 'server 127.0.0.1\nupdate delete _acme-challenge.%s TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key - {{ item.clean_challenge_hook }} + {{ item.clean_challenge_hook|default("") }} } sync_cert() { @@ -66,7 +66,7 @@ sync_cert() { # Simple example: sync the files before symlinking them # sync "${KEYFILE}" "${CERTFILE}" "${FULLCHAINFILE}" "${CHAINFILE}" "${REQUESTFILE}" - {{ item.sync_cert_hook }} + {{ item.sync_cert_hook|default("") }} } deploy_cert() { @@ -94,7 +94,7 @@ deploy_cert() { # Simple example: Copy file to nginx config # cp "${KEYFILE}" "${FULLCHAINFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl # systemctl reload nginx - {{ item.deploy_cert_hook }} + {{ item.deploy_cert_hook|default("") }} } deploy_ocsp() { @@ -116,7 +116,7 @@ deploy_ocsp() { # Simple example: Copy file to nginx config # cp "${OCSPFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl # systemctl reload nginx - {{ item.deploy_ocsp_hook }} + {{ item.deploy_ocsp_hook|default("") }} } @@ -138,7 +138,7 @@ unchanged_cert() { # The path of the file containing the full certificate chain. # - CHAINFILE # The path of the file containing the intermediate certificate(s). - {{ item.unchanged_cert_hook }} + {{ item.unchanged_cert_hook|default("") }} } invalid_challenge() { @@ -156,7 +156,7 @@ invalid_challenge() { # Simple example: Send mail to root # printf "Subject: Validation of ${DOMAIN} failed!\n\nOh noez!" | sendmail root - {{ item.invalid_challenge_hook }} + {{ item.invalid_challenge_hook|default("") }} } request_failure() { @@ -179,7 +179,7 @@ request_failure() { # Simple example: Send mail to root # printf "Subject: HTTP request failed failed!\n\nA http request failed with status ${STATUSCODE}!" | sendmail root - {{ item.request_failure_hook }} + {{ item.request_failure_hook|default("") }} } generate_csr() { @@ -205,14 +205,14 @@ generate_csr() { # if [ -e "${CERTDIR}/pre-generated.csr" ]; then # cat "${CERTDIR}/pre-generated.csr" # fi - {{ item.startup_hook }} + {{ item.startup_hook|default("") }} } startup_hook() { # This hook is called before the cron command to do some initial tasks # (e.g. starting a webserver). - {{ item.startup_hook }} + {{ item.startup_hook|default("") }} : } @@ -224,7 +224,7 @@ exit_hook() { # Parameters: # - ERROR # Contains error message if dehydrated exits with error - {{ item.exit_hook }} + {{ item.exit_hook|default("") }} } HANDLER="$1"; shift From f7a1fe81439b9ca3eb7906007e9d56911982f305 Mon Sep 17 00:00:00 2001 From: David Kilias Date: Thu, 11 Feb 2021 23:25:37 +0100 Subject: [PATCH 06/18] add some documentation in README.md --- roles/dehydrated-domains/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 roles/dehydrated-domains/README.md diff --git a/roles/dehydrated-domains/README.md b/roles/dehydrated-domains/README.md new file mode 100644 index 0000000..3da2197 --- /dev/null +++ b/roles/dehydrated-domains/README.md @@ -0,0 +1,17 @@ +# Dehydrated Domains + +Ansible role to configure domains for use with dehydrated + +## Usage + +```yaml +vars: + dehydrated_domains: + name: example.com + deploy_challenge_hook: printf 'server 127.0.0.1\nupdate add _acme-challenge.%s 300 IN TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key + clean_challenge_hook: printf 'server 127.0.0.1\nupdate delete _acme-challenge.%s TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key + +roles: + - role: dehydrated-domains + +``` \ No newline at end of file From 4d2287d525b3246788f58feea9f08e0cc028e1f9 Mon Sep 17 00:00:00 2001 From: David Kilias Date: Sat, 13 Feb 2021 17:38:44 +0100 Subject: [PATCH 07/18] =?UTF-8?q?optional=20sind=20auch=20alternate=5Fname?= =?UTF-8?q?s=20f=C3=BCr=20die=20domains=20m=C3=B6glich?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roles/dehydrated-domains/README.md | 1 + roles/dehydrated-domains/tasks/main.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/roles/dehydrated-domains/README.md b/roles/dehydrated-domains/README.md index 3da2197..0d3f9bf 100644 --- a/roles/dehydrated-domains/README.md +++ b/roles/dehydrated-domains/README.md @@ -8,6 +8,7 @@ Ansible role to configure domains for use with dehydrated vars: dehydrated_domains: name: example.com + alternate_names: "www.example.com web.example.com" deploy_challenge_hook: printf 'server 127.0.0.1\nupdate add _acme-challenge.%s 300 IN TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key clean_challenge_hook: printf 'server 127.0.0.1\nupdate delete _acme-challenge.%s TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key diff --git a/roles/dehydrated-domains/tasks/main.yml b/roles/dehydrated-domains/tasks/main.yml index 10ff537..e4243cd 100644 --- a/roles/dehydrated-domains/tasks/main.yml +++ b/roles/dehydrated-domains/tasks/main.yml @@ -14,6 +14,6 @@ - name: Ensure Domains are in domains.txt lineinfile: path: "{{ dehydrated_config_dir }}/domains.txt" - line: "{{ item.name }}" + line: "{{ item.name }} {{ item.alternate_names|default(omit) }}" with_items: dehydrated_domains notify: dehydrated cron \ No newline at end of file From 9ff8f0ad6c255f9063730daf31fe98e9f52fc9d5 Mon Sep 17 00:00:00 2001 From: David Kilias Date: Sat, 13 Feb 2021 18:00:33 +0100 Subject: [PATCH 08/18] =?UTF-8?q?einr=C3=BCckungen=20repariert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roles/dehydrated-domains/README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/roles/dehydrated-domains/README.md b/roles/dehydrated-domains/README.md index 0d3f9bf..f368286 100644 --- a/roles/dehydrated-domains/README.md +++ b/roles/dehydrated-domains/README.md @@ -6,13 +6,12 @@ Ansible role to configure domains for use with dehydrated ```yaml vars: - dehydrated_domains: - name: example.com - alternate_names: "www.example.com web.example.com" - deploy_challenge_hook: printf 'server 127.0.0.1\nupdate add _acme-challenge.%s 300 IN TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key - clean_challenge_hook: printf 'server 127.0.0.1\nupdate delete _acme-challenge.%s TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key + dehydrated_domains: + - name: example.com + alternate_names: "www.example.com web.example.com" + deploy_challenge_hook: printf 'server 127.0.0.1\nupdate add _acme-challenge.%s 300 IN TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key + clean_challenge_hook: printf 'server 127.0.0.1\nupdate delete _acme-challenge.%s TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key roles: - - role: dehydrated-domains - + - role: dehydrated-domains ``` \ No newline at end of file From cbe0368ac18dd4c0c7f01e2004c6232f325b4f8e Mon Sep 17 00:00:00 2001 From: David Kilias Date: Sun, 14 Feb 2021 17:41:27 +0100 Subject: [PATCH 09/18] alternate_names als Liste --- roles/dehydrated-domains/README.md | 4 +++- roles/dehydrated-domains/tasks/main.yml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/roles/dehydrated-domains/README.md b/roles/dehydrated-domains/README.md index f368286..44f897d 100644 --- a/roles/dehydrated-domains/README.md +++ b/roles/dehydrated-domains/README.md @@ -8,7 +8,9 @@ Ansible role to configure domains for use with dehydrated vars: dehydrated_domains: - name: example.com - alternate_names: "www.example.com web.example.com" + alternate_names: + - www.example.com + - web.example.com deploy_challenge_hook: printf 'server 127.0.0.1\nupdate add _acme-challenge.%s 300 IN TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key clean_challenge_hook: printf 'server 127.0.0.1\nupdate delete _acme-challenge.%s TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key diff --git a/roles/dehydrated-domains/tasks/main.yml b/roles/dehydrated-domains/tasks/main.yml index e4243cd..d082e39 100644 --- a/roles/dehydrated-domains/tasks/main.yml +++ b/roles/dehydrated-domains/tasks/main.yml @@ -14,6 +14,6 @@ - name: Ensure Domains are in domains.txt lineinfile: path: "{{ dehydrated_config_dir }}/domains.txt" - line: "{{ item.name }} {{ item.alternate_names|default(omit) }}" + line: "{{ item.name }}{% for an in item.alternate_names %} {{ an|default(omit) }}{% endfor %}" with_items: dehydrated_domains notify: dehydrated cron \ No newline at end of file From fbd1d7a2acd6bd9a4553bd4c4dfb85b824378a28 Mon Sep 17 00:00:00 2001 From: David Kilias Date: Mon, 15 Feb 2021 18:06:35 +0100 Subject: [PATCH 10/18] =?UTF-8?q?jetzt=20gibts=20ein=20flag=20f=C3=BCr=20f?= =?UTF-8?q?orced=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roles/dehydrated-domains/README.md | 1 + roles/dehydrated/handlers/main.yml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/roles/dehydrated-domains/README.md b/roles/dehydrated-domains/README.md index 44f897d..6f2f544 100644 --- a/roles/dehydrated-domains/README.md +++ b/roles/dehydrated-domains/README.md @@ -6,6 +6,7 @@ Ansible role to configure domains for use with dehydrated ```yaml vars: + dehydrated_force_update: True dehydrated_domains: - name: example.com alternate_names: diff --git a/roles/dehydrated/handlers/main.yml b/roles/dehydrated/handlers/main.yml index 4498b79..9552e98 100644 --- a/roles/dehydrated/handlers/main.yml +++ b/roles/dehydrated/handlers/main.yml @@ -3,4 +3,5 @@ command: "{{ dehydrated_binary }} --register --accept-terms" - name: dehydrated cron - command: "{{ dehydrated_binary }} --cron" \ No newline at end of file + command: "{{ dehydrated_binary }} --cron" + when: dehydrated_force_update|default(False)|bool \ No newline at end of file From 4ff88a0af31ce378b97f79d6a4e827337adfbcf2 Mon Sep 17 00:00:00 2001 From: David Kilias Date: Mon, 15 Feb 2021 18:18:36 +0100 Subject: [PATCH 11/18] =?UTF-8?q?cron=20job=20f=C3=BCr=20dehydrated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roles/dehydrated/defaults/main.yml | 3 +++ roles/dehydrated/tasks/main.yml | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/roles/dehydrated/defaults/main.yml b/roles/dehydrated/defaults/main.yml index 74a8e83..d3e3fb7 100644 --- a/roles/dehydrated/defaults/main.yml +++ b/roles/dehydrated/defaults/main.yml @@ -6,3 +6,6 @@ dehydrated_binary: "/usr/local/bin/dehydrated" dehydrated_config_dir: "/usr/local/etc/dehydrated" dehydrated_certs_dir: "{{ dehydrated_config_dir }}/certs" dehydrated_wellknown_dir: "{{ dehydrated_config_dir }}/challenge" + +dehydrated_cron_minute: 0 +dehydrated_cron_hour: 3 diff --git a/roles/dehydrated/tasks/main.yml b/roles/dehydrated/tasks/main.yml index 8614ded..77456f8 100644 --- a/roles/dehydrated/tasks/main.yml +++ b/roles/dehydrated/tasks/main.yml @@ -50,4 +50,10 @@ src: config.j2 dest: "{{ dehydrated_config_dir }}/config" notify: dehydrated register - \ No newline at end of file + +- name: Install dehydrated cron job. + cron: + name: renew dehydrated certs + hour: dehydrated_cron_hour + minute: dehydrated_cron_minute + job: "{{ dehydrated_binary }} -c -g" \ No newline at end of file From 1703e7226e6fda60c1146df1ae6ef079b5db4e4a Mon Sep 17 00:00:00 2001 From: David Kilias Date: Tue, 16 Feb 2021 20:01:11 +0100 Subject: [PATCH 12/18] add month to dehydrated_cron config --- roles/dehydrated/defaults/main.yml | 5 +++-- roles/dehydrated/tasks/main.yml | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/roles/dehydrated/defaults/main.yml b/roles/dehydrated/defaults/main.yml index d3e3fb7..67a49e5 100644 --- a/roles/dehydrated/defaults/main.yml +++ b/roles/dehydrated/defaults/main.yml @@ -7,5 +7,6 @@ dehydrated_config_dir: "/usr/local/etc/dehydrated" dehydrated_certs_dir: "{{ dehydrated_config_dir }}/certs" dehydrated_wellknown_dir: "{{ dehydrated_config_dir }}/challenge" -dehydrated_cron_minute: 0 -dehydrated_cron_hour: 3 +dehydrated_cron_minute: "0" +dehydrated_cron_hour: "3" +dehydrated_cron_day: "*/5" diff --git a/roles/dehydrated/tasks/main.yml b/roles/dehydrated/tasks/main.yml index 77456f8..4f0d395 100644 --- a/roles/dehydrated/tasks/main.yml +++ b/roles/dehydrated/tasks/main.yml @@ -56,4 +56,5 @@ name: renew dehydrated certs hour: dehydrated_cron_hour minute: dehydrated_cron_minute + day: dehydrated_cron_day job: "{{ dehydrated_binary }} -c -g" \ No newline at end of file From eb6f5a815d652f21f6d4a38a045da581d7010373 Mon Sep 17 00:00:00 2001 From: David Kilias Date: Tue, 23 Feb 2021 18:39:18 +0100 Subject: [PATCH 13/18] pebkac... variablen sollte man auch als variablen benutzen --- roles/dehydrated/tasks/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/dehydrated/tasks/main.yml b/roles/dehydrated/tasks/main.yml index 4f0d395..6720424 100644 --- a/roles/dehydrated/tasks/main.yml +++ b/roles/dehydrated/tasks/main.yml @@ -54,7 +54,7 @@ - name: Install dehydrated cron job. cron: name: renew dehydrated certs - hour: dehydrated_cron_hour - minute: dehydrated_cron_minute - day: dehydrated_cron_day + hour: "{{ dehydrated_cron_hour }}" + minute: "{{ dehydrated_cron_minute }}" + day: "{{ dehydrated_cron_day }}" job: "{{ dehydrated_binary }} -c -g" \ No newline at end of file From 5d8e8f9ded653c3690532e06c3b2b096089daa43 Mon Sep 17 00:00:00 2001 From: David Kilias Date: Tue, 23 Feb 2021 20:54:32 +0100 Subject: [PATCH 14/18] separate out crin instead of domains --- roles/dehydrated-cron/defaults/main.yml | 4 ++ .../meta/main.yml | 0 roles/dehydrated-cron/tasks/main.yml | 8 +++ .../README.md | 2 +- roles/dehydrated/defaults/main.yml | 4 -- .../main.yml => dehydrated/tasks/domains.yml} | 0 roles/dehydrated/tasks/install.yml | 52 ++++++++++++++++ roles/dehydrated/tasks/main.yml | 61 +------------------ .../templates/hook.sh.j2 | 0 9 files changed, 67 insertions(+), 64 deletions(-) create mode 100644 roles/dehydrated-cron/defaults/main.yml rename roles/{dehydrated-domains => dehydrated-cron}/meta/main.yml (100%) create mode 100644 roles/dehydrated-cron/tasks/main.yml rename roles/{dehydrated-domains => dehydrated}/README.md (96%) rename roles/{dehydrated-domains/tasks/main.yml => dehydrated/tasks/domains.yml} (100%) create mode 100644 roles/dehydrated/tasks/install.yml rename roles/{dehydrated-domains => dehydrated}/templates/hook.sh.j2 (100%) diff --git a/roles/dehydrated-cron/defaults/main.yml b/roles/dehydrated-cron/defaults/main.yml new file mode 100644 index 0000000..275abdb --- /dev/null +++ b/roles/dehydrated-cron/defaults/main.yml @@ -0,0 +1,4 @@ +--- +dehydrated_cron_minute: "0" +dehydrated_cron_hour: "3" +dehydrated_cron_day: "*/5" diff --git a/roles/dehydrated-domains/meta/main.yml b/roles/dehydrated-cron/meta/main.yml similarity index 100% rename from roles/dehydrated-domains/meta/main.yml rename to roles/dehydrated-cron/meta/main.yml diff --git a/roles/dehydrated-cron/tasks/main.yml b/roles/dehydrated-cron/tasks/main.yml new file mode 100644 index 0000000..13a22bf --- /dev/null +++ b/roles/dehydrated-cron/tasks/main.yml @@ -0,0 +1,8 @@ +--- +- name: Install dehydrated cron job. + cron: + name: renew dehydrated certs + hour: "{{ dehydrated_cron_hour }}" + minute: "{{ dehydrated_cron_minute }}" + day: "{{ dehydrated_cron_day }}" + job: "{{ dehydrated_binary }} -c -g" \ No newline at end of file diff --git a/roles/dehydrated-domains/README.md b/roles/dehydrated/README.md similarity index 96% rename from roles/dehydrated-domains/README.md rename to roles/dehydrated/README.md index 6f2f544..816a898 100644 --- a/roles/dehydrated-domains/README.md +++ b/roles/dehydrated/README.md @@ -1,4 +1,4 @@ -# Dehydrated Domains +# Dehydrated Ansible role to configure domains for use with dehydrated diff --git a/roles/dehydrated/defaults/main.yml b/roles/dehydrated/defaults/main.yml index 67a49e5..74a8e83 100644 --- a/roles/dehydrated/defaults/main.yml +++ b/roles/dehydrated/defaults/main.yml @@ -6,7 +6,3 @@ dehydrated_binary: "/usr/local/bin/dehydrated" dehydrated_config_dir: "/usr/local/etc/dehydrated" dehydrated_certs_dir: "{{ dehydrated_config_dir }}/certs" dehydrated_wellknown_dir: "{{ dehydrated_config_dir }}/challenge" - -dehydrated_cron_minute: "0" -dehydrated_cron_hour: "3" -dehydrated_cron_day: "*/5" diff --git a/roles/dehydrated-domains/tasks/main.yml b/roles/dehydrated/tasks/domains.yml similarity index 100% rename from roles/dehydrated-domains/tasks/main.yml rename to roles/dehydrated/tasks/domains.yml diff --git a/roles/dehydrated/tasks/install.yml b/roles/dehydrated/tasks/install.yml new file mode 100644 index 0000000..b1e2065 --- /dev/null +++ b/roles/dehydrated/tasks/install.yml @@ -0,0 +1,52 @@ +--- +- name: Gather package facts. + package_facts: + manager: "auto" + +- name: Ensure git and curl are installed. + package: + name: + - git + - curl + state: present + +- name: Clone dehydrated repo. + git: + repo: 'https://github.com/dehydrated-io/dehydrated.git' + dest: "{{ dehydrated_location }}" + version: "{{ dehydrated_version }}" + +- name: Ensure dehydrated symlink is present. + file: + src: "{{ dehydrated_location }}/dehydrated" + dest: "{{ dehydrated_binary }}" + state: link + +- name: Ensure config directory is present. + file: + path: "{{ dehydrated_config_dir }}" + state: directory + mode: "0711" + +- name: Ensure wellknown directory is present. + file: + path: "{{ dehydrated_wellknown_dir }}" + state: directory + mode: "0755" + +- name: Ensure certs directory is present. + file: + path: "{{ dehydrated_certs_dir }}" + state: directory + mode: "0700" + +- name: Ensure domains.txt is present. + file: + path: "{{ dehydrated_config_dir }}/domains.txt" + state: touch + +- name: Ensure config is present. + template: + src: config.j2 + dest: "{{ dehydrated_config_dir }}/config" + notify: dehydrated register \ No newline at end of file diff --git a/roles/dehydrated/tasks/main.yml b/roles/dehydrated/tasks/main.yml index 6720424..90c9742 100644 --- a/roles/dehydrated/tasks/main.yml +++ b/roles/dehydrated/tasks/main.yml @@ -1,60 +1,3 @@ --- -- name: Gather package facts. - package_facts: - manager: "auto" - -- name: Ensure git and curl are installed. - package: - name: - - git - - curl - state: present - -- name: Clone dehydrated repo. - git: - repo: 'https://github.com/dehydrated-io/dehydrated.git' - dest: "{{ dehydrated_location }}" - version: "{{ dehydrated_version }}" - -- name: Ensure dehydrated symlink is present. - file: - src: "{{ dehydrated_location }}/dehydrated" - dest: "{{ dehydrated_binary }}" - state: link - -- name: Ensure config directory is present. - file: - path: "{{ dehydrated_config_dir }}" - state: directory - mode: "0711" - -- name: Ensure wellknown directory is present. - file: - path: "{{ dehydrated_wellknown_dir }}" - state: directory - mode: "0755" - -- name: Ensure certs directory is present. - file: - path: "{{ dehydrated_certs_dir }}" - state: directory - mode: "0700" - -- name: Ensure domains.txt is present. - file: - path: "{{ dehydrated_config_dir }}/domains.txt" - state: touch - -- name: Ensure config is present. - template: - src: config.j2 - dest: "{{ dehydrated_config_dir }}/config" - notify: dehydrated register - -- name: Install dehydrated cron job. - cron: - name: renew dehydrated certs - hour: "{{ dehydrated_cron_hour }}" - minute: "{{ dehydrated_cron_minute }}" - day: "{{ dehydrated_cron_day }}" - job: "{{ dehydrated_binary }} -c -g" \ No newline at end of file +- include_tasks: install.yml +- include_tasks: domains.yml \ No newline at end of file diff --git a/roles/dehydrated-domains/templates/hook.sh.j2 b/roles/dehydrated/templates/hook.sh.j2 similarity index 100% rename from roles/dehydrated-domains/templates/hook.sh.j2 rename to roles/dehydrated/templates/hook.sh.j2 From 4b37aa2d49a528588d860b8ff97c2417d3c7e51b Mon Sep 17 00:00:00 2001 From: David Kilias Date: Tue, 23 Feb 2021 21:12:36 +0100 Subject: [PATCH 15/18] domains need a default --- roles/dehydrated/defaults/main.yml | 1 + roles/dehydrated/tasks/main.yml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/roles/dehydrated/defaults/main.yml b/roles/dehydrated/defaults/main.yml index 74a8e83..41442df 100644 --- a/roles/dehydrated/defaults/main.yml +++ b/roles/dehydrated/defaults/main.yml @@ -6,3 +6,4 @@ dehydrated_binary: "/usr/local/bin/dehydrated" dehydrated_config_dir: "/usr/local/etc/dehydrated" dehydrated_certs_dir: "{{ dehydrated_config_dir }}/certs" dehydrated_wellknown_dir: "{{ dehydrated_config_dir }}/challenge" +dehydrated_domains: \ No newline at end of file diff --git a/roles/dehydrated/tasks/main.yml b/roles/dehydrated/tasks/main.yml index 90c9742..f440275 100644 --- a/roles/dehydrated/tasks/main.yml +++ b/roles/dehydrated/tasks/main.yml @@ -1,3 +1,4 @@ --- - include_tasks: install.yml -- include_tasks: domains.yml \ No newline at end of file +- include_tasks: domains.yml + when: dehydrated_domains is iterable \ No newline at end of file From 011b4d355c25c7e555e912eb35a0c0b898ba53b4 Mon Sep 17 00:00:00 2001 From: David Kilias Date: Tue, 23 Feb 2021 21:13:03 +0100 Subject: [PATCH 16/18] fix readme for changes --- roles/dehydrated/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/dehydrated/README.md b/roles/dehydrated/README.md index 816a898..ada63a9 100644 --- a/roles/dehydrated/README.md +++ b/roles/dehydrated/README.md @@ -1,6 +1,6 @@ # Dehydrated -Ansible role to configure domains for use with dehydrated +Ansible role to configure dehydrated ## Usage @@ -16,5 +16,5 @@ vars: clean_challenge_hook: printf 'server 127.0.0.1\nupdate delete _acme-challenge.%s TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key roles: - - role: dehydrated-domains + - role: dehydrated ``` \ No newline at end of file From 06400afc87f0b8e37bcac7f855f91efa04cbebaa Mon Sep 17 00:00:00 2001 From: David Kilias Date: Thu, 25 Feb 2021 14:47:59 +0100 Subject: [PATCH 17/18] rename handler, cron didn't really fit --- roles/dehydrated/handlers/main.yml | 2 +- roles/dehydrated/tasks/domains.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/dehydrated/handlers/main.yml b/roles/dehydrated/handlers/main.yml index 9552e98..5a55b3a 100644 --- a/roles/dehydrated/handlers/main.yml +++ b/roles/dehydrated/handlers/main.yml @@ -2,6 +2,6 @@ - name: dehydrated register command: "{{ dehydrated_binary }} --register --accept-terms" -- name: dehydrated cron +- name: dehydrated run command: "{{ dehydrated_binary }} --cron" when: dehydrated_force_update|default(False)|bool \ No newline at end of file diff --git a/roles/dehydrated/tasks/domains.yml b/roles/dehydrated/tasks/domains.yml index d082e39..102b8aa 100644 --- a/roles/dehydrated/tasks/domains.yml +++ b/roles/dehydrated/tasks/domains.yml @@ -16,4 +16,4 @@ path: "{{ dehydrated_config_dir }}/domains.txt" line: "{{ item.name }}{% for an in item.alternate_names %} {{ an|default(omit) }}{% endfor %}" with_items: dehydrated_domains - notify: dehydrated cron \ No newline at end of file + notify: dehydrated run \ No newline at end of file From ea4e167f204a4e18ad016a1cb73f5f946ebccd15 Mon Sep 17 00:00:00 2001 From: David Kilias Date: Fri, 26 Feb 2021 21:26:14 +0100 Subject: [PATCH 18/18] fix domain iteration --- roles/dehydrated/tasks/domains.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/dehydrated/tasks/domains.yml b/roles/dehydrated/tasks/domains.yml index 102b8aa..aa020d4 100644 --- a/roles/dehydrated/tasks/domains.yml +++ b/roles/dehydrated/tasks/domains.yml @@ -3,17 +3,17 @@ file: name: "{{ dehydrated_certs_dir }}/{{ item.name }}" state: directory - with_items: dehydrated_domains + with_items: "{{ dehydrated_domains }}" - name: Render hook script templates. template: src: hook.sh.j2 dest: "{{ dehydrated_certs_dir }}/{{ item.name }}/hook.sh" - with_items: dehydrated_domains + with_items: "{{ dehydrated_domains }}" - name: Ensure Domains are in domains.txt lineinfile: path: "{{ dehydrated_config_dir }}/domains.txt" - line: "{{ item.name }}{% for an in item.alternate_names %} {{ an|default(omit) }}{% endfor %}" - with_items: dehydrated_domains + line: "{{ item.name }}{% if 'alternate_names' in item %}{% for an in item.alternate_names %} {{ an|default(omit) }}{% endfor %}{% endif %}" + with_items: "{{ dehydrated_domains }}" notify: dehydrated run \ No newline at end of file