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.pull/54/head
| @@ -1,5 +1,20 @@ | |||||
| # 2018-12-23 | # 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 | ## (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). | 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). | ||||
| @@ -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 | - 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 | - (optional, default) a [Riot](https://riot.im/) web UI, which is configured to connect to your own Matrix Synapse server by default | ||||
| @@ -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 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) | |||||
| - 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) | |||||
| @@ -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: | |||||
| - `<matrix_ssl_config_dir_path>/live/<domain>/fullchain.pem` | |||||
| - `<matrix_ssl_config_dir_path>/live/<domain>/privkey.pem` | |||||
| where `<domain>` refers to the domains that you need (usually `matrix.<your-domain>` and `riot.<your-domain>`). | |||||
| @@ -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 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) | - [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) | - [Setting up the REST authentication password provider module](configuring-playbook-rest-auth.md) (optional, advanced) | ||||
| @@ -4,8 +4,12 @@ | |||||
| # In case SSL renewal fails at some point, you'll also get | # In case SSL renewal fails at some point, you'll also get | ||||
| # an email notification there. | # 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 | # 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 (`<your-domain`). | # This is your bare domain name (`<your-domain`). | ||||
| # | # | ||||
| @@ -387,17 +387,34 @@ matrix_nginx_proxy_reload_cron_time_definition: "20 4 */5 * *" | |||||
| # See: https://github.com/nginxinc/docker-nginx/issues/190 | # See: https://github.com/nginxinc/docker-nginx/issues/190 | ||||
| matrix_nginx_proxy_ssl_protocols: "TLSv1.1 TLSv1.2" | matrix_nginx_proxy_ssl_protocols: "TLSv1.1 TLSv1.2" | ||||
| # By default, this playbook automatically retrieves and auto-renews | |||||
| # free SSL certificates from Let's Encrypt. | |||||
| # | |||||
| # The following retrieval methods are supported: | |||||
| # - "lets-encrypt" - the playbook obtains free SSL certificates from Let's Encrypt | |||||
| # - "self-signed" - the playbook generates and self-signs certificates | |||||
| # - "manually-managed" - lets you manage certificates by yourself (manually; see below) | |||||
| # | |||||
| # If you decide to manage certificates by yourself (`matrix_ssl_retrieval_method: manually-managed`), | |||||
| # you'd need to drop them into the directory specified by `matrix_ssl_config_dir_path` | |||||
| # obeying the following hierarchy: | |||||
| # - <matrix_ssl_config_dir_path>/live/<domain>/fullchain.pem | |||||
| # - <matrix_ssl_config_dir_path>/live/<domain>/privkey.pem | |||||
| # where <domain> 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_base_path: "{{ matrix_base_data_path }}/ssl" | ||||
| matrix_ssl_config_dir_path: "{{ matrix_ssl_base_path }}/config" | matrix_ssl_config_dir_path: "{{ matrix_ssl_base_path }}/config" | ||||
| matrix_ssl_log_dir_path: "{{ matrix_ssl_base_path }}/log" | 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. | # Variables to Control which parts of the role run. | ||||
| run_setup: true | run_setup: true | ||||
| @@ -8,7 +8,7 @@ | |||||
| tags: | tags: | ||||
| - setup-all | - setup-all | ||||
| - include: tasks/setup/setup_ssl.yml | |||||
| - include: tasks/setup/ssl/main.yml | |||||
| tags: | tags: | ||||
| - setup-all | - setup-all | ||||
| - setup-ssl | - setup-ssl | ||||
| @@ -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 | |||||
| @@ -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 | |||||
| @@ -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'" | |||||
| @@ -22,38 +22,38 @@ | |||||
| --net=host | --net=host | ||||
| -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt | -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt | ||||
| -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt | -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt | ||||
| {{ matrix_ssl_certbot_docker_image }} | |||||
| {{ matrix_ssl_lets_encrypt_certbot_docker_image }} | |||||
| certonly | certonly | ||||
| --non-interactive | --non-interactive | ||||
| {% if matrix_ssl_use_staging %}--staging{% endif %} | |||||
| {% if matrix_ssl_lets_encrypt_staging %}--staging{% endif %} | |||||
| --standalone | --standalone | ||||
| --preferred-challenges http | --preferred-challenges http | ||||
| --agree-tos | --agree-tos | ||||
| --email={{ matrix_ssl_support_email }} | |||||
| --email={{ matrix_ssl_lets_encrypt_support_email }} | |||||
| -d {{ domain_name }} | -d {{ domain_name }} | ||||
| when: "domain_name_needs_cert" | when: "domain_name_needs_cert" | ||||
| register: result_certbot_direct | register: result_certbot_direct | ||||
| ignore_errors: true | ignore_errors: true | ||||
| # If matrix-nginx-proxy is configured from a previous run of this playbook, | # 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) | - name: Attempt initial SSL certificate retrieval with standalone authenticator (via proxy) | ||||
| shell: >- | shell: >- | ||||
| /usr/bin/docker run | /usr/bin/docker run | ||||
| --rm | --rm | ||||
| --name=matrix-certbot | --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 }} | --network={{ matrix_docker_network }} | ||||
| -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt | -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt | ||||
| -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt | -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt | ||||
| {{ matrix_ssl_certbot_docker_image }} | |||||
| {{ matrix_ssl_lets_encrypt_certbot_docker_image }} | |||||
| certonly | certonly | ||||
| --non-interactive | --non-interactive | ||||
| {% if matrix_ssl_use_staging %}--staging{% endif %} | |||||
| {% if matrix_ssl_lets_encrypt_staging %}--staging{% endif %} | |||||
| --standalone | --standalone | ||||
| --preferred-challenges http | --preferred-challenges http | ||||
| --agree-tos | --agree-tos | ||||
| --email={{ matrix_ssl_support_email }} | |||||
| --email={{ matrix_ssl_lets_encrypt_support_email }} | |||||
| -d {{ domain_name }} | -d {{ domain_name }} | ||||
| when: "domain_name_needs_cert and result_certbot_direct.failed" | when: "domain_name_needs_cert and result_certbot_direct.failed" | ||||
| register: result_certbot_proxy | register: result_certbot_proxy | ||||
| @@ -65,6 +65,6 @@ | |||||
| Failed to obtain a certificate directly (by listening on port 80) | 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. | and also failed to obtain by relying on the server at port 80 to proxy the request. | ||||
| See above for details. | 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. | 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" | |||||
| when: "domain_name_needs_cert and result_certbot_direct.failed and result_certbot_proxy.failed" | |||||
| @@ -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'" | |||||
| @@ -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" | |||||
| @@ -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'" | |||||
| @@ -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" | |||||
| @@ -1,4 +1,4 @@ | |||||
| MAILTO="{{ matrix_ssl_support_email }}" | |||||
| MAILTO="{{ matrix_ssl_lets_encrypt_support_email }}" | |||||
| # This periodically reloads the matrix-nginx-proxy service | # This periodically reloads the matrix-nginx-proxy service | ||||
| # to ensure it's using the latest SSL certificate | # to ensure it's using the latest SSL certificate | ||||
| @@ -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 goal of this cronjob is to ask certbot to check | ||||
| # the current SSL certificates and to see if some need renewal. | # 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. | # 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). | # 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 | |||||
| @@ -12,7 +12,7 @@ server { | |||||
| proxy_pass http://$backend; | proxy_pass http://$backend; | ||||
| {% else %} | {% else %} | ||||
| {# Generic configuration for use outside of our container setup #} | {# 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 %} | {% endif %} | ||||
| } | } | ||||
| @@ -12,7 +12,7 @@ server { | |||||
| proxy_pass http://$backend; | proxy_pass http://$backend; | ||||
| {% else %} | {% else %} | ||||
| {# Generic configuration for use outside of our container setup #} | {# 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 %} | {% endif %} | ||||
| } | } | ||||
| @@ -4,23 +4,23 @@ | |||||
| # need to forward requests for `/.well-known/acme-challenge` to the certbot container. | # 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` | # 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 \ | docker run \ | ||||
| --rm \ | --rm \ | ||||
| --name=matrix-certbot \ | --name=matrix-certbot \ | ||||
| --network="{{ matrix_docker_network }}" \ | --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_config_dir_path }}:/etc/letsencrypt \ | ||||
| -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt \ | -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt \ | ||||
| {{ matrix_ssl_certbot_docker_image }} \ | |||||
| {{ matrix_ssl_lets_encrypt_certbot_docker_image }} \ | |||||
| renew \ | renew \ | ||||
| --non-interactive \ | --non-interactive \ | ||||
| {% if matrix_ssl_use_staging %} | |||||
| {% if matrix_ssl_lets_encrypt_staging %} | |||||
| --staging \ | --staging \ | ||||
| {% endif %} | {% endif %} | ||||
| --quiet \ | --quiet \ | ||||
| --standalone \ | --standalone \ | ||||
| --preferred-challenges http \ | --preferred-challenges http \ | ||||
| --agree-tos \ | --agree-tos \ | ||||
| --email={{ matrix_ssl_support_email }} | |||||
| --email={{ matrix_ssl_lets_encrypt_support_email }} | |||||