add dehydrated role with pdns-api.sh support (#25)
* add dehydrated role with pdns-api.sh support * Minor changes to Readme * Remove Meta * move dehydrated to linse * Remove Zuckerwatte from PR (nothing to do with dehydrated) * Add other domains to dehydrated config, added hook_chain * Add authorized keys for cert user, add structures in /home/cert/ for checking out certs * Send dehydrated ouput to /dev/null * user authorized_keys module, add kumpir key * Fix typo. Use \\n for each ssh-key * remove unnecessary .ssh creation (done by authorized_key module) * Added wrapper script to execute two hooks: pdns_api.sh + deploy certificates * Remove challengetype variable, as only dns-01 is supported anyway. * Add freifunk-mainz.de domain * fix cert deploy script.
This commit is contained in:
parent
b564d8113c
commit
7611fb9d76
15 changed files with 474 additions and 4 deletions
|
@ -6,9 +6,23 @@ magic: 71
|
||||||
nodejs_major_version: "10"
|
nodejs_major_version: "10"
|
||||||
|
|
||||||
http_dns_prefix: "dns-ext"
|
http_dns_prefix: "dns-ext"
|
||||||
pdns_limit_api_access:
|
|
||||||
- 94.130.21.214
|
dehydrated_accept_letsencrypt_terms: yes
|
||||||
- 2a01:4f8:10b:1b29::1
|
dehydrated_contactemail: hostmaster@freifunk-mwu.de
|
||||||
|
dehydrated_domains: ffmwu.org *.ffmwu.org freifunk-mwu.de *.freifunk-mwu.de freifunk-mainz.de *.freifunk-mainz.de freifunk-wiesbaden.de *.freifunk-wiesbaden.de mainz.freifunk.net *.mainz.freifunk.net wiesbaden.freifunk.net *.wiesbaden.freifunk.net
|
||||||
|
pdns_host: http://localhost:8081
|
||||||
|
dehydrated_install_root: "{{ git_path }}/dehydrated"
|
||||||
|
dehydrated_deploycert:
|
||||||
|
ffmwu.org: |
|
||||||
|
mkdir -p /home/cert/certificates/$DOMAIN/
|
||||||
|
cp $KEYFILE /home/cert/certificates/$DOMAIN/
|
||||||
|
cp $CERTFILE /home/cert/certificates/$DOMAIN/
|
||||||
|
cp $CHAINFILE /home/cert/certificates/$DOMAIN/
|
||||||
|
cp $FULLCHAINFILE /home/cert/certificates/$DOMAIN/
|
||||||
|
chmod 750 $(find /home/cert/certificates -mindepth 1 -type d )
|
||||||
|
chmod 740 $(find /home/cert/certificates -mindepth 1 -type f )
|
||||||
|
chown root.cert -R /home/cert/certificates/*
|
||||||
|
dehydrated_authorized_keys: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHC4MutFCH6xgzwiarEjnASS5PpG3b3UEYDa8XNxCpy8 kumpir\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDzIaCJpcNlrwKAt+XAQEPOKvfV2xK5rhzyFez42rdmY84pMvAIbogI+HYZCgwUklcRA8/cpzX93sGFC9Gg/7drtRIL/3wQwf55UdeY+W+PVUkLGC/v+D6vSsxoYBn3eiHrbkZJOIJfLfiPrEUkQEAW98KRheySyhXAHpF+71jd/ZlD3DJtinXrexeHthX8APbgzoP6lQCQsH/XtqlO3bqSchTSj3MEl2ylRVWZHdgfc8+daX3s78T8C/zsue9AbXlWyjtL6n9fkYQ2kPkA+/0ymbHCFxq/rBnTq0CaIu/kiQjkI8oTi/tk3SpgNKnY2CKnTj1X62lEuAKgk2WfsjaVqH4K3xNJ4Ugl9kWCUPjJm+EMQ4rLhyi6lH10r2yYG1oBKGGOa+jYevHRqWmHmKuYTiHSFIQoPvd59MXE/3cQslt1RtcoxVl4E2U/S+s3ph8J4nGDa980oE+VMRKG4RsJs9H/1XvWSUVo14xWBufbJR/PnxNicjOhImbfN2rPL1YmwllaqQovRoE4BuwU05iVlT5KwKErHcBO+tz8Gm9IjBuUk6pbUNAi/8Of7/g4BUIvL78/JiAaWBlrGxA169L+r+d9urDibdfVbILrWGI61MX7S2v7KCu5yXT3+UOS2p6oJoahO1mWOMQXcwn1Yf1OlHg5RNUFqcNvw8u119H08Q== wasserfloh"
|
||||||
|
|
||||||
mysql_root_password: "{{ lookup('passwordstore', inventory_hostname_short + '/mysql_root subkey=secret') }}"
|
mysql_root_password: "{{ lookup('passwordstore', inventory_hostname_short + '/mysql_root subkey=secret') }}"
|
||||||
mysql_databases:
|
mysql_databases:
|
||||||
|
|
|
@ -21,4 +21,4 @@
|
||||||
- geerlingguy.mysql
|
- geerlingguy.mysql
|
||||||
- powerdns.pdns
|
- powerdns.pdns
|
||||||
- pdns-admin
|
- pdns-admin
|
||||||
- pdns-api
|
- service-dehydrated
|
||||||
|
|
20
roles/service-dehydrated/LICENSE
Normal file
20
roles/service-dehydrated/LICENSE
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
Copyright (c) 2018 Alexander Zielke
|
||||||
|
Copyright (c) 2019 Sebastian Schmachtel
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
141
roles/service-dehydrated/README.md
Normal file
141
roles/service-dehydrated/README.md
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
# service-dehydrated
|
||||||
|
|
||||||
|
Install, configure and run dehydrated Let's Encrypt client using powerdns api hook
|
||||||
|
|
||||||
|
- Based upon clutterbox.dehydrated (https://github.com/clutterbox/ansible-dehydrated) by Alexander Zielke
|
||||||
|
- Stripped down for simplicity: removed http-01 challenge, hooks
|
||||||
|
- Added pdns_api.sh (https://github.com/silkeh/pdns_api.sh) for powerdns api handling
|
||||||
|
|
||||||
|
|
||||||
|
- [service-dehydrated](#clutterboxdehydrated)
|
||||||
|
* [Role Variables](#role-variables)
|
||||||
|
* [Using dns-01 challenges](#using-dns-01-challenges)
|
||||||
|
* [using systemd timers](#using-systemd-timers)
|
||||||
|
* [Overriding per certificate config](#overriding-per-certificate-config)
|
||||||
|
* [dehydrated_deploycert](#dehydrated-deploycert)
|
||||||
|
+ [Variables](#variables)
|
||||||
|
* [Example Playbooks](#example-playbooks)
|
||||||
|
+ [Using dns-01 with cloudflare](#using-dns-01-with-cloudflare)
|
||||||
|
+ [Using dehydrated_deploycert with multiple certificates](#using-dehydrated-deploycert-with-multiple-certificates)
|
||||||
|
* [License](#license)
|
||||||
|
* [Author Information](#author-information)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Role Variables
|
||||||
|
|
||||||
|
Variable | Function | Default
|
||||||
|
--- | --- | ---
|
||||||
|
dehydrated_accept_letsencrypt_terms | Set to yes to automatically register and accept Let's Encrypt terms | no
|
||||||
|
dehydrated_contactemail | E-Mail address (required) |
|
||||||
|
dehydrated_domains | List of domains to request SSL certificates for |
|
||||||
|
dehydrated_deploycert | Script to run to deploy a certificate (see below) |
|
||||||
|
dehydrated_install_root | Where to install dehydrated | /opt/dehydrated
|
||||||
|
dehydrated_update | Update dehydrated sources on ansible run | yes
|
||||||
|
dehydrated_version | Which version to check out from github | HEAD
|
||||||
|
dehydrated_key_algo | Keytype to generate (rsa, prime256v1, secp384r1) | rsa
|
||||||
|
dehydrated_keysize | Size of Key (only for rsa Keys) | 4096
|
||||||
|
dehydrated_ca | CA to use | https://acme-v02.api.letsencrypt.org/directory
|
||||||
|
dehydrated_cronjob | Install cronjob for certificate renewals | yes
|
||||||
|
dehydrated_systemd_timer | Use systemd timer for certificate renewals | no
|
||||||
|
dehydrated_run_on_changes | If dehydrated should run if the list of domains changed | yes
|
||||||
|
dehydrated_systemd_timer_onfailure | If set, an OnFailure-Directive will be added to the systemd unit |
|
||||||
|
dehydrated_cert_config | Override configuration for certificates | []
|
||||||
|
dehydrated_repo_url | Specify URL to git repository of dehydrated | https://github.com/lukas2511/dehydrated.git
|
||||||
|
pdns_api_repo_url | Specify URL to git repository of pdns_api.sh | https://github.com/silkeh/pdns_api.sh
|
||||||
|
pdns_api_update | Update pdns_api.sh sources on ansible run | yes
|
||||||
|
pdns_api_version | Powerdns api version (v>=4 ? 1 : 0) | 1
|
||||||
|
|
||||||
|
## Using dns-01 challenges
|
||||||
|
|
||||||
|
Due to simplicity only dns-01 is supported. See [Example Playbooks](#example-playbooks)
|
||||||
|
|
||||||
|
## using systemd timers
|
||||||
|
|
||||||
|
It is possible to use a systemd-timer instead of a cronjob to renew certificates.
|
||||||
|
|
||||||
|
**Note**: Enabling the systemd timer does *not* disable the cronjob. This might change in the future.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
dehydrated_systemd_timer: yes
|
||||||
|
dehydrated_cronjob: no
|
||||||
|
```
|
||||||
|
|
||||||
|
## Overriding per certificate config
|
||||||
|
|
||||||
|
|
||||||
|
The Configration for single certificates can be overridden using `dehydrated_cert_config`.
|
||||||
|
|
||||||
|
`dehydrated_cert_config` must be a list of dicts. Only the elemenent `name:` is mandatory ans must match a certificate name. The certificate name is either the first domain listed in domains.txt or the certificate alias, if defined.
|
||||||
|
|
||||||
|
Format is as follows:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
dehydrated_cert_config:
|
||||||
|
- name: # certificate name or alias (mandatory)
|
||||||
|
state: present # present or absent (optional)
|
||||||
|
wellknown: # override WELLKNOWN (optional)
|
||||||
|
key_algo: # override KEY_ALGO (optional)
|
||||||
|
keysize: # override KEYSIZE (optional)
|
||||||
|
```
|
||||||
|
|
||||||
|
## dehydrated_deploycert
|
||||||
|
|
||||||
|
The variable dehydrated_deploycert contains a shellscript fragment to be executed when a certificate has successfully been optained. This variable can either be a multiline string or a hash of multiline strings.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
dehydrated_deploycert: |
|
||||||
|
service nginx reload
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, for ever certificate obtained, nginx will be reloaded
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
dehydrated_deploycert:
|
||||||
|
example.com: |
|
||||||
|
service nginx reload
|
||||||
|
service.example.com: |
|
||||||
|
cat ${FULLCHAINFILE} ${KEYFILE} > /etc/somewhere/ssl/full.pem
|
||||||
|
service someservice reload
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, for certificates with the primary domain example.com, nginx will be reloaded and for service.example.com the certificate, intermediate and key will be written to another file and someservice is reloaded.
|
||||||
|
|
||||||
|
### Variables
|
||||||
|
|
||||||
|
Variable | Function
|
||||||
|
--- | ---
|
||||||
|
DOMAIN | (Primary) Domain of the certificate
|
||||||
|
KEYFILE | Full path to the keyfile
|
||||||
|
CERTFILE | Full path to certificate file
|
||||||
|
FULLCHAINFILE | Full path to file containing both certificate and intermediate
|
||||||
|
CHAINFILE | Full path to intermediate certificate file
|
||||||
|
TIMESTAMP | Timestamp when the certificate was created.
|
||||||
|
|
||||||
|
## Example Playbooks
|
||||||
|
|
||||||
|
### Using dns-01 with powerdns (only supported use case)
|
||||||
|
```yaml
|
||||||
|
- hosts: servers
|
||||||
|
vars:
|
||||||
|
dehydrated_accept_letsencrypt_terms: yes
|
||||||
|
dehydrated_contactemail: hostmaster@example.com
|
||||||
|
dehydrated_domains: example.com
|
||||||
|
pdns_host: https://powerdns-api.url.com:port
|
||||||
|
|
||||||
|
dehydrated_deploycert: |
|
||||||
|
service nginx reload
|
||||||
|
roles:
|
||||||
|
- service-dehydrated
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
# Author Information
|
||||||
|
|
||||||
|
Alexander Zielke - mail@alexander.zielke.name
|
||||||
|
|
||||||
|
Sebastian Schmachtel - prisma_freifunk@oimel.net
|
21
roles/service-dehydrated/defaults/main.yml
Normal file
21
roles/service-dehydrated/defaults/main.yml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
dehydrated_dependencies:
|
||||||
|
- git
|
||||||
|
- openssl
|
||||||
|
- curl
|
||||||
|
dehydrated_repo_url: https://github.com/lukas2511/dehydrated.git
|
||||||
|
dehydrated_install_root: /opt/dehydrated
|
||||||
|
dehydrated_update: yes
|
||||||
|
dehydrated_version: HEAD
|
||||||
|
dehydrated_key_algo: rsa
|
||||||
|
dehydrated_keysize: 4096
|
||||||
|
dehydrated_ca: "https://acme-v02.api.letsencrypt.org/directory"
|
||||||
|
dehydrated_cronjob: yes
|
||||||
|
dehydrated_run_on_changes: yes
|
||||||
|
dehydrated_systemd_timer: no
|
||||||
|
dehydrated_hook_scripts: []
|
||||||
|
dehydrated_cert_config: []
|
||||||
|
# dehydrated_systemd_timer_onfailure: some_unit.service
|
||||||
|
pdns_api_version: HEAD
|
||||||
|
pdns_api_repo_url: https://github.com/silkeh/pdns_api.sh.git
|
||||||
|
pdns_api_update: yes
|
14
roles/service-dehydrated/handlers/main.yml
Normal file
14
roles/service-dehydrated/handlers/main.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
- name: run dehydrated
|
||||||
|
command: "{{ dehydrated_install_root }}/dehydrated -c"
|
||||||
|
when: dehydrated_run_on_changes
|
||||||
|
|
||||||
|
- name: Reload systemd
|
||||||
|
systemd:
|
||||||
|
daemon_reload: true
|
||||||
|
|
||||||
|
- name: Remove timer
|
||||||
|
systemd:
|
||||||
|
name: dehydrated.timer
|
||||||
|
enabled: no
|
||||||
|
state: stopped
|
28
roles/service-dehydrated/tasks/domain_config.yml
Normal file
28
roles/service-dehydrated/tasks/domain_config.yml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
- name: Ensure certificate directory exists
|
||||||
|
file:
|
||||||
|
path: "/etc/dehydrated/certs/{{ item.name }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0700
|
||||||
|
loop: "{{ dehydrated_cert_config }}"
|
||||||
|
|
||||||
|
- name: Generate per certificate configs
|
||||||
|
template:
|
||||||
|
dest: "/etc/dehydrated/certs/{{ item.name }}/config"
|
||||||
|
src: certconfig.j2
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0600
|
||||||
|
loop: "{{ dehydrated_cert_config }}"
|
||||||
|
when: item.state|default('present') == "present"
|
||||||
|
notify: run dehydrated
|
||||||
|
|
||||||
|
- name: Remove per certificate configs
|
||||||
|
file:
|
||||||
|
path: "/etc/dehydrated/certs/{{ item.name }}/config"
|
||||||
|
state: absent
|
||||||
|
loop: "{{ dehydrated_cert_config }}"
|
||||||
|
when: item.state|default('present') == "absent"
|
||||||
|
notify: run dehydrated
|
131
roles/service-dehydrated/tasks/main.yml
Normal file
131
roles/service-dehydrated/tasks/main.yml
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
---
|
||||||
|
- name: Install dehydrated dependencies
|
||||||
|
apt: name={{ dehydrated_dependencies }}
|
||||||
|
|
||||||
|
- name: Checkout dehydrated from github
|
||||||
|
git:
|
||||||
|
repo: "{{ dehydrated_repo_url }}"
|
||||||
|
update: "{{ dehydrated_update }}"
|
||||||
|
dest: "{{ dehydrated_install_root }}"
|
||||||
|
version: "{{ dehydrated_version }}"
|
||||||
|
|
||||||
|
- name: Checkout pdns_api.sh from github
|
||||||
|
git:
|
||||||
|
repo: "{{ pdns_api_repo_url }}"
|
||||||
|
update: "{{ pdns_api_update }}"
|
||||||
|
dest: "{{ dehydrated_install_root }}/pdns_api"
|
||||||
|
version: "{{ pdns_api_version }}"
|
||||||
|
|
||||||
|
- name: Create /etc/dehydrated
|
||||||
|
file: dest=/etc/dehydrated state=directory owner=root group=root mode=0700
|
||||||
|
|
||||||
|
- name: Generate dehydrated config
|
||||||
|
template:
|
||||||
|
dest: /etc/dehydrated/config
|
||||||
|
src: config.j2
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0600
|
||||||
|
|
||||||
|
- name: Generate dehydrated domains.txt
|
||||||
|
copy:
|
||||||
|
dest: /etc/dehydrated/domains.txt
|
||||||
|
content: "{{ dehydrated_domains }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0600
|
||||||
|
notify: run dehydrated
|
||||||
|
|
||||||
|
- import_tasks: domain_config.yml
|
||||||
|
|
||||||
|
- name: Generate hookwrapper.sh
|
||||||
|
template:
|
||||||
|
src: hookwrapper.j2
|
||||||
|
dest: /etc/dehydrated/hookwrapper.sh
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0700"
|
||||||
|
when: dehydrated_deploycert is defined
|
||||||
|
|
||||||
|
- name: Generate deploycert.sh
|
||||||
|
template:
|
||||||
|
src: deploycert.j2
|
||||||
|
dest: /etc/dehydrated/deploycert.sh
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0700"
|
||||||
|
when: dehydrated_deploycert is defined
|
||||||
|
|
||||||
|
- name: Remove deploycert.sh
|
||||||
|
file: dest=/etc/dehydrated/deploycert.sh state=absent
|
||||||
|
when: dehydrated_deploycert is not defined
|
||||||
|
|
||||||
|
- name: Remove hookwrapper.sh
|
||||||
|
file: dest=/etc/dehydrated/hookwrapper.sh state=absent
|
||||||
|
when: dehydrated_deploycert is not defined
|
||||||
|
|
||||||
|
- name: Install cronjob
|
||||||
|
cron:
|
||||||
|
name: dehydrated-renew
|
||||||
|
minute: "{{ 59|random(seed=inventory_hostname) }}"
|
||||||
|
hour: "{{ 4|random(seed=inventory_hostname) }}"
|
||||||
|
user: root
|
||||||
|
job: "{{ dehydrated_install_root }}/dehydrated -c > /dev/null"
|
||||||
|
cron_file: dehydrated
|
||||||
|
state: "{{ 'present' if dehydrated_cronjob else 'absent' }}"
|
||||||
|
|
||||||
|
- import_tasks: systemd.yml
|
||||||
|
|
||||||
|
# /opt/dehydrated/dehydrated --register --accept-terms
|
||||||
|
- name: Check if already registered
|
||||||
|
stat:
|
||||||
|
path: "/etc/dehydrated/accounts/{{ ((dehydrated_ca + '\n')|b64encode).rstrip('=').replace('+', '-').replace('/', '_') }}"
|
||||||
|
register: ca_stat
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: "assert dehydrated_accept_letsencrypt_terms is true"
|
||||||
|
assert:
|
||||||
|
that: dehydrated_accept_letsencrypt_terms
|
||||||
|
|
||||||
|
- name: Register to CA
|
||||||
|
command: "{{ dehydrated_install_root }}/dehydrated --register --accept-terms"
|
||||||
|
# \end block register
|
||||||
|
when: "not ca_stat.stat.exists or (ca_stat.stat.isdir is defined and not ca_stat.stat.isdir)"
|
||||||
|
|
||||||
|
- meta: flush_handlers
|
||||||
|
|
||||||
|
|
||||||
|
- name: Add the cert user for distributing certs
|
||||||
|
user:
|
||||||
|
name: cert
|
||||||
|
|
||||||
|
- name: Create cert/bin directory if it does not exist
|
||||||
|
file:
|
||||||
|
path: /home/cert/bin
|
||||||
|
state: directory
|
||||||
|
owner: cert
|
||||||
|
group: cert
|
||||||
|
mode: '0700'
|
||||||
|
|
||||||
|
- name: Create certificates directory if it does not exist
|
||||||
|
file:
|
||||||
|
path: /home/cert/certificates
|
||||||
|
state: directory
|
||||||
|
owner: cert
|
||||||
|
group: cert
|
||||||
|
mode: '0700'
|
||||||
|
|
||||||
|
- name: generate authorized_keys
|
||||||
|
authorized_key:
|
||||||
|
key: "{{ dehydrated_authorized_keys }}"
|
||||||
|
key_options: command="$HOME/bin/rrsync -ro ~/certificates",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding
|
||||||
|
user: cert
|
||||||
|
exclusive: true
|
||||||
|
|
||||||
|
- name: Download rrsync
|
||||||
|
get_url:
|
||||||
|
url: http://ftp.samba.org/pub/unpacked/rsync/support/rrsync
|
||||||
|
dest: /home/cert/bin/rrsync
|
||||||
|
owner: cert
|
||||||
|
group: cert
|
||||||
|
mode: '0700'
|
29
roles/service-dehydrated/tasks/systemd.yml
Normal file
29
roles/service-dehydrated/tasks/systemd.yml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: Upload systemd service files
|
||||||
|
template:
|
||||||
|
src: "{{ item }}.j2"
|
||||||
|
dest: /etc/systemd/system/{{ item }}
|
||||||
|
loop:
|
||||||
|
- dehydrated.service
|
||||||
|
- dehydrated.timer
|
||||||
|
when: dehydrated_systemd_timer
|
||||||
|
notify: Reload systemd
|
||||||
|
|
||||||
|
- name: Remove system service files
|
||||||
|
file:
|
||||||
|
path: /etc/systemd/system/{{ item }}
|
||||||
|
state: absent
|
||||||
|
loop:
|
||||||
|
- dehydrated.service
|
||||||
|
- dehydrated.timer
|
||||||
|
when: not dehydrated_systemd_timer
|
||||||
|
notify: Remove timer
|
||||||
|
|
||||||
|
- name: Activate systemd timer
|
||||||
|
systemd:
|
||||||
|
daemon_reload: yes
|
||||||
|
name: dehydrated.timer
|
||||||
|
enabled: yes
|
||||||
|
state: started
|
||||||
|
when: dehydrated_systemd_timer
|
5
roles/service-dehydrated/templates/certconfig.j2
Normal file
5
roles/service-dehydrated/templates/certconfig.j2
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||||
|
{% if item.challengetype is defined %}CHALLENGETYPE={{ item.challengetype }}{% endif %}
|
||||||
|
{% if item.key_algo is defined %}KEY_ALGO={{ item.key_algo }}{% endif %}
|
||||||
|
{% if item.keysize is defined %}KEYSIZE={{ item.keysize }}{% endif %}
|
||||||
|
{% if item.wellknown is defined %}WELLKNOWN={{ item.wellknown }}{% endif %}
|
14
roles/service-dehydrated/templates/config.j2
Normal file
14
roles/service-dehydrated/templates/config.j2
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||||
|
CA="{{ dehydrated_ca }}"
|
||||||
|
CHALLENGETYPE="dns-01"
|
||||||
|
CONTACT_EMAIL="{{ dehydrated_contactemail | mandatory }}"
|
||||||
|
KEY_ALGO={{ dehydrated_key_algo }}
|
||||||
|
KEYSIZE={{ dehydrated_keysize }}
|
||||||
|
{% if dehydrated_deploycert is defined %}
|
||||||
|
HOOK=/etc/dehydrated/hookwrapper.sh
|
||||||
|
{% else %}
|
||||||
|
HOOK={{ dehydrated_install_root }}/pdns_api/pdns_api.sh
|
||||||
|
{% endif %}
|
||||||
|
HOOK_CHAIN="yes"
|
||||||
|
PDNS_HOST={{ pdns_host}}
|
||||||
|
PDNS_KEY={{ lookup('passwordstore', 'linse/pdns_apikey') }}
|
11
roles/service-dehydrated/templates/dehydrated.service.j2
Normal file
11
roles/service-dehydrated/templates/dehydrated.service.j2
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[Unit]
|
||||||
|
Description=ACME Cert renewal
|
||||||
|
ConditionFileNotEmpty=/etc/dehydrated/domains.txt
|
||||||
|
{% if dehydrated_systemd_timer_onfailure is defined %}
|
||||||
|
OnFailure={{ dehydrated_systemd_timer_onfailure }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=root
|
||||||
|
ExecStart={{ dehydrated_install_root }}/dehydrated --cron
|
||||||
|
Type=oneshot
|
10
roles/service-dehydrated/templates/dehydrated.timer.j2
Normal file
10
roles/service-dehydrated/templates/dehydrated.timer.j2
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[Unit]
|
||||||
|
Description=ACME Cert renewal timer
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=*-*-* {{ 4|random(seed=inventory_hostname) }}:{{ 59|random(seed=inventory_hostname) }}:00
|
||||||
|
Persistent=true
|
||||||
|
RandomizedDelaySec=300
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
25
roles/service-dehydrated/templates/deploycert.j2
Normal file
25
roles/service-dehydrated/templates/deploycert.j2
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
deploy_cert() {
|
||||||
|
local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="${6}"
|
||||||
|
|
||||||
|
{% if dehydrated_deploycert is string %}
|
||||||
|
{{ dehydrated_deploycert }}
|
||||||
|
{% else %}
|
||||||
|
{% for domain, script in dehydrated_deploycert.items() %}
|
||||||
|
if [[ "${DOMAIN}" = "{{ domain }}" ]]; then
|
||||||
|
{{ script }}
|
||||||
|
fi
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLER="$1"; shift
|
||||||
|
if [[ "${HANDLER}" =~ ^(deploy_cert)$ ]]; then
|
||||||
|
"$HANDLER" "$@"
|
||||||
|
fi
|
7
roles/service-dehydrated/templates/hookwrapper.j2
Normal file
7
roles/service-dehydrated/templates/hookwrapper.j2
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
{{ dehydrated_install_root }}/pdns_api/pdns_api.sh "$@"
|
||||||
|
{% if dehydrated_deploycert is defined %}
|
||||||
|
/etc/dehydrated/deploycert.sh "$@"
|
||||||
|
{% endif %}
|
Loading…
Reference in a new issue