diff --git a/acmebot/defaults/main.yml b/acmebot/defaults/main.yml index edc0c9607e632df0bd0e3ae5bc4884bac472b012..23557df45181fc1e71f8d25967a6759909185f7a 100644 --- a/acmebot/defaults/main.yml +++ b/acmebot/defaults/main.yml @@ -1,7 +1,8 @@ --- acmebot_account_mail: "{{ adminaddr }}" -acmebot_after_nginx_proxy: true +acmebot_version: "v2.6.0" +acmebot_enable_update_check: true acmebot_settings: {} acmebot_default_settings: @@ -20,9 +21,8 @@ acmebot_default_settings: - "google_pilot" file_user: root - file_group: ssl-cert + file_group: root - # TODO default to both key types or single one? default to non-/custom params? key_size: 4096 # null to turn off RSA certificates key_curve: "secp384r1" # null to turn off ECDSA certificates key_cipher: null @@ -63,12 +63,11 @@ acmebot_default_key_suffixes: # set to null for specified certs to use dns-01 for those acmebot_directories: {} acmebot_default_directories: - pid: "/run" + pid: "/run/acmebot" log: "/var/log/acmebot" resource: "/var/lib/acmebot" temp: null - # TODO layout equivalent to acmetool private_key: /etc/ssl/acmebot/privkey backup_key: /etc/ssl/acmebot/backup_privkey previous_key: null @@ -78,7 +77,7 @@ acmebot_default_directories: chain: /etc/ssl/acmebot/chain # maybe null param: /etc/ssl/acmebot/params # maybe null challenge: /etc/ssl/acmebot/challenges # for dns-01 only - http_challenge: /var/www/acme-challenge # maybe null + http_challenge: "/var/run/acme/acme-challenge" # maybe null hpkp: /etc/ssl/acmebot/hpkp # maybe null ocsp: /etc/ssl/acmebot/ocsp # maybe null sct: "/etc/ssl/acmebot/scts/{name}/{key_type}" # maybe null @@ -90,13 +89,12 @@ acmebot_file_names: {} acmebot_default_file_names: log: "acmebot.log" - # TODO layout equivalent to acmetool - private_key: "{name}{suffix}.key" - backup_key: "{name}_backup{suffix}.key" - previous_key: "{name}_previous{suffix}.key" - full_key: "{name}_full{suffix}.key" + private_key: "{name}{suffix}.pem" + backup_key: "{name}_backup{suffix}.pem" + previous_key: "{name}_previous{suffix}.pem" + full_key: "{name}_full{suffix}.pem" certificate: "{name}{suffix}.pem" - full_certificate: "{name}+root{suffix}.pem" + full_certificate: "{name}{suffix}.pem" chain: "{name}_chain{suffix}.pem" param: "{name}_param.pem" challenge: "{name}" diff --git a/acmebot/files/acmebot.service b/acmebot/files/acmebot.service new file mode 100644 index 0000000000000000000000000000000000000000..8ba466a125cd0a880db8176db4235146dc5da4a4 --- /dev/null +++ b/acmebot/files/acmebot.service @@ -0,0 +1,26 @@ +[Unit] +Description=Reconcile Let's Encrypt certificates +Documentation=file:/usr/share/doc/acmebot/README.rst.gz +After=nss-lookup.target +After=apache2.service nginx.service bind9.service nginx-proxy.service + +[Service] +Type=oneshot +ExecStart=/usr/local/sbin/acmebot --accept +TimeoutStartSec=5min +CapabilityBoundingSet=CAP_CHOWN +NoNewPrivileges=yes +PrivateTmp=yes +PrivateDevices=yes +ProtectSystem=strict +ReadWritePaths=/etc/ssl +ConfigurationDirectory=acmebot +RuntimeDirectory=acmebot acme/acme-challenge +StateDirectory=acmebot +LogsDirectory=acmebot +ProtectHome=yes +ProtectKernelTunables=yes +ProtectControlGroups=yes +RestrictRealtime=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 + diff --git a/acmebot/files/acmebot.timer b/acmebot/files/acmebot.timer new file mode 100644 index 0000000000000000000000000000000000000000..02c80b10717fd691b3ac907e02a27482122e2ad1 --- /dev/null +++ b/acmebot/files/acmebot.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Reconcile Let's Encrypt certificates twice daily + +[Timer] +OnCalendar=*-*-* 00,12:00:00 +RandomizedDelaySec=1h +Persistent=yes + +[Install] +WantedBy=timers.target + diff --git a/acmebot/files/service-after.conf b/acmebot/files/service-after.conf deleted file mode 100644 index a54ec72b702a5b82200d813310d1f8f5fc2fe5e0..0000000000000000000000000000000000000000 --- a/acmebot/files/service-after.conf +++ /dev/null @@ -1,2 +0,0 @@ -[Unit] -After=nginx-proxy.service diff --git a/acmebot/tasks/main.yml b/acmebot/tasks/main.yml index 5cb2fcbf697848da27409c1507037ec90f6d46bc..dfb7b45ae7ddbdc6d540558c624b153d5ed7f43f 100644 --- a/acmebot/tasks/main.yml +++ b/acmebot/tasks/main.yml @@ -1,40 +1,53 @@ --- -# TODO import account info from acmetool if present -- name: ensure acmebot is installed +- name: ensure requirements for acmebot are installed apt: - name: acmebot + name: + - python3-appdirs + - python3-pyparsing + - python3-packaging + - python3-openssl + - python3-dns + - python3-cryptography + - python3-asn1crypto + - python3-acme + - python3-yaml state: present -- name: ensure we can modify the systemd unit +- name: get the acmebot repository + git: + repo: https://github.com/plinss/acmebot.git + dest: /opt/acmebot + version: "{{acmebot_version}}" + environment: + TMPDIR: /root/.ansible/tmp + +- name: add acmebot to path file: - path: /etc/systemd/system/acmebot.service.d - state: directory - owner: root - group: root - mode: '0755' - notify: - - reload systemd service files - when: acmebot_after_nginx_proxy + src: /opt/acmebot/acmebot + dest: /usr/local/sbin/acmebot + state: link -- name: ensure systemd waits for proxy service +- name: install systemd units copy: - src: service-after.conf - dest: /etc/systemd/system/acmebot.service.d/nginx-proxy.conf + src: "{{item}}" + dest: /etc/systemd/system/ owner: root group: root mode: '0644' + with_items: + - "acmebot.service" + - "acmebot.timer" notify: - reload systemd service files - when: acmebot_after_nginx_proxy -- name: ensure systemd does not wait for proxy service +- name: create the acmebot config directory file: - path: /etc/systemd/system/acmebot.service.d/nginx-proxy.conf - state: absent - notify: - - reload systemd service files - when: not acmebot_after_nginx_proxy + path: /etc/acmebot + state: directory + owner: root + group: root + mode: '0755' - name: ensure the acmebot is configured template: @@ -57,27 +70,28 @@ notify: - update certificates -# TODO initial run accepting TOS -- name: check if acmebot is configured - command: acmetool status - register: acmetool_status - changed_when: false -- name: initially configure acmebot - command: acmebot --detail - when: not acmetool_status.stdout is search(acmetool_endpoint) - -# TODO force run when cert store does not match configured certificates -- name: test if the desired certificates are present - stat: - path: "/var/lib/acme/live/{{item.hostnames[0]}}" - register: live_stat - changed_when: not live_stat.stat.exists - with_items: "{{acmetool_certificates}}" - notify: - - update certificates - - name: ensure certificates are updated regularly systemd: name: acmebot.timer enabled: true state: started + +- name: check for updates daily + file: + src: /opt/acmebot/update-check.sh + dest: /etc/cron.daily/acmebot-update-check.sH + state: link + when: acmebot_enable_update_check + +- name: don't check for updates daily + file: + path: /etc/cron.daily/acmebot-update-check.sh + state: absent + when: not acmebot_enable_update_check + +- name: rotate acmebot logs + file: + src: /opt/acmebot/logrotate.d/acmebot + dest: /etc/logrotate.d/acmebot + state: link + diff --git a/webserver/templates/ssl-certificate b/webserver/templates/ssl-certificate index 87bcc8a80c297879bce1bac8f06437a77fd98612..5ddb5e2de9081cc0696d42b3ca804ca8b30a081a 100644 --- a/webserver/templates/ssl-certificate +++ b/webserver/templates/ssl-certificate @@ -1,6 +1,6 @@ - ssl_certificate {{server.certificate|default("/var/lib/acme/live/" + server.server_name + "/fullchain")}}; - ssl_trusted_certificate {{server.certificate|default("/var/lib/acme/live/" + server.server_name + "/fullchain")}}; - ssl_certificate_key {{server.private_key|default("/var/lib/acme/live/" + server.server_name + "/privkey")}}; + ssl_certificate {{server.certificate|default("/etc/ssl/acmebot/cert/" + server.server_name + ".pem")}}; + ssl_trusted_certificate {{server.certificate|default("/etc/ssl/acmebot/cert/" + server.server_name + ".pem")}}; + ssl_certificate_key {{server.private_key|default("/etc/ssl/acmebot/privkey/" + server.server_name + ".pem")}}; {% set strength = server.cipher_strength|default(cipher_strength) %} ssl_protocols {{protocols[strength]}};