mirror of
https://git.lapiole.org/dani/ansible-roles.git
synced 2025-07-27 00:05:44 +02:00
Update to 2021-12-01 19:13
This commit is contained in:
76
roles/letsencrypt/defaults/main.yml
Normal file
76
roles/letsencrypt/defaults/main.yml
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
|
||||
# Set the API endpoint to use. Default is to use https://acme-v02.api.letsencrypt.org/directory
|
||||
# letsencrypt_ca: https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
|
||||
# letsencrypt_key_size: 4096
|
||||
# letsencrypt_renew_days: 30
|
||||
# Can be rsa, prime256v1 or secp384r1
|
||||
# letsencrypt_key_algo: rsa
|
||||
# letsencrypt_auto_renew: True
|
||||
# letsencrypt_revoke_old_certs: False
|
||||
#
|
||||
letsencrypt_challenge: http
|
||||
# If you want to use dns-01 challenges
|
||||
# letsencrypt_challenge: dns
|
||||
# letsencrypt_dns_provider: gandi
|
||||
# letsencrypt_dns_provider_options: '--api-protocol=rest'
|
||||
# letsencrypt_dns_auth_token: XXXX
|
||||
|
||||
# Specify a preferred chain of intermediate certs
|
||||
# If not specified, it'll use the short ISRG Root X1 chain
|
||||
# (not signed with the expired DST Root CA X3)
|
||||
# The special value "default" means to omit the directive, and use the default
|
||||
# dehydrated value
|
||||
# letsencrypt_preferred_chain: default
|
||||
|
||||
#
|
||||
letsencrypt_certs: []
|
||||
# letsencrypt_certs:
|
||||
# - common_name: www.domain.org
|
||||
# alt_names:
|
||||
# - www1.domain.org
|
||||
# - m.domain.org
|
||||
# - foo.domain.org
|
||||
# - common_name: mail.domain.com
|
||||
# - common_name: ldap.domain.com
|
||||
# alt_names:
|
||||
# - directory.domain.com
|
||||
# config:
|
||||
# CHALLENGETYPE: http-01
|
||||
# RENEW_DAYS: 20
|
||||
# KEYSIZE: 3072
|
||||
|
||||
letsencrypt_base_hooks:
|
||||
clean_challenge: |
|
||||
#!/bin/bash -e
|
||||
# Managed by ansible, manual modifications will be lost
|
||||
deploy_cert: |
|
||||
#!/bin/bash -e
|
||||
# Managed by ansible, manual modifications will be lost
|
||||
deploy_challenge: |
|
||||
#!/bin/bash -e
|
||||
# Managed by ansible, manual modifications will be lost
|
||||
exit_hook: |
|
||||
#!/bin/bash -e
|
||||
# Managed by ansible, manual modifications will be lost
|
||||
generate_csr: |
|
||||
#!/bin/bash -e
|
||||
# Managed by ansible, manual modifications will be lost
|
||||
invalid_challenge: |
|
||||
#!/bin/bash -e
|
||||
# Managed by ansible, manual modifications will be lost
|
||||
request_failure: |
|
||||
#!/bin/bash -e
|
||||
# Managed by ansible, manual modifications will be lost
|
||||
startup_hook: |
|
||||
#!/bin/bash -e
|
||||
# Managed by ansible, manual modifications will be lost
|
||||
unchanged_cert: |
|
||||
#!/bin/bash -e
|
||||
# Managed by ansible, manual modifications will be lost
|
||||
|
||||
letsencrypt_extra_hooks: {}
|
||||
letsencrypt_hooks: "{{ letsencrypt_base_hooks | combine(letsencrypt_extra_hooks, recursive=True) }}"
|
||||
|
||||
...
|
2
roles/letsencrypt/files/common_letsencrypt.inc
Normal file
2
roles/letsencrypt/files/common_letsencrypt.inc
Normal file
@@ -0,0 +1,2 @@
|
||||
Alias /.well-known/acme-challenge/ /var/lib/dehydrated/challenges/
|
||||
ProxyPass /.well-known/acme-challenge/ !
|
16
roles/letsencrypt/files/httpd_dehydrated.conf
Normal file
16
roles/letsencrypt/files/httpd_dehydrated.conf
Normal file
@@ -0,0 +1,16 @@
|
||||
Alias /.well-known/acme-challenge/ /var/lib/dehydrated/challenges/
|
||||
|
||||
<Directory /var/lib/dehydrated/challenges>
|
||||
Options None
|
||||
AllowOverride None
|
||||
Header set Content-Type "application/jose+json"
|
||||
<IfModule mod_authz_core.c>
|
||||
# Apache 2.4
|
||||
Require all granted
|
||||
</IfModule>
|
||||
<IfModule !mod_authz_core.c>
|
||||
# Apache 2.2
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
</IfModule>
|
||||
</Directory>
|
6
roles/letsencrypt/handlers/main.yml
Normal file
6
roles/letsencrypt/handlers/main.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: renew dehydrated
|
||||
command: dehydrated -c
|
||||
environment:
|
||||
- https_proxy: "{{ system_proxy | default('') }}"
|
||||
...
|
167
roles/letsencrypt/tasks/main.yml
Normal file
167
roles/letsencrypt/tasks/main.yml
Normal file
@@ -0,0 +1,167 @@
|
||||
---
|
||||
|
||||
- include_vars: "{{ item }}"
|
||||
with_first_found:
|
||||
- vars/{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml
|
||||
- vars/{{ ansible_os_family }}-{{ ansible_distribution_major_version }}.yml
|
||||
- vars/{{ ansible_distribution }}.yml
|
||||
- vars/{{ ansible_os_family }}.yml
|
||||
tags: web,ssl
|
||||
|
||||
- name: Install dehydrated client
|
||||
package: name={{ letsencrypt_packages }}
|
||||
tags: web,ssl
|
||||
|
||||
- name: Detect openssl version
|
||||
shell: openssl version | perl -ne 'm/OpenSSL (\d+[^\s\-]+)/ && print "$1\n"'
|
||||
register: letsencrypt_openssl_version
|
||||
changed_when: False
|
||||
tags: web,ssl
|
||||
|
||||
- name: Create needed directories
|
||||
file: path={{ item }} state=directory
|
||||
with_items:
|
||||
- /etc/dehydrated
|
||||
- /var/lib/dehydrated/certificates
|
||||
- /var/lib/dehydrated/challenges
|
||||
tags: web,ssl
|
||||
|
||||
- name: Install dehydrated
|
||||
get_url:
|
||||
url: "{{ item.url }}"
|
||||
dest: "{{ item.dest }}"
|
||||
mode: 755
|
||||
force: True
|
||||
environment:
|
||||
- https_proxy: "{{ system_proxy | default('') }}"
|
||||
with_items:
|
||||
- url: https://raw.githubusercontent.com/dehydrated-io/dehydrated/master/dehydrated
|
||||
dest: /usr/local/bin/dehydrated
|
||||
- url: https://git.fws.fr/fws/dehydrated/raw/branch/master/dehydrated_hooks
|
||||
dest: /usr/local/bin/dehydrated_hooks
|
||||
when: ansible_os_family == 'Debian'
|
||||
tags: web,ssl
|
||||
|
||||
- name: Install lexicon
|
||||
pip: name=dns-lexicon state=latest
|
||||
environment:
|
||||
- https_proxy: "{{ system_proxy | default('') }}"
|
||||
when: ansible_os_family == 'Debian'
|
||||
tags: web,ssl
|
||||
|
||||
- name: Create hook directories
|
||||
file: path=/etc/dehydrated/hooks_{{ item }}.d state=directory
|
||||
loop:
|
||||
- clean_challenge
|
||||
- deploy_cert
|
||||
- deploy_challenge
|
||||
- unchanged_cert
|
||||
- invalid_challenge
|
||||
- request_failure
|
||||
- generate_csr
|
||||
- startup_hook
|
||||
- exit_hook
|
||||
tags: web,ssl
|
||||
|
||||
- name: Create per cert configuration dir
|
||||
file: path=/etc/dehydrated/certificates state=directory
|
||||
tags: web,ssl
|
||||
|
||||
- name: Deploy default hooks
|
||||
copy: content={{ letsencrypt_hooks[item] }} dest=/etc/dehydrated/hooks_{{ item }}.d/00-default mode=755
|
||||
loop:
|
||||
- clean_challenge
|
||||
- deploy_cert
|
||||
- deploy_challenge
|
||||
- unchanged_cert
|
||||
- invalid_challenge
|
||||
- request_failure
|
||||
- generate_csr
|
||||
- startup_hook
|
||||
- exit_hook
|
||||
tags: web,ssl
|
||||
|
||||
- name: Remove obsolete gandi_live backend # merged with gandi now
|
||||
file: path=/usr/lib/python2.7/site-packages/lexicon/providers/{{ item }} state=absent
|
||||
loop:
|
||||
- gandi_live.py
|
||||
- gandi_live.pyc
|
||||
tags: web,ssl
|
||||
|
||||
- name: Deploy lexicon hooks
|
||||
template: src=dns-lexicon-{{ item }}.j2 dest=/etc/dehydrated/hooks_{{ item }}.d/dns-lexicon mode=755
|
||||
with_items:
|
||||
- deploy_challenge
|
||||
- clean_challenge
|
||||
when:
|
||||
- letsencrypt_challenge == 'dns'
|
||||
- letsencrypt_dns_provider is defined
|
||||
- letsencrypt_dns_auth_token is defined
|
||||
tags: web,ssl
|
||||
|
||||
- name: Remove lexicon hooks
|
||||
file: path=/etc/dehydrated/hooks_{{ item }}.d/dns-lexicon state=absent
|
||||
with_items:
|
||||
- deploy_challenge
|
||||
- clean_challenge
|
||||
when: letsencrypt_challenge != 'dns' or letsencrypt_dns_provider is not defined or letsencrypt_dns_auth_token is not defined
|
||||
tags: web,ssl
|
||||
|
||||
- name: Deploy dehydrated configuration
|
||||
template: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode | default('644') }}
|
||||
with_items:
|
||||
- src: config.j2
|
||||
dest: /etc/dehydrated/config
|
||||
mode: 600
|
||||
- src: domains.txt.j2
|
||||
dest: /etc/dehydrated/domains.txt
|
||||
- src: cron.j2
|
||||
dest: /etc/cron.daily/dehydrated
|
||||
mode: 755
|
||||
notify: renew dehydrated
|
||||
tags: web,ssl
|
||||
|
||||
- name: Deploy per certificate config
|
||||
template: src=cert_config.j2 dest=/etc/dehydrated/certificates/{{ item.common_name }} mode=600
|
||||
loop: "{{ letsencrypt_certs }}"
|
||||
notify: renew dehydrated
|
||||
tags: web,ssl
|
||||
|
||||
- name: Create httpd conf dir
|
||||
file: path=/etc/httpd/ansible_conf.d state=directory
|
||||
when: ansible_os_family == 'RedHat'
|
||||
tags: web,ssl
|
||||
|
||||
- name: Deploy dehydrated config for apache
|
||||
copy: src={{ item.src }} dest={{ item.dest }}
|
||||
with_items:
|
||||
- src: httpd_dehydrated.conf
|
||||
dest: /etc/httpd/ansible_conf.d/10-dehydrated.conf
|
||||
- src: common_letsencrypt.inc
|
||||
dest: /etc/httpd/ansible_conf.d/common_letsencrypt.inc
|
||||
register: letsencrypt_httpd_conf
|
||||
when: ansible_os_family == 'RedHat'
|
||||
tags: web,ssl
|
||||
|
||||
- name: Check if Apache httpd is installed
|
||||
stat: path=/lib/systemd/system/httpd.service
|
||||
register: letsencrypt_httpd
|
||||
when: ansible_os_family == 'RedHat'
|
||||
tags: web,ssl
|
||||
|
||||
- name: Reload httpd config
|
||||
command: /bin/systemctl condreload httpd
|
||||
when:
|
||||
- letsencrypt_httpd_conf.changed
|
||||
- letsencrypt_httpd.stat.exists
|
||||
- ansible_os_family == 'RedHat'
|
||||
tags: web,ssl
|
||||
|
||||
- name: Register on Let's Encrypt
|
||||
command: dehydrated --register --accept-terms
|
||||
changed_when: False
|
||||
environment:
|
||||
- https_proxy: "{{ system_proxy | default('') }}"
|
||||
tags: web,ssl
|
||||
|
||||
...
|
5
roles/letsencrypt/templates/cert_config.j2
Normal file
5
roles/letsencrypt/templates/cert_config.j2
Normal file
@@ -0,0 +1,5 @@
|
||||
{% if item.config is defined and item.config is mapping %}
|
||||
{% for key in item.config.keys() | list %}
|
||||
{{ key }}={{ item.config[key] }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
33
roles/letsencrypt/templates/config.j2
Normal file
33
roles/letsencrypt/templates/config.j2
Normal file
@@ -0,0 +1,33 @@
|
||||
{% if letsencrypt_ca is defined %}
|
||||
CA={{ letsencrypt_ca }}
|
||||
{% endif %}
|
||||
IP_VERSION=4
|
||||
BASEDIR=/var/lib/dehydrated/certificates
|
||||
DOMAINS_TXT=/etc/dehydrated/domains.txt
|
||||
DOMAINS_D=/etc/dehydrated/certificates
|
||||
WELLKNOWN=/var/lib/dehydrated/challenges
|
||||
KEYSIZE="{{ letsencrypt_key_size | default('4096') }}"
|
||||
HOOK=/usr/{{ (ansible_os_family == 'Debian') | ternary('local/','') }}bin/dehydrated_hooks
|
||||
RENEW_DAYS="{{ letsencrypt_renew_days | default('30') }}"
|
||||
PRIVATE_KEY_RENEW="yes"
|
||||
{% if letsencrypt_preferred_chain is not defined %}
|
||||
PREFERRED_CHAIN="{{ letsencrypt_openssl_version.stdout is version('1.1', '>=') | ternary('ISRG Root X1','issuer= /C=US/O=Internet Security Research Group/CN=ISRG Root X1') }}"
|
||||
{% elif letsencrypt_preferred_chain != 'default' %}
|
||||
PREFERRED_CHAIN={{ letsencrypt_preferred_chain | quote }}
|
||||
{% endif %}
|
||||
{% if letsencrypt_key_algo | default('rsa') in ['rsa', 'prime256v1', 'secp384r1' ] %}
|
||||
KEY_ALGO={{ letsencrypt_key_algo | default('rsa') }}
|
||||
{% endif %}
|
||||
{% if system_admin_email is defined %}
|
||||
CONTACT_EMAIL={{ system_admin_email }}
|
||||
{% endif %}
|
||||
{% if letsencrypt_challenge == 'dns' and letsencrypt_dns_provider is defined and letsencrypt_dns_auth_token is defined %}
|
||||
CHALLENGETYPE=dns-01
|
||||
export DNS_PROVIDER="{{ letsencrypt_dns_provider }}"
|
||||
export LEXICON_{{ letsencrypt_dns_provider | upper }}_TOKEN="{{ letsencrypt_dns_auth_token }}"
|
||||
{% endif %}
|
||||
{% if system_proxy is defined and system_proxy != '' %}
|
||||
{% for proto in ['http','https','HTTP','HTTPS'] %}
|
||||
export {{ proto }}_proxy={{ system_proxy }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
10
roles/letsencrypt/templates/cron.j2
Normal file
10
roles/letsencrypt/templates/cron.j2
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
{% if letsencrypt_auto_renew | default(True) %}
|
||||
sleep $[ $RANDOM % 900 ];
|
||||
systemd-cat dehydrated --cron --keep-going
|
||||
{% endif %}
|
||||
|
||||
{% if letsencrypt_revoke_old_certs | default(False) and ansible_os_family == 'RedHat' %}
|
||||
systemd-cat dehydrated_revoke
|
||||
{% endif %}
|
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
DOMAIN="${1}"
|
||||
TOKEN_VALUE="${3}"
|
||||
lexicon $DNS_PROVIDER {% if letsencrypt_dns_provider_options is defined %}{{ letsencrypt_dns_provider_options }} {% endif %}delete ${DOMAIN} TXT --name="_acme-challenge.${DOMAIN}." --content="${TOKEN_VALUE}"
|
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
DOMAIN="${1}"
|
||||
TOKEN_VALUE="${3}"
|
||||
lexicon $DNS_PROVIDER {% if letsencrypt_dns_provider_options is defined %}{{ letsencrypt_dns_provider_options }} {% endif %}create ${DOMAIN} TXT --name="_acme-challenge.${DOMAIN}." --content="${TOKEN_VALUE}"
|
||||
sleep 5
|
||||
|
51
roles/letsencrypt/templates/domains.txt.j2
Normal file
51
roles/letsencrypt/templates/domains.txt.j2
Normal file
@@ -0,0 +1,51 @@
|
||||
{% for cert in letsencrypt_certs | default([]) %}
|
||||
{{ cert.common_name }} {{ cert.alt_names | default([]) | join(' ') }}
|
||||
{% endfor %}
|
||||
{% if nginx_auto_letsencrypt_cert is defined and nginx_auto_letsencrypt_cert and nginx_vhosts is defined %}
|
||||
{% for vhost in nginx_vhosts %}
|
||||
{% if vhost.ssl.cert is not defined and (vhost.ssl.letsencrypt_cert is not defined or vhost.ssl.letsencrypt_cert not in letsencrypt_certs | default([]) | map(attribute='common_name')) %}
|
||||
{{ vhost.name }} {{ vhost.aliases | default([]) | join(' ') }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if role_wh_proxy | default(False) %}
|
||||
{% for client in wh_clients | default([]) %}
|
||||
{% for app in client.apps %}
|
||||
{% set app = wh_default_app | combine(app, recursive=True) %}
|
||||
{% if app.letsencrypt_cert %}
|
||||
{{ app.vhost | default(client.name + '-' + app.name + '.wh.fws.fr') }} {{ app.aliases | join(' ') }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if pve_letsencrypt is defined and pve_letsencrypt and inventory_hostname not in letsencrypt_certs | default([]) | map(attribute='common_name') %}
|
||||
{{ inventory_hostname }} {{ pve_cluster_vhosts | join(' ') }}
|
||||
{% endif %}
|
||||
{% if graylog_letsencrypt_cert is defined and graylog_letsencrypt_cert not in letsencrypt_certs | default([]) | map(attribute='common_name') %}
|
||||
{{ graylog_letsencrypt_cert }}
|
||||
{% endif %}
|
||||
{% if zcs_letsencrypt is defined and zcs_letsencrypt and inventory_hostname not in letsencrypt_certs | default([]) | map(attribute='common_name') %}
|
||||
{{ inventory_hostname }} {{ zcs_vhosts | default([]) | join(' ') }}
|
||||
{% endif %}
|
||||
{% if bitwarden_letsencrypt_cert is defined and bitwarden_letsencrypt_cert == True %}
|
||||
{{ bitwarden_public_url | urlsplit('hostname') }}
|
||||
{% endif %}
|
||||
{% if psono_letsencrypt_cert is defined and psono_letsencrypt_cert == True %}
|
||||
{{ psono_public_url | urlsplit('hostname') }}
|
||||
{% endif %}
|
||||
{% if jitsi_letsencrypt_cert is defined and jitsi_letsencrypt_cert == True and jitsi_domain is defined %}
|
||||
{{ jitsi_domain }} auth.{{ jitsi_domain }}
|
||||
{% endif %}
|
||||
{% if turn_letsencrypt_cert is defined and turn_letsencrypt_cert not in letsencrypt_certs | default([]) | map(attribute='common_name') %}
|
||||
{{ turn_letsencrypt_cert }}
|
||||
{% endif %}
|
||||
{% if rabbitmq_letsencrypt_cert is defined and rabbitmq_letsencrypt_cert != False %}
|
||||
{% if rabbitmq_letsencrypt_cert is string and rabbitmq_letsencrypt_cert not in letsencrypt_certs | default([]) | map(attribute='common_name') %}
|
||||
{{ rabbitmq_letsencrypt_cert }}
|
||||
{% elif rabbitmq_letsencrypt_cert == True and inventory_hostname not in letsencrypt_certs | default([]) | map(attribute='common_name') %}
|
||||
{{ inventory_hostname }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if pbs_letsencrypt_cert is defined and pbs_letsencrypt_cert not in letsencrypt_certs | default([]) | map(attribute='common_name') %}
|
||||
{{ pbs_letsencrypt_cert }}
|
||||
{% endif %}
|
6
roles/letsencrypt/vars/Debian-10.yml
Normal file
6
roles/letsencrypt/vars/Debian-10.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
|
||||
letsencrypt_packages:
|
||||
- python-pip
|
||||
- python-setuptools
|
||||
- curl
|
6
roles/letsencrypt/vars/Debian-11.yml
Normal file
6
roles/letsencrypt/vars/Debian-11.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
|
||||
letsencrypt_packages:
|
||||
- python3-pip
|
||||
- python3-setuptools
|
||||
- curl
|
6
roles/letsencrypt/vars/Debian-9.yml
Normal file
6
roles/letsencrypt/vars/Debian-9.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
|
||||
letsencrypt_packages:
|
||||
- python-pip
|
||||
- python-setuptools
|
||||
- curl
|
5
roles/letsencrypt/vars/RedHat-7.yml
Normal file
5
roles/letsencrypt/vars/RedHat-7.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
|
||||
letsencrypt_packages:
|
||||
- dehydrated
|
||||
- python2-dns-lexicon
|
5
roles/letsencrypt/vars/RedHat-8.yml
Normal file
5
roles/letsencrypt/vars/RedHat-8.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
|
||||
letsencrypt_packages:
|
||||
- dehydrated
|
||||
- python3-dns-lexicon
|
Reference in New Issue
Block a user