From d28bdb325871a4c50700dc073a5ac3f32639d9b3 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Sun, 23 Dec 2018 11:00:12 +0200 Subject: [PATCH] Add support for 2 more SSL certificate retrieval methods Adds support for managing certificates manually and for having the playbook generate self-signed certificates for you. With this, Let's Encrypt usage is no longer required. Fixes Github issue #50. --- CHANGELOG.md | 15 +++++ README.md | 2 +- docs/configuring-playbook-own-webserver.md | 4 +- docs/configuring-playbook-ssl-certificates.md | 32 ++++++++++ docs/configuring-playbook.md | 2 + examples/host-vars.yml | 6 +- roles/matrix-server/defaults/main.yml | 31 +++++++--- roles/matrix-server/tasks/setup/main.yml | 2 +- roles/matrix-server/tasks/setup/setup_ssl.yml | 54 ---------------- roles/matrix-server/tasks/setup/ssl/main.yml | 38 ++++++++++++ .../setup/ssl/setup_ssl_lets_encrypt.yml | 61 +++++++++++++++++++ ...up_ssl_lets_encrypt_obtain_for_domain.yml} | 20 +++--- .../setup/ssl/setup_ssl_manually_managed.yml | 8 +++ ...ssl_manually_managed_verify_for_domain.yml | 23 +++++++ .../tasks/setup/ssl/setup_ssl_self_signed.yml | 24 ++++++++ ...etup_ssl_self_signed_obtain_for_domain.yml | 40 ++++++++++++ .../matrix-nginx-proxy-periodic-restarter.j2 | 2 +- .../cron.d/matrix-ssl-certificate-renewal.j2 | 4 +- .../nginx-conf.d/matrix-riot-web.conf.j2 | 2 +- .../nginx-conf.d/matrix-synapse.conf.j2 | 2 +- .../matrix-ssl-certificates-renew.j2 | 10 +-- 21 files changed, 296 insertions(+), 86 deletions(-) create mode 100644 docs/configuring-playbook-ssl-certificates.md delete mode 100644 roles/matrix-server/tasks/setup/setup_ssl.yml create mode 100644 roles/matrix-server/tasks/setup/ssl/main.yml create mode 100644 roles/matrix-server/tasks/setup/ssl/setup_ssl_lets_encrypt.yml rename roles/matrix-server/tasks/setup/{setup_ssl_for_domain.yml => ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml} (79%) create mode 100644 roles/matrix-server/tasks/setup/ssl/setup_ssl_manually_managed.yml create mode 100644 roles/matrix-server/tasks/setup/ssl/setup_ssl_manually_managed_verify_for_domain.yml create mode 100644 roles/matrix-server/tasks/setup/ssl/setup_ssl_self_signed.yml create mode 100644 roles/matrix-server/tasks/setup/ssl/setup_ssl_self_signed_obtain_for_domain.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cfb1d03c..e09290f99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # 2018-12-23 +## More SSL certificate retrieval methods + +The playbook now lets you decide between 3 different SSL certificate retrieval methods: +- (default) obtaining free SSL certificates from Let's Encrypt +- generating self-signed SSL certificates +- managing SSL certificates manually + +Learn more in [Adjusting SSL certificate retrieval](docs/configuring-playbook-ssl-certificates.md). + +For people who use Let's Encrypt (mostly everyone, since it's the default), you'll also have to rename a variable in your configuration: + +- before: `host_specific_matrix_ssl_support_email` +- after: `host_specific_matrix_ssl_lets_encrypt_support_email` + + ## (BC Break) mxisd upgrade with multiple base DN support mxisd has bee upgraded to [version 1.2.2](https://github.com/kamax-matrix/mxisd/releases/tag/v1.2.2), which supports [multiple base DNs](https://github.com/kamax-matrix/mxisd/blob/v1.2.2/docs/stores/ldap.md#base). diff --git a/README.md b/README.md index 38ec5748c..c037f8f83 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Using this playbook, you can get the following services configured on your serve - a [coturn](https://github.com/coturn/coturn) STUN/TURN server for WebRTC audio/video calls -- free [Let's Encrypt](https://letsencrypt.org/) SSL certificate, which secures the connection to the Synapse server and the Riot web UI +- (optional, default) free [Let's Encrypt](https://letsencrypt.org/) SSL certificate, which secures the connection to the Synapse server and the Riot web UI - (optional, default) a [Riot](https://riot.im/) web UI, which is configured to connect to your own Matrix Synapse server by default diff --git a/docs/configuring-playbook-own-webserver.md b/docs/configuring-playbook-own-webserver.md index 5bafe142b..a85719baf 100644 --- a/docs/configuring-playbook-own-webserver.md +++ b/docs/configuring-playbook-own-webserver.md @@ -24,6 +24,6 @@ matrix_nginx_proxy_enabled: false - ensure you set up (separate) vhosts that proxy for both Riot (`localhost:8765`) and Matrix Synapse (`localhost:8008`) -- ensure that the `/.well-known/acme-challenge` location for each "port=80 vhost" gets proxied to `http://localhost:2402` (controlled by `matrix_ssl_certbot_standalone_http_port`) for automated SSL renewal to work +- ensure that the `/.well-known/acme-challenge` location for each "port=80 vhost" gets proxied to `http://localhost:2402` (controlled by `matrix_ssl_lets_encrypt_certbot_standalone_http_port`) for automated SSL renewal to work -- ensure that you restart/reload your webserver once in a while, so that renewed SSL certificates would take effect (once a month should be enough) \ No newline at end of file +- ensure that you restart/reload your webserver once in a while, so that renewed SSL certificates would take effect (once a month should be enough) diff --git a/docs/configuring-playbook-ssl-certificates.md b/docs/configuring-playbook-ssl-certificates.md new file mode 100644 index 000000000..8974431aa --- /dev/null +++ b/docs/configuring-playbook-ssl-certificates.md @@ -0,0 +1,32 @@ +# Adjusting SSL certificate retrieval (optional, advanced) + +By default, this playbook retrieves and auto-renews free SSL certificates from [Let's Encrypt](https://letsencrypt.org/). + +If that's alright, you can skip this. + + +## Using self-signed SSL certificates + +For private deployments (not publicly accessible from the internet), you may not be able to use Let's Encrypt certificates. + +If self-signed certificates are alright with you, you can ask the playbook to generate such for you with the following configuration: + +```yaml +matrix_ssl_retrieval_method: self-signed +``` + + +## Using your own SSL certificates + +If you'd like to manage SSL certificates by yourself and have the playbook use your certificate files, you can use the following configuration: + +```yaml +matrix_ssl_retrieval_method: manually-managed +``` + +With such a configuration, the playbook would expect you to drop the SSL certificate files in the directory specified by `matrix_ssl_config_dir_path` (`/matrix/ssl/config` by default) obeying the following hierarchy: + +- `/live//fullchain.pem` +- `/live//privkey.pem` + +where `` refers to the domains that you need (usually `matrix.` and `riot.`). \ No newline at end of file diff --git a/docs/configuring-playbook.md b/docs/configuring-playbook.md index b0dc0cb39..d069f2e1f 100644 --- a/docs/configuring-playbook.md +++ b/docs/configuring-playbook.md @@ -35,6 +35,8 @@ When you're done with all the configuration you'd like to do, continue with [Ins - [Adjusting mxisd Identity Server configuration](configuring-playbook-mxisd.md) (optional) +- [Adjusting SSL certificate retrieval](configuring-playbook-ssl-certificates.md) (optional, advanced) + - [Using your own webserver, instead of this playbook's nginx proxy](configuring-playbook-own-webserver.md) (optional, advanced) - [Setting up the REST authentication password provider module](configuring-playbook-rest-auth.md) (optional, advanced) diff --git a/examples/host-vars.yml b/examples/host-vars.yml index 80a4c13ec..79311af43 100644 --- a/examples/host-vars.yml +++ b/examples/host-vars.yml @@ -4,8 +4,12 @@ # In case SSL renewal fails at some point, you'll also get # an email notification there. # +# If you decide to use another method for managing SSL certifites (different than the default Let's Encrypt), +# you won't be required to define this variable +# (see `docs/configuring-playbook-ssl-certificates.md`). +# # Example value: someone@example.com -host_specific_matrix_ssl_support_email: YOUR_EMAIL_ADDRESS_HERE +host_specific_matrix_ssl_lets_encrypt_support_email: YOUR_EMAIL_ADDRESS_HERE # This is your bare domain name (`/live//fullchain.pem +# - /live//privkey.pem +# where refers to the domains that you need (usually `hostname_matrix` and `hostname_riot`). +matrix_ssl_retrieval_method: "lets-encrypt" + +# Controls whether to obtain production or staging certificates from Let's Encrypt. +matrix_ssl_lets_encrypt_staging: false +matrix_ssl_lets_encrypt_certbot_docker_image: "certbot/certbot:v0.29.1" +matrix_ssl_lets_encrypt_certbot_standalone_http_port: 2402 +matrix_ssl_lets_encrypt_support_email: "{{ host_specific_matrix_ssl_lets_encrypt_support_email }}" + +# Specifies when to attempt to retrieve new SSL certificates from Let's Encrypt. +matrix_ssl_lets_encrypt_renew_cron_time_definition: "15 4 */5 * *" matrix_ssl_base_path: "{{ matrix_base_data_path }}/ssl" matrix_ssl_config_dir_path: "{{ matrix_ssl_base_path }}/config" matrix_ssl_log_dir_path: "{{ matrix_ssl_base_path }}/log" -matrix_ssl_support_email: "{{ host_specific_matrix_ssl_support_email }}" -matrix_ssl_certbot_docker_image: "certbot/certbot:v0.29.1" -matrix_ssl_certbot_standalone_http_port: 2402 -matrix_ssl_use_staging: false - -# Specifies when to attempt to retrieve new SSL certificates from Let's Encrypt. -matrix_ssl_renew_cron_time_definition: "15 4 */5 * *" # Variables to Control which parts of the role run. run_setup: true diff --git a/roles/matrix-server/tasks/setup/main.yml b/roles/matrix-server/tasks/setup/main.yml index ac6cb782e..33e6e7f8b 100644 --- a/roles/matrix-server/tasks/setup/main.yml +++ b/roles/matrix-server/tasks/setup/main.yml @@ -8,7 +8,7 @@ tags: - setup-all -- include: tasks/setup/setup_ssl.yml +- include: tasks/setup/ssl/main.yml tags: - setup-all - setup-ssl diff --git a/roles/matrix-server/tasks/setup/setup_ssl.yml b/roles/matrix-server/tasks/setup/setup_ssl.yml deleted file mode 100644 index cabffb81f..000000000 --- a/roles/matrix-server/tasks/setup/setup_ssl.yml +++ /dev/null @@ -1,54 +0,0 @@ ---- - -- name: Determine domains to obtain certificates for (Matrix) - set_fact: - domains_to_obtain_certificate_for: "['{{ hostname_matrix }}']" - -- name: Determine domains to obtain certificates for (Riot) - set_fact: - domains_to_obtain_certificate_for: "{{ domains_to_obtain_certificate_for + [hostname_riot] }}" - when: matrix_riot_web_enabled - -- name: Allow access to HTTP/HTTPS in firewalld - firewalld: - service: "{{ item }}" - state: enabled - immediate: yes - permanent: yes - with_items: - - http - - https - when: ansible_os_family == 'RedHat' - -- name: Ensure certbot Docker image is pulled - docker_image: - name: "{{ matrix_ssl_certbot_docker_image }}" - -- name: Ensure SSL certificate paths exists - file: - path: "{{ item }}" - state: directory - mode: 0770 - owner: "{{ matrix_user_username }}" - group: "{{ matrix_user_username }}" - with_items: - - "{{ matrix_ssl_log_dir_path }}" - - "{{ matrix_ssl_config_dir_path }}" - -- name: Obtain initial certificates - include_tasks: "tasks/setup/setup_ssl_for_domain.yml" - with_items: "{{ domains_to_obtain_certificate_for }}" - loop_control: - loop_var: domain_name - -- name: Ensure SSL renewal script installed - template: - src: "{{ role_path }}/templates/usr-local-bin/matrix-ssl-certificates-renew.j2" - dest: "/usr/local/bin/matrix-ssl-certificates-renew" - mode: 0750 - -- name: Ensure periodic SSL renewal cronjob configured - template: - src: "{{ role_path }}/templates/cron.d/matrix-ssl-certificate-renewal.j2" - dest: "/etc/cron.d/matrix-ssl-certificate-renewal" - mode: 0600 diff --git a/roles/matrix-server/tasks/setup/ssl/main.yml b/roles/matrix-server/tasks/setup/ssl/main.yml new file mode 100644 index 000000000..d8593d78c --- /dev/null +++ b/roles/matrix-server/tasks/setup/ssl/main.yml @@ -0,0 +1,38 @@ +--- + +- name: Fail if using unsupported SSL certificate retrieval method + fail: + msg: "The `matrix_ssl_retrieval_method` variable contains an unsupported value" + when: "matrix_ssl_retrieval_method not in ['lets-encrypt', 'self-signed', 'manually-managed']" + + +# Common tasks, required by any method below. + +- name: Determine domains that we require certificates for (Matrix) + set_fact: + domains_requiring_certificates: "['{{ hostname_matrix }}']" + +- name: Determine domains that we require certificates for (Riot) + set_fact: + domains_requiring_certificates: "{{ domains_requiring_certificates + [hostname_riot] }}" + when: "matrix_riot_web_enabled" + +- name: Ensure SSL certificate paths exists + file: + path: "{{ item }}" + state: directory + mode: 0770 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_username }}" + with_items: + - "{{ matrix_ssl_log_dir_path }}" + - "{{ matrix_ssl_config_dir_path }}" + + +# Method specific tasks follow + +- include: tasks/setup/ssl/setup_ssl_lets_encrypt.yml + +- include: tasks/setup/ssl/setup_ssl_self_signed.yml + +- include: tasks/setup/ssl/setup_ssl_manually_managed.yml diff --git a/roles/matrix-server/tasks/setup/ssl/setup_ssl_lets_encrypt.yml b/roles/matrix-server/tasks/setup/ssl/setup_ssl_lets_encrypt.yml new file mode 100644 index 000000000..2836e5959 --- /dev/null +++ b/roles/matrix-server/tasks/setup/ssl/setup_ssl_lets_encrypt.yml @@ -0,0 +1,61 @@ +--- + +# +# Tasks related to setting up Let's Encrypt's management of certificates +# + +- name: (Deprecation) Fail if using outdated configuration + fail: + msg: "You're using the `host_specific_matrix_ssl_support_email` variable, which has been superseded by `host_specific_matrix_ssl_lets_encrypt_support_email`. Please change your configuration to use the new name!" + when: "matrix_ssl_retrieval_method == 'lets-encrypt' and host_specific_matrix_ssl_support_email is defined" + +- name: Allow access to HTTP/HTTPS in firewalld + firewalld: + service: "{{ item }}" + state: enabled + immediate: yes + permanent: yes + with_items: + - http + - https + when: "matrix_ssl_retrieval_method == 'lets-encrypt' and ansible_os_family == 'RedHat'" + +- name: Ensure certbot Docker image is pulled + docker_image: + name: "{{ matrix_ssl_lets_encrypt_certbot_docker_image }}" + when: "matrix_ssl_retrieval_method == 'lets-encrypt'" + +- name: Obtain certificates + include_tasks: "tasks/setup/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml" + with_items: "{{ domains_requiring_certificates }}" + loop_control: + loop_var: domain_name + when: "matrix_ssl_retrieval_method == 'lets-encrypt'" + +- name: Ensure SSL renewal script installed + template: + src: "{{ role_path }}/templates/usr-local-bin/matrix-ssl-certificates-renew.j2" + dest: "/usr/local/bin/matrix-ssl-certificates-renew" + mode: 0750 + when: "matrix_ssl_retrieval_method == 'lets-encrypt'" + +- name: Ensure periodic SSL renewal cronjob configured + template: + src: "{{ role_path }}/templates/cron.d/matrix-ssl-certificate-renewal.j2" + dest: "/etc/cron.d/matrix-ssl-certificate-renewal" + mode: 0600 + when: "matrix_ssl_retrieval_method == 'lets-encrypt'" + + +# +# Tasks related to getting rid of Let's Encrypt's management of certificates +# + +- name: Ensure Let's Encrypt SSL certificate management files removed + file: + path: "{{ item }}" + state: absent + with_items: + - /usr/local/bin/matrix-ssl-certificates-renew + - /etc/cron.d/matrix-ssl-certificate-renewal + when: "matrix_ssl_retrieval_method != 'lets-encrypt'" diff --git a/roles/matrix-server/tasks/setup/setup_ssl_for_domain.yml b/roles/matrix-server/tasks/setup/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml similarity index 79% rename from roles/matrix-server/tasks/setup/setup_ssl_for_domain.yml rename to roles/matrix-server/tasks/setup/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml index c7bb15c1c..cf97444f1 100644 --- a/roles/matrix-server/tasks/setup/setup_ssl_for_domain.yml +++ b/roles/matrix-server/tasks/setup/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml @@ -22,38 +22,38 @@ --net=host -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt - {{ matrix_ssl_certbot_docker_image }} + {{ matrix_ssl_lets_encrypt_certbot_docker_image }} certonly --non-interactive - {% if matrix_ssl_use_staging %}--staging{% endif %} + {% if matrix_ssl_lets_encrypt_staging %}--staging{% endif %} --standalone --preferred-challenges http --agree-tos - --email={{ matrix_ssl_support_email }} + --email={{ matrix_ssl_lets_encrypt_support_email }} -d {{ domain_name }} when: "domain_name_needs_cert" register: result_certbot_direct ignore_errors: true # If matrix-nginx-proxy is configured from a previous run of this playbook, -# and it's running now, it may be able to proxy requests to `matrix_ssl_certbot_standalone_http_port`. +# and it's running now, it may be able to proxy requests to `matrix_ssl_lets_encrypt_certbot_standalone_http_port`. - name: Attempt initial SSL certificate retrieval with standalone authenticator (via proxy) shell: >- /usr/bin/docker run --rm --name=matrix-certbot - -p 127.0.0.1:{{ matrix_ssl_certbot_standalone_http_port }}:80 + -p 127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}:80 --network={{ matrix_docker_network }} -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt - {{ matrix_ssl_certbot_docker_image }} + {{ matrix_ssl_lets_encrypt_certbot_docker_image }} certonly --non-interactive - {% if matrix_ssl_use_staging %}--staging{% endif %} + {% if matrix_ssl_lets_encrypt_staging %}--staging{% endif %} --standalone --preferred-challenges http --agree-tos - --email={{ matrix_ssl_support_email }} + --email={{ matrix_ssl_lets_encrypt_support_email }} -d {{ domain_name }} when: "domain_name_needs_cert and result_certbot_direct.failed" register: result_certbot_proxy @@ -65,6 +65,6 @@ Failed to obtain a certificate directly (by listening on port 80) and also failed to obtain by relying on the server at port 80 to proxy the request. See above for details. - You may wish to set up proxying of /.well-known/acme-challenge to {{ matrix_ssl_certbot_standalone_http_port }} or, + You may wish to set up proxying of /.well-known/acme-challenge to {{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }} or, more easily, stop the server on port 80 while this playbook runs. - when: "domain_name_needs_cert and result_certbot_direct.failed and result_certbot_proxy.failed" \ No newline at end of file + when: "domain_name_needs_cert and result_certbot_direct.failed and result_certbot_proxy.failed" diff --git a/roles/matrix-server/tasks/setup/ssl/setup_ssl_manually_managed.yml b/roles/matrix-server/tasks/setup/ssl/setup_ssl_manually_managed.yml new file mode 100644 index 000000000..787663819 --- /dev/null +++ b/roles/matrix-server/tasks/setup/ssl/setup_ssl_manually_managed.yml @@ -0,0 +1,8 @@ +--- + +- name: Verify certificates + include_tasks: "tasks/setup/ssl/setup_ssl_manually_managed_verify_for_domain.yml" + with_items: "{{ domains_requiring_certificates }}" + loop_control: + loop_var: domain_name + when: "matrix_ssl_retrieval_method == 'manually-managed'" \ No newline at end of file diff --git a/roles/matrix-server/tasks/setup/ssl/setup_ssl_manually_managed_verify_for_domain.yml b/roles/matrix-server/tasks/setup/ssl/setup_ssl_manually_managed_verify_for_domain.yml new file mode 100644 index 000000000..be0444b13 --- /dev/null +++ b/roles/matrix-server/tasks/setup/ssl/setup_ssl_manually_managed_verify_for_domain.yml @@ -0,0 +1,23 @@ +--- + +- set_fact: + matrix_ssl_certificate_verification_cert_path: "{{ matrix_ssl_config_dir_path }}/live/{{ domain_name }}/fullchain.pem" + matrix_ssl_certificate_verification_cert_key_path: "{{ matrix_ssl_config_dir_path }}/live/{{ domain_name }}/privkey.pem" + +- name: Check if SSL certificate file exists + stat: + path: "{{ matrix_ssl_certificate_verification_cert_path }}" + register: matrix_ssl_certificate_verification_cert_path_stat_result + +- fail: + msg: "Failed finding a certificate file (for domain `{{ domain_name }}`) at `{{ matrix_ssl_certificate_verification_cert_path }}`" + when: "not matrix_ssl_certificate_verification_cert_path_stat_result.stat.exists" + +- name: Check if SSL certificate key file exists + stat: + path: "{{ matrix_ssl_certificate_verification_cert_key_path }}" + register: matrix_ssl_certificate_verification_cert_key_path_stat_result + +- fail: + msg: "Failed finding a certificate key file (for domain `{{ domain_name }}`) at `{{ matrix_ssl_certificate_verification_cert_key_path }}`" + when: "not matrix_ssl_certificate_verification_cert_key_path_stat_result.stat.exists" \ No newline at end of file diff --git a/roles/matrix-server/tasks/setup/ssl/setup_ssl_self_signed.yml b/roles/matrix-server/tasks/setup/ssl/setup_ssl_self_signed.yml new file mode 100644 index 000000000..92780266b --- /dev/null +++ b/roles/matrix-server/tasks/setup/ssl/setup_ssl_self_signed.yml @@ -0,0 +1,24 @@ +--- + +- name: Ensure OpenSSL installed (RedHat) + yum: + name: + - openssl + state: present + update_cache: no + when: ansible_os_family == 'RedHat' + +- name: Ensure APT usage dependencies are installed (Debian) + apt: + name: + - openssl + state: present + update_cache: no + when: ansible_os_family == 'Debian' + +- name: Obtain certificates + include_tasks: "tasks/setup/ssl/setup_ssl_self_signed_obtain_for_domain.yml" + with_items: "{{ domains_requiring_certificates }}" + loop_control: + loop_var: domain_name + when: "matrix_ssl_retrieval_method == 'self-signed'" diff --git a/roles/matrix-server/tasks/setup/ssl/setup_ssl_self_signed_obtain_for_domain.yml b/roles/matrix-server/tasks/setup/ssl/setup_ssl_self_signed_obtain_for_domain.yml new file mode 100644 index 000000000..0e6908346 --- /dev/null +++ b/roles/matrix-server/tasks/setup/ssl/setup_ssl_self_signed_obtain_for_domain.yml @@ -0,0 +1,40 @@ +--- + +- set_fact: + matrix_ssl_certificate_csr_path: "{{ matrix_ssl_config_dir_path }}/live/{{ domain_name }}/csr.csr" + matrix_ssl_certificate_cert_path: "{{ matrix_ssl_config_dir_path }}/live/{{ domain_name }}/fullchain.pem" + matrix_ssl_certificate_cert_key_path: "{{ matrix_ssl_config_dir_path }}/live/{{ domain_name }}/privkey.pem" + +- name: Check if SSL certificate file exists + stat: + path: "{{ matrix_ssl_certificate_cert_path }}" + register: matrix_ssl_certificate_cert_path_stat_result + +# In order to do any sort of generation (below), we need to ensure the directory exists first +- name: Ensure SSL certificate directory exists + file: + path: "{{ matrix_ssl_certificate_csr_path|dirname }}" + state: directory + mode: 0750 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_username }}" + when: "not matrix_ssl_certificate_cert_path_stat_result.stat.exists" + +# The proper way to do this is by using a sequence of +# `openssl_privatekey`, `openssl_csr` and `openssl_certificate`. +# +# Unfortunately, `openssl_csr` and `openssl_certificate` require `PyOpenSSL>=0.15` to work, +# which is not available on CentOS 7 (at least). +# +# We'll do it in a more manual way. +- name: Generate SSL certificate + command: | + openssl req -x509 \ + -sha256 \ + -newkey rsa:4096 \ + -nodes \ + -subj "/CN={{ domain_name }}" \ + -keyout {{ matrix_ssl_certificate_cert_key_path }} \ + -out {{ matrix_ssl_certificate_cert_path }} \ + -days 3650 + when: "not matrix_ssl_certificate_cert_path_stat_result.stat.exists" \ No newline at end of file diff --git a/roles/matrix-server/templates/cron.d/matrix-nginx-proxy-periodic-restarter.j2 b/roles/matrix-server/templates/cron.d/matrix-nginx-proxy-periodic-restarter.j2 index e8dfb72b2..0cfa2a7b1 100644 --- a/roles/matrix-server/templates/cron.d/matrix-nginx-proxy-periodic-restarter.j2 +++ b/roles/matrix-server/templates/cron.d/matrix-nginx-proxy-periodic-restarter.j2 @@ -1,4 +1,4 @@ -MAILTO="{{ matrix_ssl_support_email }}" +MAILTO="{{ matrix_ssl_lets_encrypt_support_email }}" # This periodically reloads the matrix-nginx-proxy service # to ensure it's using the latest SSL certificate diff --git a/roles/matrix-server/templates/cron.d/matrix-ssl-certificate-renewal.j2 b/roles/matrix-server/templates/cron.d/matrix-ssl-certificate-renewal.j2 index 2c7b71f2b..b8eb8ce88 100644 --- a/roles/matrix-server/templates/cron.d/matrix-ssl-certificate-renewal.j2 +++ b/roles/matrix-server/templates/cron.d/matrix-ssl-certificate-renewal.j2 @@ -1,4 +1,4 @@ -MAILTO="{{ matrix_ssl_support_email }}" +MAILTO="{{ matrix_ssl_lets_encrypt_support_email }}" # The goal of this cronjob is to ask certbot to check # the current SSL certificates and to see if some need renewal. @@ -8,4 +8,4 @@ MAILTO="{{ matrix_ssl_support_email }}" # This is not our concern here. We simply make sure the certificates are up to date. # Restarting of services happens on its own different schedule (other cronjobs). -{{ matrix_ssl_renew_cron_time_definition }} root /bin/bash /usr/local/bin/matrix-ssl-certificates-renew +{{ matrix_ssl_lets_encrypt_renew_cron_time_definition }} root /bin/bash /usr/local/bin/matrix-ssl-certificates-renew diff --git a/roles/matrix-server/templates/nginx-conf.d/matrix-riot-web.conf.j2 b/roles/matrix-server/templates/nginx-conf.d/matrix-riot-web.conf.j2 index eaa87440d..273915a88 100644 --- a/roles/matrix-server/templates/nginx-conf.d/matrix-riot-web.conf.j2 +++ b/roles/matrix-server/templates/nginx-conf.d/matrix-riot-web.conf.j2 @@ -12,7 +12,7 @@ server { proxy_pass http://$backend; {% else %} {# Generic configuration for use outside of our container setup #} - proxy_pass http://localhost:{{ matrix_ssl_certbot_standalone_http_port }}; + proxy_pass http://localhost:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; {% endif %} } diff --git a/roles/matrix-server/templates/nginx-conf.d/matrix-synapse.conf.j2 b/roles/matrix-server/templates/nginx-conf.d/matrix-synapse.conf.j2 index 2b4c0231a..0b6b22353 100644 --- a/roles/matrix-server/templates/nginx-conf.d/matrix-synapse.conf.j2 +++ b/roles/matrix-server/templates/nginx-conf.d/matrix-synapse.conf.j2 @@ -12,7 +12,7 @@ server { proxy_pass http://$backend; {% else %} {# Generic configuration for use outside of our container setup #} - proxy_pass http://localhost:{{ matrix_ssl_certbot_standalone_http_port }}; + proxy_pass http://localhost:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; {% endif %} } diff --git a/roles/matrix-server/templates/usr-local-bin/matrix-ssl-certificates-renew.j2 b/roles/matrix-server/templates/usr-local-bin/matrix-ssl-certificates-renew.j2 index 2fde95ddf..12504d1f5 100644 --- a/roles/matrix-server/templates/usr-local-bin/matrix-ssl-certificates-renew.j2 +++ b/roles/matrix-server/templates/usr-local-bin/matrix-ssl-certificates-renew.j2 @@ -4,23 +4,23 @@ # need to forward requests for `/.well-known/acme-challenge` to the certbot container. # # This can happen inside the container network by proxying to `http://matrix-certbot:80` -# or outside (on the host) by proxying to `http://localhost:{{ matrix_ssl_certbot_standalone_http_port }}`. +# or outside (on the host) by proxying to `http://localhost:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}`. docker run \ --rm \ --name=matrix-certbot \ --network="{{ matrix_docker_network }}" \ - -p 127.0.0.1:{{ matrix_ssl_certbot_standalone_http_port }}:80 \ + -p 127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}:80 \ -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt \ -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt \ - {{ matrix_ssl_certbot_docker_image }} \ + {{ matrix_ssl_lets_encrypt_certbot_docker_image }} \ renew \ --non-interactive \ - {% if matrix_ssl_use_staging %} + {% if matrix_ssl_lets_encrypt_staging %} --staging \ {% endif %} --quiet \ --standalone \ --preferred-challenges http \ --agree-tos \ - --email={{ matrix_ssl_support_email }} + --email={{ matrix_ssl_lets_encrypt_support_email }}