Letsencrypt acme-sh-client has its own repository.
This commit is contained in:
parent
dbacfd7f04
commit
ba21e09bd6
38
README.md
38
README.md
|
@ -1,38 +1,46 @@
|
||||||
Role Name
|
Role Name
|
||||||
=========
|
=========
|
||||||
|
|
||||||
A brief description of the role goes here.
|
A role that installs the acme.sh Letsencrypt.org client
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
|
Git must be available as a package
|
||||||
|
|
||||||
Role Variables
|
Role Variables
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
|
Here are listed the most important defaults. See defaults/main.yml for the complete set of variables.
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
letsencrypt_acme_install: False
|
||||||
|
letsencrypt_acme_sh_git_install: True
|
||||||
|
letsencrypt_acme_sh_certificates_install_dir: '{{ ansible_fqdn }}'
|
||||||
|
letsencrypt_acme_sh_certificates_install_base_path: '{{ letsencrypt_acme_sh_user_home }}/live'
|
||||||
|
letsencrypt_acme_sh_certificates_install_path: '{{ letsencrypt_acme_sh_certificates_install_base_path }}/{{ letsencrypt_acme_sh_certificates_install_dir }}'
|
||||||
|
letsencrypt_acme_email: sysadmin@example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
* Set the following one to `80` if there is no web server that acts as reverse proxy.
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
letsencrypt_acme_standalone_port: 4402
|
||||||
|
letsencrypt_acme_sh_domains:
|
||||||
|
- { domain: '{{ ansible_fqdn }}', standalone: True }
|
||||||
|
```
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
------------
|
------------
|
||||||
|
|
||||||
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
|
None
|
||||||
|
|
||||||
Example Playbook
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
|
|
||||||
|
|
||||||
- hosts: servers
|
|
||||||
roles:
|
|
||||||
- { role: username.rolename, x: 42 }
|
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|
||||||
BSD
|
EUPL-1.2
|
||||||
|
|
||||||
Author Information
|
Author Information
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
|
Andrea Dell'Amico, <andrea.dellamico@isti.cnr.it>
|
||||||
|
|
|
@ -1,2 +1,75 @@
|
||||||
---
|
---
|
||||||
# defaults file for ansible-role-template
|
letsencrypt_acme_install: False
|
||||||
|
letsencrypt_acme_sh_install: '{{ letsencrypt_acme_install }}'
|
||||||
|
letsencrypt_acme_sh_git_install: True
|
||||||
|
letsencrypt_acme_sh_git_url: https://github.com/Neilpang/acme.sh.git
|
||||||
|
letsencrypt_acme_user: acme
|
||||||
|
letsencrypt_acme_sh_user: '{{ letsencrypt_acme_user }}'
|
||||||
|
letsencrypt_acme_user_home: /var/lib/acme
|
||||||
|
letsencrypt_acme_git_dest_dir: '{{ letsencrypt_acme_user_home }}/acme_sh_dist'
|
||||||
|
letsencrypt_acme_sh_user_home: '{{ letsencrypt_acme_user_home }}'
|
||||||
|
letsencrypt_acme_sh_base_data_dir: '{{ letsencrypt_acme_sh_user_home }}/acme_data'
|
||||||
|
letsencrypt_acme_sh_certs_data_prefix: '{{ ansible_fqdn }}'
|
||||||
|
letsencrypt_acme_sh_certs_data_path: '{{ letsencrypt_acme_sh_base_data_dir }}/certs/{{ letsencrypt_acme_sh_certs_data_prefix }}'
|
||||||
|
letsencrypt_acme_sh_certificates_install_dir: '{{ ansible_fqdn }}'
|
||||||
|
letsencrypt_acme_sh_certificates_install_base_path: '{{ letsencrypt_acme_sh_user_home }}/live'
|
||||||
|
letsencrypt_acme_sh_certificates_install_path: '{{ letsencrypt_acme_sh_certificates_install_base_path }}/{{ letsencrypt_acme_sh_certificates_install_dir }}'
|
||||||
|
letsencrypt_acme_sh_log_dir: /var/log/acme
|
||||||
|
letsencrypt_acme_sh_install_cron: False
|
||||||
|
letsencrypt_acme_sh_log_enabled: True
|
||||||
|
letsencrypt_acme_sh_auto_upgrade: False
|
||||||
|
letsencrypt_acme_sh_install_options: '--install'
|
||||||
|
letsencrypt_acme_sh_test_request: False
|
||||||
|
letsencrypt_acme_sh_use_syslog: True
|
||||||
|
letsencrypt_acme_sh_syslog_level: 6
|
||||||
|
|
||||||
|
# We only support the PowerDNS API. Adding other ones should be straightforward
|
||||||
|
letsencrypt_acme_sh_use_dns_provider: False
|
||||||
|
letsencrypt_acme_sh_dns_provider_type: dns_pdns
|
||||||
|
letsencrypt_acme_sh_dns_api_url: 'http://localhost:8081'
|
||||||
|
letsencrypt_acme_sh_dns_api_provider_id: localhost
|
||||||
|
# Use a vault variable for this one
|
||||||
|
letsencrypt_acme_sh_dns_api_token: XXXXXXX
|
||||||
|
|
||||||
|
|
||||||
|
letsencrypt_acme_sh_command: acme.sh
|
||||||
|
# The data directory is created by the acme.sh install
|
||||||
|
letsencrypt_acme_sh_dirs:
|
||||||
|
- '{{ letsencrypt_acme_sh_user_home }}/bin'
|
||||||
|
- '{{ letsencrypt_acme_sh_base_data_dir }}/certs'
|
||||||
|
- '{{ letsencrypt_acme_sh_base_data_dir }}/logs'
|
||||||
|
# - '{{ letsencrypt_acme_sh_base_data_dir }}/data'
|
||||||
|
letsencrypt_acme_sh_dest_dir: '{{ ansible_fqdn }}'
|
||||||
|
letsencrypt_acme_sh_certs_dir: '{{ letsencrypt_acme_sh_base_data_dir }}/certs/{{ letsencrypt_acme_sh_dest_dir }}'
|
||||||
|
letsencrypt_acme_certs_dir: '{{ letsencrypt_acme_sh_certificates_install_path }}'
|
||||||
|
# The various services maintainers need to put the reconfigure/restart scripts there
|
||||||
|
letsencrypt_acme_services_scripts_dir: /usr/lib/acme/hooks
|
||||||
|
letsencrypt_acme_sh_services_scripts_dir: '{{ letsencrypt_acme_services_scripts_dir }}'
|
||||||
|
|
||||||
|
letsencrypt_acme_sh_explicitly_install_certs: True
|
||||||
|
|
||||||
|
# ECC is better, but most old distributions fail on them
|
||||||
|
letsencrypt_acme_sh_use_ecc: False
|
||||||
|
letsencrypt_acme_sh_ecc_key_lenght: ec-384
|
||||||
|
letsencrypt_acme_sh_rsa_key_lenght: 4096
|
||||||
|
letsencrypt_acme_sh_ocsp_must_staple: False
|
||||||
|
letsencrypt_acme_email: sysadmin@example.com
|
||||||
|
letsencrypt_acme_sh_email: '{{ letsencrypt_acme_email }}'
|
||||||
|
letsencrypt_acme_standalone_port: 4402
|
||||||
|
letsencrypt_acme_sh_standalone_port: '{{ letsencrypt_acme_standalone_port }}'
|
||||||
|
letsencrypt_acme_cron_day_of_month: '*'
|
||||||
|
letsencrypt_acme_cron_hour: '{{ range(1, 4) | random }}'
|
||||||
|
letsencrypt_acme_cron_minute: '{{ range(0, 59) | random }}'
|
||||||
|
letsencrypt_acme_services_hook_script: /usr/local/bin/acme-services-hook
|
||||||
|
|
||||||
|
# Use this when you want a single certificate. Even when multiple provider methods are needed
|
||||||
|
# The dns_provider and standalone options are mutually exclusive
|
||||||
|
letsencrypt_acme_sh_domains:
|
||||||
|
- { domain: '{{ ansible_fqdn }}', standalone: True }
|
||||||
|
|
||||||
|
letsencrypt_acme_sh_domains_install:
|
||||||
|
- { domain: '{{ letsencrypt_acme_sh_certificates_install_dir }}', ecc: '{{ letsencrypt_acme_sh_use_ecc }}', cert_file: '{{ letsencrypt_acme_sh_certificates_install_path }}/cert', key_file: '{{ letsencrypt_acme_sh_certificates_install_path }}/privkey', fullchain_file: '{{ letsencrypt_acme_sh_certificates_install_path }}/fullchain' }
|
||||||
|
|
||||||
|
### Stuff related to the obsolete acmetool package. Needed to cleanup systems where it was installed in the past
|
||||||
|
letsencrypt_acme_ppa_repo: 'ppa:hlandau/rhea'
|
||||||
|
letsencrypt_acme_debian_repo: 'deb http://ppa.launchpad.net/hlandau/rhea/ubuntu xenial main'
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ -f "/etc/default/acme_sh_request_env" ] ; then
|
||||||
|
. "/etc/default/acme_sh_request_env"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$ACME_SH_ENV_FILE" ] ; then
|
||||||
|
. "$ACME_SH_ENV_FILE"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
$ACME_SH_BIN --cron --home "$ACME_SH_BINDIR" --config-home "$ACME_SH_CONFIG_HOME" > "$ACME_SH_CRON_LOG_FILE" 2>&1
|
||||||
|
|
||||||
|
exit $?
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ -f "/etc/default/acme_sh_request_env" ] ; then
|
||||||
|
. "/etc/default/acme_sh_request_env"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$ACME_SH_ENV_FILE" ] ; then
|
||||||
|
. "$ACME_SH_ENV_FILE"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
chown -R acme:acme "$ACME_SH_HOME"
|
||||||
|
if [ "$ACME_SH_HTTP_BIND_PORT" -eq 80 ] && [ "$ACME_SH_USE_DNS_PROVIDER" == "False" ] ; then
|
||||||
|
/usr/local/bin/acme-sh-cron-command
|
||||||
|
chown -R acme:acme "$ACME_SH_HOME"
|
||||||
|
else
|
||||||
|
sudo -u acme -s /bin/bash /usr/local/bin/acme-sh-cron-command
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ACME_SH_INSTALL_CERTS" == "True" ] ; then
|
||||||
|
$ACME_SH_BIN $ACME_SH_INSTALL_CERT_REQUEST > "$ACME_SH_INSTALL_LOG_FILE" 2>&1
|
||||||
|
chown -R acme:acme "$ACME_SH_HOME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $?
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ -f "/etc/default/acme_sh_request_env" ] ; then
|
||||||
|
. "/etc/default/acme_sh_request_env"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$ACME_SH_GIT_DIST_DIR"
|
||||||
|
./acme.sh $ACME_SH_INSTALL_OPTS
|
||||||
|
|
||||||
|
exit $?
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ -f "/etc/default/acme_sh_request_env" ] ; then
|
||||||
|
. "/etc/default/acme_sh_request_env"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$ACME_SH_ENV_FILE" ] ; then
|
||||||
|
. "$ACME_SH_ENV_FILE"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d "$ACME_SH_HOME/keys/fakeselfsignedcert" ] && [ -d "$ACME_SH_HOME/certs/fakeselfsignedcert" ] ; then
|
||||||
|
rm -fr "$ACME_SH_HOME/keys"
|
||||||
|
rm -fr "$ACME_SH_HOME/certs"
|
||||||
|
fi
|
||||||
|
|
||||||
|
$ACME_SH_BIN $ACME_SH_INSTALL_CERT_REQUEST > "$ACME_SH_INSTALL_LOG_FILE" 2>&1
|
||||||
|
chown -R acme:acme "$ACME_SH_HOME"
|
||||||
|
|
||||||
|
exit $?
|
|
@ -0,0 +1,55 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ $# -ne 1 ] ; then
|
||||||
|
ACME_SH_ENV_FILE="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "/etc/default/acme_sh_request_env" ] ; then
|
||||||
|
. "/etc/default/acme_sh_request_env"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$ACME_SH_ENV_FILE" ] && [ -f "$ACME_SH_ENV_FILE" ] ; then
|
||||||
|
. "$ACME_SH_ENV_FILE"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
RETVAL=
|
||||||
|
|
||||||
|
if [ ! -f "$ACME_SH_CONFIG_HOME/ok_certificate_issued" ] && [ "$ACME_SH_USE_DNS_PROVIDER" == "False" ] ; then
|
||||||
|
# First request. Try to shut down all the services running on port 80
|
||||||
|
if [ -x /bin/systemctl ] ; then
|
||||||
|
/bin/systemctl stop nginx >/dev/null 2>&1
|
||||||
|
/bin/systemctl stop apache2 >/dev/null 2>&1
|
||||||
|
/bin/systemctl stop httpd >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
service nginx stop
|
||||||
|
service apache2 stop
|
||||||
|
service httpd stop
|
||||||
|
fi
|
||||||
|
$ACME_SH_BIN $ACME_SH_FIRST_CERT_REQUEST > "$ACME_SH_ISSUE_LOG_FILE" 2>&1
|
||||||
|
RETVAL=$?
|
||||||
|
if [ -x /bin/systemctl ] ; then
|
||||||
|
/bin/systemctl start nginx >/dev/null 2>&1
|
||||||
|
/bin/systemctl start apache2 >/dev/null 2>&1
|
||||||
|
/bin/systemctl start httpd >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
service nginx start
|
||||||
|
service apache2 start
|
||||||
|
service httpd start
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
$ACME_SH_BIN $ACME_SH_ISSUE_CERT_REQUEST > "$ACME_SH_ISSUE_LOG_FILE" 2>&1
|
||||||
|
RETVAL=$?
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $RETVAL -eq 0 ] ; then
|
||||||
|
touch "$ACME_SH_CONFIG_HOME/ok_certificate_issued"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $RETVAL -eq 2 ] ; then
|
||||||
|
# There is a valid certificate already
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
exit $RETVAL
|
|
@ -1,2 +1,7 @@
|
||||||
---
|
---
|
||||||
# handlers file for ansible-role-template
|
- name: Install the requested certificates
|
||||||
|
shell: /usr/local/bin/acme-sh-install-certs
|
||||||
|
when:
|
||||||
|
- letsencrypt_acme_sh_explicitly_install_certs
|
||||||
|
- acme_sh_certificate_issued is changed
|
||||||
|
|
||||||
|
|
|
@ -1,61 +1,25 @@
|
||||||
galaxy_info:
|
galaxy_info:
|
||||||
author: your name
|
author: Andrea Dell'Amico
|
||||||
description: your description
|
description: Systems Architect
|
||||||
company: ISTI-CNR
|
company: ISTI-CNR
|
||||||
|
|
||||||
# If the issue tracker for your role is not on github, uncomment the
|
|
||||||
# next line and provide a value
|
|
||||||
issue_tracker_url: https://redmine-s2i2s.isti.cnr.it/projects/provisioning
|
issue_tracker_url: https://redmine-s2i2s.isti.cnr.it/projects/provisioning
|
||||||
|
|
||||||
# Some suggested licenses:
|
|
||||||
# - BSD (default)
|
|
||||||
# - MIT
|
|
||||||
# - GPLv2
|
|
||||||
# - GPLv3
|
|
||||||
# - Apache
|
|
||||||
# - CC-BY
|
|
||||||
license: EUPL 1.2+
|
license: EUPL 1.2+
|
||||||
|
|
||||||
min_ansible_version: 2.8
|
min_ansible_version: 2.8
|
||||||
|
|
||||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
|
||||||
# min_ansible_container_version:
|
|
||||||
|
|
||||||
# Optionally specify the branch Galaxy will use when accessing the GitHub
|
|
||||||
# repo for this role. During role install, if no tags are available,
|
|
||||||
# Galaxy will use this branch. During import Galaxy will access files on
|
|
||||||
# this branch. If Travis integration is configured, only notifications for this
|
|
||||||
# branch will be accepted. Otherwise, in all cases, the repo's default branch
|
|
||||||
# (usually master) will be used.
|
|
||||||
#github_branch:
|
|
||||||
|
|
||||||
#
|
|
||||||
# Provide a list of supported platforms, and for each platform a list of versions.
|
|
||||||
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
|
|
||||||
# To view available platforms and versions (or releases), visit:
|
# To view available platforms and versions (or releases), visit:
|
||||||
# https://galaxy.ansible.com/api/v1/platforms/
|
# https://galaxy.ansible.com/api/v1/platforms/
|
||||||
#
|
#
|
||||||
# platforms:
|
platforms:
|
||||||
# - name: Fedora
|
- name: Ubuntu
|
||||||
# versions:
|
versions:
|
||||||
# - all
|
- bionic
|
||||||
# - 25
|
- name: EL
|
||||||
# - name: SomePlatform
|
versions:
|
||||||
# versions:
|
- 7
|
||||||
# - all
|
- 8
|
||||||
# - 1.0
|
|
||||||
# - 7
|
|
||||||
# - 99.99
|
|
||||||
|
|
||||||
galaxy_tags: []
|
|
||||||
# List tags for your role here, one per line. A tag is a keyword that describes
|
|
||||||
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
|
||||||
# remove the '[]' above, if you add tags to this list.
|
|
||||||
#
|
|
||||||
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
|
||||||
# Maximum 20 tags per role.
|
|
||||||
|
|
||||||
dependencies: []
|
|
||||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
|
||||||
# if you add dependencies to this list.
|
|
||||||
|
|
||||||
|
galaxy_tags:
|
||||||
|
- letsencrypt
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
- block:
|
||||||
|
- name: Remove the old acme package because the tool is not supported anymore.
|
||||||
|
apt: pkg=acmetool state=absent purge=yes
|
||||||
|
|
||||||
|
- name: Remove the old letsencrypt acmetool repo on ubuntu
|
||||||
|
apt_repository: repo={{ letsencrypt_acme_ppa_repo }} state=absent update_cache=yes
|
||||||
|
|
||||||
|
- name: Remove the old letsencrypt acmetool repo on debian
|
||||||
|
apt_repository: repo={{ letsencrypt_acme_debian_repo }} state=absent update_cache=yes
|
||||||
|
|
||||||
|
- name: Install the socat utility, needed when using the http protocols to request the certificates
|
||||||
|
apt: pkg=socat state=present cache_valid_time=1800
|
||||||
|
|
||||||
|
- name: Install the git client if we are installing using git
|
||||||
|
apt: pkg=git state=present cache_valid_time=1800
|
||||||
|
when: letsencrypt_acme_sh_git_install
|
||||||
|
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_acme_sh' ]
|
|
@ -0,0 +1,15 @@
|
||||||
|
- block:
|
||||||
|
- name: Remove the old acme package because the tool is not supported anymore.
|
||||||
|
yum: pkg=acmetool state=absent
|
||||||
|
|
||||||
|
- name: Remove the acmetool repo file
|
||||||
|
file: dest=/etc/yum.repos.d/hlandau-acmetool-epel-7.repo state=absent
|
||||||
|
|
||||||
|
- name: Install the socat utility, needed when using the http protocols to request the certificates
|
||||||
|
yum: pkg=socat state=present
|
||||||
|
|
||||||
|
- name: Install the git client if we are installing using git
|
||||||
|
yum: pkg=git state=present
|
||||||
|
when: letsencrypt_acme_sh_git_install
|
||||||
|
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_acme_sh' ]
|
133
tasks/main.yml
133
tasks/main.yml
|
@ -1,2 +1,133 @@
|
||||||
---
|
---
|
||||||
# tasks file for ansible-role-template
|
- import_tasks: acmetool_deb.yml
|
||||||
|
when: ansible_distribution_file_variety == "Debian"
|
||||||
|
|
||||||
|
- import_tasks: acmetool_rh.yml
|
||||||
|
when: ansible_distribution_file_variety == "RedHat"
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Remove the sudoers config needed to run the old acmetool package hooks
|
||||||
|
file: dest=/etc/sudoers.d/letsencrypt-acme state=absent
|
||||||
|
|
||||||
|
- name: Remove the old acmetool script that requested certificates
|
||||||
|
file: dest=/usr/local/bin/acme-cert-request state=absent
|
||||||
|
|
||||||
|
- name: Remove the old letsencrypt cron job
|
||||||
|
cron: name="Letsencrypt certificate renewal" user={{ letsencrypt_acme_user }} state=absent
|
||||||
|
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_acme_sh' ]
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Create the letsencrypt acme user
|
||||||
|
user: name={{ letsencrypt_acme_sh_user }} home={{ letsencrypt_acme_sh_user_home }} createhome=no shell=/usr/sbin/nologin system=yes
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_user' ]
|
||||||
|
|
||||||
|
- name: Create the letsencrypt acme home, if it does not exist already. In a separate step because it could be already there.
|
||||||
|
file: dest={{ letsencrypt_acme_sh_user_home }} owner={{ letsencrypt_acme_sh_user }} group={{ letsencrypt_acme_sh_user }} state=directory recurse=yes
|
||||||
|
|
||||||
|
- name: Create a directory where to put the cron job and hooks logs
|
||||||
|
file: dest={{ letsencrypt_acme_sh_log_dir }} state=directory owner={{ letsencrypt_acme_sh_user }} group={{ letsencrypt_acme_sh_user }} mode=0750
|
||||||
|
|
||||||
|
- name: Install the acme.sh environment variables file
|
||||||
|
template: src=acme_sh_request_env.j2 dest=/etc/default/acme_sh_request_env owner=root group=root mode=0444
|
||||||
|
register: acme_sh_issue
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_cron', 'letsencrypt_acme_sh', 'letsencrypt_acme_sh_env' ]
|
||||||
|
|
||||||
|
- name: Install the script that initializes the acme.sh environment
|
||||||
|
copy: src=acme-sh-install dest=/usr/local/bin/acme-sh-install owner=root group=acme mode=0750
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_cron', 'letsencrypt_acme_sh', 'letsencrypt_acme_sh_scripts' ]
|
||||||
|
|
||||||
|
- name: Install a script that issues the certificates
|
||||||
|
copy: src=acme-sh-request-cert dest=/usr/local/bin/acme-sh-request-cert owner=root group=acme mode=0750
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_cron', 'letsencrypt_acme_sh', 'letsencrypt_acme_sh_scripts' ]
|
||||||
|
|
||||||
|
- name: Install a script that installs the issued certificates
|
||||||
|
copy: src=acme-sh-install-certs dest=/usr/local/bin/acme-sh-install-certs owner=root group=acme mode=0750
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_cron', 'letsencrypt_acme_sh', 'letsencrypt_acme_sh_scripts' ]
|
||||||
|
|
||||||
|
- name: Install the script that will run the services hooks when a certificate is installed
|
||||||
|
template: src=acme-services-hook.j2 dest=/usr/local/bin/acme-services-hook owner=root group=acme mode=0750
|
||||||
|
|
||||||
|
- name: Install the scripts that will be run as a cron job
|
||||||
|
copy: src={{ item }} dest=/usr/local/bin/{{ item }} owner=root group=acme mode=0750
|
||||||
|
with_items:
|
||||||
|
- acme-sh-cron-script
|
||||||
|
- acme-sh-cron-command
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_cron', 'letsencrypt_acme_sh', 'letsencrypt_acme_sh_scripts' ]
|
||||||
|
|
||||||
|
- name: Install a daily cron job to renew the certificates when needed. It runs as root
|
||||||
|
cron: name="Letsencrypt certificate renewal" day={{ letsencrypt_acme_cron_day_of_month }} hour={{ letsencrypt_acme_cron_hour }} minute={{ letsencrypt_acme_cron_minute }} job="/usr/local/bin/acme-sh-cron-script > {{ letsencrypt_acme_sh_log_dir }}/acme-cron.log 2>&1"
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_cron', 'letsencrypt_acme_sh', 'letsencrypt_acme_sh_scripts' ]
|
||||||
|
|
||||||
|
when: letsencrypt_acme_sh_install | bool
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_acme_sh' ]
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Download the acme.sh distribution
|
||||||
|
git: repo={{ letsencrypt_acme_sh_git_url }} dest={{ letsencrypt_acme_git_dest_dir }} recursive=yes update=yes
|
||||||
|
|
||||||
|
- name: Create the letsencrypt acme.sh directory tree
|
||||||
|
file: dest={{ item }} state=directory mode=0755
|
||||||
|
with_items: '{{ letsencrypt_acme_sh_dirs }}'
|
||||||
|
|
||||||
|
- name: Run the installation command for acme.sh
|
||||||
|
shell: /usr/local/bin/acme-sh-install
|
||||||
|
args:
|
||||||
|
creates: '{{ letsencrypt_acme_sh_user_home }}/bin/acme.sh'
|
||||||
|
|
||||||
|
- name: Create the letsencrypt acme.sh account configuration
|
||||||
|
template: src=account.conf.j2 dest={{ letsencrypt_acme_sh_base_data_dir }}/data/account.conf mode=0640
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_account_conf', 'letsencrypt_acme_sh' ]
|
||||||
|
|
||||||
|
- name: Remove the daily cron job that run as acme user.
|
||||||
|
cron: name="Letsencrypt certificate renewal" day={{ letsencrypt_acme_cron_day_of_month }} hour={{ letsencrypt_acme_cron_hour }} minute={{ letsencrypt_acme_cron_minute }} job="/usr/local/bin/acme-sh-cron-script > {{ letsencrypt_acme_sh_log_dir }}/acme-cron.log 2>&1" state=absent
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_cron', 'letsencrypt_acme_sh' ]
|
||||||
|
|
||||||
|
become: True
|
||||||
|
become_user: '{{ letsencrypt_acme_sh_user }}'
|
||||||
|
when: letsencrypt_acme_sh_install | bool
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_acme_sh' ]
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Remove the ok_certificate_issued file when the env file has been changed so that we can force a new request
|
||||||
|
file: dest={{ letsencrypt_acme_sh_base_data_dir }}/data/ok_certificate_issued state=absent
|
||||||
|
when: acme_sh_issue is changed
|
||||||
|
|
||||||
|
- name: Request the certificates. As root because we must bind on port 80
|
||||||
|
shell: /usr/local/bin/acme-sh-request-cert
|
||||||
|
args:
|
||||||
|
creates: '{{ letsencrypt_acme_sh_base_data_dir }}/data/ok_certificate_issued'
|
||||||
|
register: acme_sh_certificate_issued
|
||||||
|
ignore_errors: True
|
||||||
|
|
||||||
|
- name: Check if the 'live' path is a symling. It is, if acmetool was installed
|
||||||
|
stat: path={{ letsencrypt_acme_sh_certificates_install_path }}
|
||||||
|
register: is_symlink
|
||||||
|
|
||||||
|
- name: Remove the 'live' path if it was a symlink
|
||||||
|
file: dest={{ letsencrypt_acme_sh_certificates_install_path }} state=absent
|
||||||
|
when: is_symlink.stat.islnk is defined and is_symlink.stat.islnk
|
||||||
|
|
||||||
|
- name: Create the certificates installation directory
|
||||||
|
file: dest={{ letsencrypt_acme_sh_certificates_install_path }} state=directory owner=root group=root mode=0755
|
||||||
|
|
||||||
|
- name: Install the certificates
|
||||||
|
shell: /usr/local/bin/acme-sh-install-certs
|
||||||
|
when:
|
||||||
|
- letsencrypt_acme_sh_explicitly_install_certs | bool
|
||||||
|
- acme_sh_certificate_issued is defined
|
||||||
|
- acme_sh_certificate_issued is changed
|
||||||
|
ignore_errors: True
|
||||||
|
|
||||||
|
- name: Fix the http port in the configuration. Needed when we renew using the http protocol and we are behind a web server
|
||||||
|
lineinfile:
|
||||||
|
path: '{{ letsencrypt_acme_sh_certs_data_path }}/{{ letsencrypt_acme_sh_certs_data_prefix }}.conf'
|
||||||
|
create: no
|
||||||
|
state: present
|
||||||
|
regexp: "^Le_HTTPPort="
|
||||||
|
line: "Le_HTTPPort='{{ letsencrypt_acme_standalone_port }}'"
|
||||||
|
when: not letsencrypt_acme_sh_use_dns_provider | bool
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_acme_sh', 'letsencrypt_acme_sh_http_port' ]
|
||||||
|
|
||||||
|
when: letsencrypt_acme_sh_install | bool
|
||||||
|
tags: [ 'letsencrypt', 'letsencrypt_acme_sh' ]
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
{% if letsencrypt_acme_sh_log_enabled %}
|
||||||
|
LOG_FILE="{{ letsencrypt_acme_sh_base_data_dir }}/logs/cert_request.log"
|
||||||
|
LOG_LEVEL=1
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if letsencrypt_acme_sh_auto_upgrade %}
|
||||||
|
AUTO_UPGRADE="1"
|
||||||
|
{% endif %}
|
||||||
|
#NO_TIMESTAMP=1
|
||||||
|
|
||||||
|
CERT_HOME='{{ letsencrypt_acme_sh_base_data_dir }}/certs'
|
||||||
|
ACCOUNT_EMAIL='{{ letsencrypt_acme_sh_email }}'
|
||||||
|
|
||||||
|
{% if letsencrypt_acme_sh_use_dns_provider %}
|
||||||
|
{% if letsencrypt_acme_sh_dns_provider_type == 'dns_pdns' %}
|
||||||
|
PDNS_Url="{{ letsencrypt_acme_sh_dns_api_url }}"
|
||||||
|
PDNS_ServerId="{{ letsencrypt_acme_sh_dns_api_provider_id }}"
|
||||||
|
PDNS_Token="{{ letsencrypt_acme_sh_dns_api_token }}"
|
||||||
|
PDNS_Ttl=180
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
ACME_LETSENCRYPT_HOOKS_DIR=/usr/lib/acme/hooks
|
||||||
|
|
||||||
|
if [ -f "/etc/default/acme_sh_request_env" ] ; then
|
||||||
|
source "/etc/default/acme_sh_request_env"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for script in "${ACME_LETSENCRYPT_HOOKS_DIR}"/* ; do
|
||||||
|
if [ -x "$script" ] ; then
|
||||||
|
$script
|
||||||
|
fi
|
||||||
|
done
|
|
@ -0,0 +1,65 @@
|
||||||
|
#
|
||||||
|
# Globals
|
||||||
|
#
|
||||||
|
ACME_SH_HOME={{ letsencrypt_acme_sh_user_home }}
|
||||||
|
ACME_SH_BINDIR={{ letsencrypt_acme_sh_user_home }}/bin
|
||||||
|
ACME_SH_BIN="{{ letsencrypt_acme_sh_user_home }}/bin/acme.sh --config-home {{ letsencrypt_acme_sh_base_data_dir }}/data"
|
||||||
|
ACME_SH_CONFIG_HOME={{ letsencrypt_acme_sh_base_data_dir }}/data
|
||||||
|
ACME_SH_ENV_FILE=${ACME_SH_BINDIR}/acme.sh.env
|
||||||
|
ACME_SH_ISSUE_LOG_FILE={{ letsencrypt_acme_sh_base_data_dir }}/logs/cert_issue.log
|
||||||
|
ACME_SH_CRON_LOG_FILE={{ letsencrypt_acme_sh_base_data_dir }}/logs/cron.log
|
||||||
|
ACME_SH_INSTALL_LOG_FILE={{ letsencrypt_acme_sh_log_dir }}/cert_install.log
|
||||||
|
ACME_SH_GIT_DIST_DIR={{ letsencrypt_acme_git_dest_dir }}
|
||||||
|
ACME_LETSENCRYPT_HOOKS_DIR={{ letsencrypt_acme_services_scripts_dir }}
|
||||||
|
ACME_SH_HTTP_BIND_PORT={{ letsencrypt_acme_standalone_port }}
|
||||||
|
ACME_SH_USE_DNS_PROVIDER="{{ letsencrypt_acme_sh_use_dns_provider }}"
|
||||||
|
|
||||||
|
ACME_SH_INSTALL_CERTS={{ letsencrypt_acme_sh_explicitly_install_certs }}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Install options
|
||||||
|
#
|
||||||
|
ACME_SH_INSTALL_OPTS="{{ letsencrypt_acme_sh_install_options }}"
|
||||||
|
{% if not letsencrypt_acme_sh_install_cron %}
|
||||||
|
ACME_SH_INSTALL_OPTS="$ACME_SH_INSTALL_OPTS --nocron"
|
||||||
|
{% endif %}
|
||||||
|
ACME_SH_INSTALL_OPTS="$ACME_SH_INSTALL_OPTS --home {{ letsencrypt_acme_sh_user_home }}/bin --config-home {{ letsencrypt_acme_sh_base_data_dir }}/data --certhome {{ letsencrypt_acme_sh_base_data_dir }}/certs --log {{ letsencrypt_acme_sh_base_data_dir }}/logs/acme.sh.log"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Certificate issue options
|
||||||
|
#
|
||||||
|
ACME_SH_ISSUE_CERT_REQUEST_OPTIONS="--issue -k {% if letsencrypt_acme_sh_use_ecc %}{{ letsencrypt_acme_sh_ecc_key_lenght }}{% else %}{{ letsencrypt_acme_sh_rsa_key_lenght }}{% endif %} --log {{ letsencrypt_acme_sh_base_data_dir }}/logs/acme.sh.log"
|
||||||
|
{% if letsencrypt_acme_sh_ocsp_must_staple %}
|
||||||
|
ACME_SH_ISSUE_CERT_REQUEST="$ACME_SH_ISSUE_CERT_REQUEST_OPTIONS --ocsp"
|
||||||
|
{% endif %}
|
||||||
|
{% if letsencrypt_acme_sh_use_syslog %}
|
||||||
|
ACME_SH_ISSUE_CERT_REQUEST="$ACME_SH_ISSUE_CERT_REQUEST_OPTIONS --syslog {{ letsencrypt_acme_sh_syslog_level }}"
|
||||||
|
{% endif %}
|
||||||
|
{% if letsencrypt_acme_sh_test_request %}
|
||||||
|
ACME_SH_ISSUE_CERT_REQUEST="$ACME_SH_ISSUE_CERT_REQUEST_OPTIONS --test"
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
ACME_SH_ISSUE_CERT_DOMAINS="{% for dom in letsencrypt_acme_sh_domains %} -d {{ dom.domain }} {% if dom.dns_provider is defined %} --dns {{ dom.dns_provider }} {% if dom.dns_alias_challenge is defined %} --challenge-alias {{ dom.dns_alias_challenge }} {% endif %} {% endif %} {% if dom.standalone is defined %} --standalone --httpport {{ letsencrypt_acme_standalone_port }} {% endif %} {% endfor %}"
|
||||||
|
|
||||||
|
ACME_SH_FIRST_REQUEST_CERT_DOMAINS="{% for dom in letsencrypt_acme_sh_domains %} -d {{ dom.domain }} {% if dom.dns_provider is defined %} --dns {{ dom.dns_provider }} {% if dom.dns_alias_challenge is defined %} --challenge-alias {{ dom.dns_alias_challenge }} {% endif %} {% endif %} {% if dom.standalone is defined %} --standalone --httpport 80 {% endif %} {% endfor %}"
|
||||||
|
|
||||||
|
# The complete command line to issue a certificate
|
||||||
|
ACME_SH_ISSUE_CERT_REQUEST="$ACME_SH_ISSUE_CERT_REQUEST_OPTIONS $ACME_SH_ISSUE_CERT_DOMAINS"
|
||||||
|
|
||||||
|
# The complete command line to issue a certificate. The first time we have to use port 80 when not using the dns protocol
|
||||||
|
ACME_SH_FIRST_CERT_REQUEST="$ACME_SH_ISSUE_CERT_REQUEST_OPTIONS --force $ACME_SH_FIRST_REQUEST_CERT_DOMAINS"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Certificate install options
|
||||||
|
#
|
||||||
|
ACME_SH_INSTALL_CERT_REQUEST="--install-cert"
|
||||||
|
{% if letsencrypt_acme_sh_use_ecc %}
|
||||||
|
ACME_SH_INSTALL_CERT_REQUEST="$ACME_SH_INSTALL_CERT_REQUEST --ecc"
|
||||||
|
{% endif %}
|
||||||
|
{% if letsencrypt_acme_sh_use_syslog %}
|
||||||
|
ACME_SH_INSTALL_CERT_REQUEST="$ACME_SH_INSTALL_CERT_REQUEST --syslog {{ letsencrypt_acme_sh_syslog_level }}"
|
||||||
|
{% endif %}
|
||||||
|
ACME_SH_INSTALL_CERT_DOMAINS="{% for dom in letsencrypt_acme_sh_domains_install %} -d {{ dom.domain }} --cert-file {{ dom.cert_file }} --key-file {{ dom.key_file }} --fullchain-file {{ dom.fullchain_file }} --reloadcmd {{ dom.reloadcmd | default('/usr/local/bin/acme-services-hook') }} {% endfor %}"
|
||||||
|
|
||||||
|
# The complete command line to install a certificate. Run as root
|
||||||
|
ACME_SH_INSTALL_CERT_REQUEST="$ACME_SH_INSTALL_CERT_REQUEST $ACME_SH_INSTALL_CERT_DOMAINS"
|
Loading…
Reference in New Issue