diff --git a/defaults/main.yml b/defaults/main.yml index 02134ba..cd65499 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -6,6 +6,9 @@ certbot_auto_renew_hour: "3" certbot_auto_renew_minute: "30" certbot_auto_renew_options: "--quiet --no-self-upgrade" +# Enable to use staging server instead of production (useful for testing) +certbot_use_staging_server: false + # Parameters used when creating new Certbot certs. certbot_create_if_missing: false certbot_create_method: standalone @@ -28,6 +31,29 @@ certbot_create_command: >- if certbot_create_standalone_stop_services else '' }} +# Parameters DNS Plugins (used when certbot_create_method = dns) +certbot_dns_plugin: rfc2136 +# certbot_dns_credentials_custom_file: # use when plugin is != rfc2136 +certbot_dns_target_server: 127.0.0.1 +certbot_dns_target_server_port: 53 +certbot_dns_tsig_keyname: "certbot." +certbot_dns_key_secret: "azertyAZERTY123456" +certbot_dns_key_algorithm: "HMAC-MD5" +certbot_dns_create_command: >- + {{ certbot_script }} certonly --noninteractive --agree-tos + {{ '--test-cert' + if certbot_use_staging_server + else '' }} + --dns-{{ certbot_dns_plugin }} --dns-{{ certbot_dns_plugin }}-credentials {{ certbot_dns_credentials_file }} + --email {{ cert_item.email | default(certbot_admin_email) }} + -d {{ cert_item.domains | join(',') }} + {{ '--deploy-hook /etc/letsencrypt/renewal-hooks/deploy/renew_hook.sh' + if certbot_create_dns_renew_hook_services + else '' }} + +certbot_create_dns_renew_hook_services: + - haproxy + certbot_create_standalone_stop_services: - nginx # - apache diff --git a/tasks/create-cert-dns-plugin.yml b/tasks/create-cert-dns-plugin.yml new file mode 100644 index 0000000..04131bd --- /dev/null +++ b/tasks/create-cert-dns-plugin.yml @@ -0,0 +1,64 @@ +--- +- name: Check if certificate already exists. + stat: + path: /etc/letsencrypt/live/{{ cert_item.domains | first | replace('*.', '') }}/cert.pem + register: letsencrypt_cert + +- name: Ensure pre,post,deploy hook folders exist. + file: + path: /etc/letsencrypt/renewal-hooks/{{ item }} + state: directory + mode: 0755 + owner: root + group: root + with_items: + - deploy + +- name: Create deploy hook to execute tasks post cert generatation. + template: + src: renew_hook.j2 + dest: /etc/letsencrypt/renewal-hooks/deploy/renew_hook.sh + owner: root + group: root + mode: 0750 + when: + - certbot_create_dns_renew_hook_services is defined + +- name: "Create DNS RFC {{ certbot_dns_plugin }} Credentials File." + template: + src: dns_plugin_credentials.j2 + dest: "{{certbot_dns_credentials_file}}" + owner: root + group: root + mode: 0600 + when: + - certbot_dns_plugin is in certbot_supported_dns_plugins + +- name: Upload custom dns credential file + copy: + src: "{{ certbot_dns_credentials_custom_file }}" + dest: "{{ certbot_dns_credentials_file }}" + state: file + mode: 0600 + owner: root + group: root + when: + - certbot_dns_plugin != 'rfc2136' + - certbot_dns_credentials_custom_file is defined + +- name: Generate new certificate if one doesn't exist. + command: "{{ certbot_dns_create_command }}" + when: not letsencrypt_cert.stat.exists + +- name: Assemble certificate crt and key into pem file for haproxy + assemble: + dest: "/etc/letsencrypt/live/{{ cert_item.domains | first | replace('*.', '') }}/{{ cert_item.domains | first | replace('*.', '') }}-haproxy.pem" + src: "/etc/letsencrypt/live/{{ cert_item.domains | first | replace('*.', '') }}/" + regexp: '(fullchain.pem|privkey.pem)' + remote_src: yes + owner: root + group: root + mode: '0600' + when: + - not letsencrypt_cert.stat.exists + - ('haproxy' is in certbot_create_dns_renew_hook_services)|bool \ No newline at end of file diff --git a/tasks/install-with-snap.yml b/tasks/install-with-snap.yml index 946ed13..d5aedab 100644 --- a/tasks/install-with-snap.yml +++ b/tasks/install-with-snap.yml @@ -35,6 +35,17 @@ dest: /usr/bin/certbot state: link +- name: Make sure certbot Trust Plugins With Root is set. + command: snap set certbot trust-plugin-with-root=ok + when: + - certbot_dns_plugin is defined + +- name: Install DNS Plugin - {{ certbot_dns_plugin }}. + snap: + name: "certbot-dns-{{certbot_dns_plugin}}" + classic: true + when: certbot_dns_plugin is defined + - name: Set Certbot script variable. set_fact: certbot_script: /usr/bin/certbot diff --git a/tasks/main.yml b/tasks/main.yml index acd2426..e2a4382 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -21,5 +21,13 @@ loop_control: loop_var: cert_item +- include_tasks: create-cert-dns-plugin.yml + with_items: "{{ certbot_certs }}" + when: + - certbot_create_if_missing + - certbot_create_method == 'dns' + loop_control: + loop_var: cert_item + - import_tasks: renew-cron.yml when: certbot_auto_renew diff --git a/templates/dns_plugin_credentials.j2 b/templates/dns_plugin_credentials.j2 new file mode 100644 index 0000000..e858455 --- /dev/null +++ b/templates/dns_plugin_credentials.j2 @@ -0,0 +1,14 @@ +# {{ ansible_managed }} + +{% if certbot_dns_plugin == 'rfc2136' %} +# Target DNS server (IPv4 or IPv6 address, not a hostname) +dns_{{certbot_dns_plugin}}_server={{certbot_dns_target_server}} +# Target DNS port +dns_{{certbot_dns_plugin}}_port={{certbot_dns_target_server_port}} +# TSIG key name +dns_{{certbot_dns_plugin}}_name={{certbot_dns_tsig_keyname}} +# TSIG key secret +dns_{{certbot_dns_plugin}}_secret={{certbot_dns_key_secret}} +# TSIG key algorithm +dns_{{certbot_dns_plugin}}_algorithm={{certbot_dns_key_algorithm}} +{% endif %} \ No newline at end of file diff --git a/templates/renew_hook.j2 b/templates/renew_hook.j2 new file mode 100644 index 0000000..4cdd0a7 --- /dev/null +++ b/templates/renew_hook.j2 @@ -0,0 +1,11 @@ +#!/bin/bash +# {{ ansible_managed }} + +{% for item in certbot_create_dns_renew_hook_services %} + +{% if item == 'haproxy' %} +echo $RENEWED_LINEAGE > /tmp/RENEWED_LINEAGE.certbot.txt +echo $RENEWED_DOMAINS > /tmp/RENEWED_DOMAINS.certbot.txt +{% endif %} + +{% endfor %} diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..6229f3a --- /dev/null +++ b/vars/main.yml @@ -0,0 +1,3 @@ +certbot_dns_credentials_file: "/etc/letsencrypt/dns-{{certbot_dns_plugin}}-credentials" +certbot_supported_dns_plugins: + - rfc2136 \ No newline at end of file