From ce3240e162e9d6096e659b27b56b7c4a1143d9fe Mon Sep 17 00:00:00 2001 From: Dan Morrison Date: Tue, 6 Feb 2024 18:44:07 +1300 Subject: [PATCH] Implement support for DNS install method --- README.md | 36 +++++++++++++++++++++++++--------- defaults/main.yml | 5 +++-- tasks/create-cert-dns.yml | 9 +++++++++ tasks/install-with-package.yml | 8 +++++++- tasks/install-with-snap.yml | 8 ++++++++ tasks/main.yml | 8 ++++++++ 6 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 tasks/create-cert-dns.yml diff --git a/README.md b/README.md index 12a8d41..f2a0607 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ By default, this role configures a cron job to run under the provided user accou ### Automatic Certificate Generation -Currently the `standalone` and `webroot` method are supported for generating new certificates using this role. +Currently the `standalone`, `webroot` and `dns` methods are supported for generating new certificates using this role. **For a complete example**: see the fully functional test playbook in [molecule/default/playbook-standalone-nginx-aws.yml](molecule/default/playbook-standalone-nginx-aws.yml). @@ -36,7 +36,7 @@ Set `certbot_create_if_missing` to `yes` or `True` to let this role generate cer certbot_create_method: standalone -Set the method used for generating certs with the `certbot_create_method` variable — current allowed values are: `standalone` or `webroot`. +Set the method used for generating certs with the `certbot_create_method` variable — current allowed values are: `standalone`, `webroot`, or `dns`. certbot_testmode: false @@ -74,6 +74,30 @@ Services that should be stopped while `certbot` runs it's own standalone server These services will only be stopped the first time a new cert is generated. +#### Webroot Certificate Generation + +When using the `webroot` creation method, a `webroot` item has to be provided for every `certbot_certs` item, specifying which directory to use for the authentication. Also, make sure your webserver correctly delivers contents from this directory. + +#### DNS Certficate Generation + +When using the `dns` creation method, you must specify `certbot_dns_plugin` to specify which [DNS plugin](https://eff-certbot.readthedocs.io/en/latest/using.html#dns-plugins) should be used: + + certbot_dns_plugin: 'route53' + +It's important to note that most of the DNS plugins require additional configuration, which must be configured elsewhere in your playbook. For example, some DNS plugins (e.g. [AWS Route53](https://certbot-dns-route53.readthedocs.io/en/stable/)), require environment variables to be set. This can be achieved with the [environment](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_environment.html) module: + + environment: + AWS_ACCESS_KEY_ID: "{{ aws_access_key }}" + AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}" + AWS_DEFAULT_REGION: "us-east-1" + +Others (e.g. [Digital Ocean](https://certbot-dns-digitalocean.readthedocs.io/en/stable/)) require you to pass an extra argument with the path to a configuration file. + + certbot_create_extra_args: "--dns-digitalocean-credentials=/tmp/digitalocean_token.ini" + +This approach of using `certbot_create_extra_args` also allows you to configure other DNS options, for example `--dns-digitalocean-propagation-seconds=30` to set the time to wait for DNS propagation. + + ### Snap Installation Beginning in December 2020, the Certbot maintainers decided to recommend installing Certbot from Snap rather than maintain scripts like `certbot-auto`. @@ -82,10 +106,6 @@ Setting `certbot_install_method: snap` configures this role to install Certbot v This install method is currently experimental and may or may not work across all Linux distributions. -#### Webroot Certificate Generation - -When using the `webroot` creation method, a `webroot` item has to be provided for every `certbot_certs` item, specifying which directory to use for the authentication. Also, make sure your webserver correctly delivers contents from this directory. - ### Source Installation from Git You can install Certbot from it's Git source repository if desired with `certbot_install_method: source`. This might be useful in several cases, but especially when older distributions don't have Certbot packages available (e.g. CentOS < 7, Ubuntu < 16.10 and Debian < 8). @@ -102,9 +122,7 @@ The directory inside which Certbot will be cloned. ### Wildcard Certificates -Let's Encrypt supports [generating wildcard certificates](https://community.letsencrypt.org/t/acme-v2-and-wildcard-certificate-support-is-live/55579), but the process for generating and using them is slightly more involved. See comments in [this pull request](https://github.com/geerlingguy/ansible-role-certbot/pull/60#issuecomment-423919284) for an example of how to use this role to maintain wildcard certs. - -Michael Porter also has a walkthrough of [Creating A Let’s Encrypt Wildcard Cert With Ansible](https://www.michaelpporter.com/2018/09/creating-a-wildcard-cert-with-ansible/), specifically with Cloudflare. +Let's Encrypt supports [generating wildcard certificates](https://community.letsencrypt.org/t/acme-v2-and-wildcard-certificate-support-is-live/55579) using the DNS method (`certbot_create_method: dns`) only. ## Dependencies diff --git a/defaults/main.yml b/defaults/main.yml index dc1034e..7a242fb 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -8,7 +8,7 @@ certbot_auto_renew_options: "--quiet" certbot_testmode: false certbot_hsts: false - +certbot_create_extra_args: "" # Parameters used when creating new Certbot certs. certbot_create_if_missing: false @@ -28,7 +28,8 @@ certbot_certs: [] # - example3.com certbot_create_command: >- - {{ certbot_script }} certonly --{{ certbot_create_method }} + {{ certbot_script }} certonly + --{{ certbot_create_method }}{{ "-" ~ certbot_dns_plugin if certbot_create_method == 'dns' else '' }} {{ '--hsts' if certbot_hsts else '' }} {{ '--test-cert' if certbot_testmode else '' }} --noninteractive --agree-tos diff --git a/tasks/create-cert-dns.yml b/tasks/create-cert-dns.yml new file mode 100644 index 0000000..27d065f --- /dev/null +++ b/tasks/create-cert-dns.yml @@ -0,0 +1,9 @@ +--- +- name: Check if certificate already exists. + stat: + path: /etc/letsencrypt/live/{{ cert_item.domains | first | replace('*.', '') }}/cert.pem + register: letsencrypt_cert + +- name: Generate new certificate if one doesn't exist. + command: "{{ certbot_create_command }}" + when: not letsencrypt_cert.stat.exists diff --git a/tasks/install-with-package.yml b/tasks/install-with-package.yml index 10490ff..5c2eb5f 100644 --- a/tasks/install-with-package.yml +++ b/tasks/install-with-package.yml @@ -1,7 +1,13 @@ --- -- name: Install Certbot. +- name: Install Certbot via package. package: "name={{ certbot_package }} state=present" +- name: Install Certbot DNS plugin via package. + package: "name=python3-certbot-dns-{{ certbot_dns_plugin }} state=present" + when: + - certbot_create_method == 'dns' + - certbot_dns_plugin is defined + - name: Set Certbot script variable. set_fact: certbot_script: "{{ certbot_package }}" diff --git a/tasks/install-with-snap.yml b/tasks/install-with-snap.yml index 7a0ca65..88b497a 100644 --- a/tasks/install-with-snap.yml +++ b/tasks/install-with-snap.yml @@ -29,6 +29,14 @@ name: certbot classic: true +- name: Install certbot DNS plugin via snap. + snap: + name: "certbot-dns-{{ certbot_dns_plugin }}" + classic: true + when: + - certbot_create_method == 'dns' + - certbot_dns_plugin is defined + - name: Symlink certbot into place. file: src: /snap/bin/certbot diff --git a/tasks/main.yml b/tasks/main.yml index 894143c..184f4d3 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -29,5 +29,13 @@ loop_control: loop_var: cert_item +- include_tasks: create-cert-dns.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