| @@ -1,5 +1,13 @@ | |||||
| # 2019-03-12 | # 2019-03-12 | ||||
| ## matrix-nginx-proxy support for serving the base domain | |||||
| If you don't have a dedicated server for your base domain and want to set up [Server Delegation via a well-known file](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file), the playbook has got you covered now. | |||||
| It's now possible for the playbook to obtain an SSL certificate and serve the necessary files for Matrix Server Delegation on your base domain. | |||||
| Take a look at the new [Serving the base domain](docs/configuring-playbook-base-domain-serving.md) documentation page. | |||||
| ## (BC break) matrix-nginx-proxy data variable renamed | ## (BC break) matrix-nginx-proxy data variable renamed | ||||
| `matrix_nginx_proxy_data_path` was renamed to `matrix_nginx_proxy_base_path`. | `matrix_nginx_proxy_data_path` was renamed to `matrix_nginx_proxy_base_path`. | ||||
| @@ -0,0 +1,29 @@ | |||||
| # Serving the base domain | |||||
| This playbook sets up services on your Matrix server (`matrix.DOMAIN`). | |||||
| To have this server officially be responsible for Matrix services for the base domain (`DOMAIN`), you need to set up [Server Delegation](howto-server-delegation.md). | |||||
| This is normally done by [configuring well-known](configuring-well-known.md) files on the base domain. | |||||
| People who don't have a separate server to dedicate to the base domain have trouble arranging this. | |||||
| Usually, there are 2 options: | |||||
| - either get a separate server for the base domain, just for serving the files necessary for [Server Delegation via a well-known file](howto-server-delegation.md#server-delegation-via-a-well-known-file) | |||||
| - or, arrange for the Matrix server to serve the base domain. This involves [using your own webserver](configuring-playbook-own-webserver.md) or making the integrated webserver somehow serve your base domain (possible, but complicated). | |||||
| To solve this problem, we've created an easy way to let you serve the base domain from the Matrix server via the integrated webserver (`matrix-nginx-proxy`). | |||||
| Just **adjust your DNS records**, so that your base domain is pointed to the Matrix server's IP address **and use the following configuration**: | |||||
| ```yaml | |||||
| matrix_nginx_proxy_base_domain_serving_enabled: true | |||||
| ``` | |||||
| Doing this, the playbook will: | |||||
| - obtain an SSL certificate for the base domain, just like it does for all other domains (see [how we handle SSL certificates](configuring-playbook-ssl-certificates.md)) | |||||
| - serve the `/.well-known/matrix/*` files which are necessary for [Federation Server Discovery](configuring-well-known.md#introduction-to-client-server-discovery) (also see [Server Delegation](howto-server-delegation.md)) and [Client-Server discovery](configuring-well-known.md#introduction-to-client-server-discovery) | |||||
| - serve a simple homepage at `https://DOMAIN` with content `Hello from DOMAIN` (configurable via the `matrix_nginx_proxy_base_domain_homepage_template` variable) | |||||
| @@ -15,7 +15,7 @@ Things discussed in this document: | |||||
| - [Not bothering with SSL certificates](#not-bothering-with-ssl-certificates), if you're using [your own webserver](docs/configuring-playbook-own-webserver.md) and would rather this playbook leaves SSL certificate management to you | - [Not bothering with SSL certificates](#not-bothering-with-ssl-certificates), if you're using [your own webserver](docs/configuring-playbook-own-webserver.md) and would rather this playbook leaves SSL certificate management to you | ||||
| - [Obtaining SSL certificates for additional domains](#obtaining-ssl-certificates-for-additional-domains), if you'd like to host additional domains on the Matrix server (perhaps your base domain?) and would like the playbook to help you obtain and renew certificates for those domains automatically. | |||||
| - [Obtaining SSL certificates for additional domains](#obtaining-ssl-certificates-for-additional-domains), if you'd like to host additional domains on the Matrix server and would like the playbook to help you obtain and renew certificates for those domains automatically | |||||
| ## Using self-signed SSL certificates | ## Using self-signed SSL certificates | ||||
| @@ -64,6 +64,7 @@ By default, it obtains certificates for: | |||||
| - `matrix.<your-domain>` (`matrix_server_fqn_matrix`) | - `matrix.<your-domain>` (`matrix_server_fqn_matrix`) | ||||
| - possibly for `riot.<your-domain>`, unless you have disabled the Riot component using `matrix_riot_web_enabled: false` | - possibly for `riot.<your-domain>`, unless you have disabled the Riot component using `matrix_riot_web_enabled: false` | ||||
| - possibly for `dimension.<your-domain>`, if you have explicitly [set up Dimension](configuring-playbook-dimension.md). | - possibly for `dimension.<your-domain>`, if you have explicitly [set up Dimension](configuring-playbook-dimension.md). | ||||
| - possibly for your base domain (`<your-domain>`), if you have explicitly configured [Serving the base domain](configuring-playbook-base-domain-serving.md) | |||||
| If you are hosting other domains on the Matrix machine, you can make the playbook obtain and renew certificates for those other domains too. | If you are hosting other domains on the Matrix machine, you can make the playbook obtain and renew certificates for those other domains too. | ||||
| To do that, simply define your own custom configuration like this: | To do that, simply define your own custom configuration like this: | ||||
| @@ -85,7 +86,7 @@ After redefining `matrix_ssl_domains_to_obtain_certificates_for`, to actually ob | |||||
| - re-run the SSL part of the playbook and restart all services: `ansible-playbook -i inventory/hosts setup.yml --tags=setup-ssl,start` | - re-run the SSL part of the playbook and restart all services: `ansible-playbook -i inventory/hosts setup.yml --tags=setup-ssl,start` | ||||
| The certificate files would be available in `/matrix/ssl/config/live/<your-domain>/...`. | |||||
| The certificate files would be available in `/matrix/ssl/config/live/<your-other-domain>/...`. | |||||
| For automated certificate renewal to work, each port `80` vhost for each domain you are obtaining certificates for needs to forward requests for `/.well-known/acme-challenge` to the certbot container we use for renewal. | For automated certificate renewal to work, each port `80` vhost for each domain you are obtaining certificates for needs to forward requests for `/.well-known/acme-challenge` to the certbot container we use for renewal. | ||||
| @@ -41,6 +41,8 @@ When you're done with all the configuration you'd like to do, continue with [Ins | |||||
| - [Adjusting SSL certificate retrieval](configuring-playbook-ssl-certificates.md) (optional, advanced) | - [Adjusting SSL certificate retrieval](configuring-playbook-ssl-certificates.md) (optional, advanced) | ||||
| - [Serving your base domain using this playbook's nginx server](configuring-playbook-base-domain-serving.md) (optional) | |||||
| - [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) | ||||
| @@ -39,7 +39,13 @@ To learn how to set it up, read the Installing section below. | |||||
| ## Installing well-known files on the base domain's server | ## Installing well-known files on the base domain's server | ||||
| To implement the two service discovery mechanisms, your base domain's server (e.g. `example.com`) needs to support HTTPS. | |||||
| To implement the two service discovery mechanisms, your base domain's server (e.g. `example.com`) needs to run an HTTPS-capable webserver. | |||||
| If you don't have a server for your base domain at all, you can use the Matrix server for this. | |||||
| See [Serving the base domain](configuring-playbook-base-domain-serving.md) to learn how the playbook can help you set it up. | |||||
| If you decide to go this route, you don't need to read ahead in this document. When **Serving the base domain**, the playbook takes care to serve the appropriate well-known files automatically. | |||||
| If you're managing the base domain by yourself somehow, you'll need to set up serving of some `/.well-known/matrix/*` files from it via HTTPS. | |||||
| To make things easy for you to set up, this playbook generates and hosts 2 well-known files on the Matrix domain's server (e.g. `https://matrix.example.com/.well-known/matrix/server` and `https://matrix.example.com/.well-known/matrix/client`), even though this is the wrong place to host them. | To make things easy for you to set up, this playbook generates and hosts 2 well-known files on the Matrix domain's server (e.g. `https://matrix.example.com/.well-known/matrix/server` and `https://matrix.example.com/.well-known/matrix/client`), even though this is the wrong place to host them. | ||||
| @@ -8,7 +8,7 @@ | |||||
| - either the `dig` tool or `python-dns` installed on your own computer. Used later on, by the playbook's [services check](maintenance-checking-services.md) feature. | - either the `dig` tool or `python-dns` installed on your own computer. Used later on, by the playbook's [services check](maintenance-checking-services.md) feature. | ||||
| - an HTTPS-capable web server at the base domain name (`<your-domain>`) which is capable of serving static files (unless you decide to use DNS SRV records for [Server Delegation](howto-server-delegation.md)) | |||||
| - an HTTPS-capable web server at the base domain name (`<your-domain>`) which is capable of serving static files. Unless you decide to [Serve the base domain from the Matrix server](configuring-playbook-base-domain-serving.md) or alternatively, to use DNS SRV records for [Server Delegation](howto-server-delegation.md). | |||||
| - properly configured DNS records for `<your-domain>` (details in [Configuring DNS](configuring-dns.md)) | - properly configured DNS records for `<your-domain>` (details in [Configuring DNS](configuring-dns.md)) | ||||
| @@ -246,6 +246,8 @@ matrix_ssl_domains_to_obtain_certificates_for: | | |||||
| ([matrix_server_fqn_riot] if matrix_riot_web_enabled else []) | ([matrix_server_fqn_riot] if matrix_riot_web_enabled else []) | ||||
| + | + | ||||
| ([matrix_server_fqn_dimension] if matrix_dimension_enabled else []) | ([matrix_server_fqn_dimension] if matrix_dimension_enabled else []) | ||||
| + | |||||
| ([matrix_domain] if matrix_nginx_proxy_base_domain_serving_enabled else []) | |||||
| }} | }} | ||||
| ###################################################################### | ###################################################################### | ||||
| @@ -21,6 +21,27 @@ matrix_nginx_proxy_systemd_wanted_services_list: [] | |||||
| # Contains definition objects like this: `{"src": "/outside", "dst": "/inside", "options": "rw|ro|slave|.."} | # Contains definition objects like this: `{"src": "/outside", "dst": "/inside", "options": "rw|ro|slave|.."} | ||||
| matrix_nginx_proxy_container_additional_volumes: [] | matrix_nginx_proxy_container_additional_volumes: [] | ||||
| # Controls whether matrix-nginx-proxy should serve the base domain. | |||||
| # | |||||
| # This is useful for when you only have your Matrix server, but you need to serve | |||||
| # to serve `/.well-known/matrix/*` files from the base domain for the needs of | |||||
| # Server-Discovery (Federation) and for Client-Discovery. | |||||
| # | |||||
| # Besides serving these Matrix files, a homepage would be served with content | |||||
| # as specified in the `matrix_nginx_proxy_base_domain_homepage_template` variable. | |||||
| # You can also put additional files to use for this webpage | |||||
| # in the `{{ matrix_nginx_proxy_data_path }}/matrix-domain` (`/matrix/nginx-proxy/data/matrix-domain`) directory. | |||||
| matrix_nginx_proxy_base_domain_serving_enabled: false | |||||
| matrix_nginx_proxy_base_domain_hostname: "{{ matrix_domain }}" | |||||
| matrix_nginx_proxy_base_domain_homepage_template: |- | |||||
| <!doctype html> | |||||
| <meta charset="utf-8" /> | |||||
| <html> | |||||
| <body> | |||||
| Hello from {{ matrix_domain }}! | |||||
| </body> | |||||
| </html> | |||||
| # Controls whether proxying the riot domain should be done. | # Controls whether proxying the riot domain should be done. | ||||
| matrix_nginx_proxy_proxy_riot_enabled: false | matrix_nginx_proxy_proxy_riot_enabled: false | ||||
| matrix_nginx_proxy_proxy_riot_hostname: "{{ matrix_server_fqn_riot }}" | matrix_nginx_proxy_proxy_riot_hostname: "{{ matrix_server_fqn_riot }}" | ||||
| @@ -66,6 +66,31 @@ | |||||
| mode: 0644 | mode: 0644 | ||||
| when: "matrix_nginx_proxy_proxy_dimension_enabled" | when: "matrix_nginx_proxy_proxy_dimension_enabled" | ||||
| - name: Ensure Matrix nginx-proxy data directory for base domain exists | |||||
| file: | |||||
| path: "{{ matrix_nginx_proxy_data_path }}/matrix-domain" | |||||
| state: directory | |||||
| mode: 0750 | |||||
| owner: "{{ matrix_user_username }}" | |||||
| group: "{{ matrix_user_username }}" | |||||
| when: "matrix_nginx_proxy_base_domain_serving_enabled" | |||||
| - name: Ensure Matrix nginx-proxy homepage for base domain exists | |||||
| copy: | |||||
| content: "{{ matrix_nginx_proxy_base_domain_homepage_template }}" | |||||
| dest: "{{ matrix_nginx_proxy_data_path }}/matrix-domain/index.html" | |||||
| mode: 0644 | |||||
| owner: "{{ matrix_user_username }}" | |||||
| group: "{{ matrix_user_username }}" | |||||
| when: "matrix_nginx_proxy_base_domain_serving_enabled" | |||||
| - name: Ensure Matrix nginx-proxy configuration for base domain exists | |||||
| template: | |||||
| src: "{{ role_path }}/templates/nginx/conf.d/matrix-domain.conf.j2" | |||||
| dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-domain.conf" | |||||
| mode: 0644 | |||||
| when: "matrix_nginx_proxy_base_domain_serving_enabled" | |||||
| # | # | ||||
| # Tasks related to setting up matrix-nginx-proxy | # Tasks related to setting up matrix-nginx-proxy | ||||
| # | # | ||||
| @@ -145,6 +170,18 @@ | |||||
| state: absent | state: absent | ||||
| when: "not matrix_nginx_proxy_proxy_dimension_enabled" | when: "not matrix_nginx_proxy_proxy_dimension_enabled" | ||||
| - name: Ensure Matrix nginx-proxy homepage for base domain deleted | |||||
| file: | |||||
| path: "{{ matrix_nginx_proxy_data_path }}/matrix-domain/index.html" | |||||
| state: absent | |||||
| when: "not matrix_nginx_proxy_base_domain_serving_enabled" | |||||
| - name: Ensure Matrix nginx-proxy configuration for base domain deleted | |||||
| file: | |||||
| path: "{{ matrix_nginx_proxy_confd_path }}/matrix-domain.conf" | |||||
| state: absent | |||||
| when: "not matrix_nginx_proxy_base_domain_serving_enabled" | |||||
| - name: Ensure Matrix nginx-proxy configuration for main config override deleted | - name: Ensure Matrix nginx-proxy configuration for main config override deleted | ||||
| file: | file: | ||||
| path: "{{ matrix_nginx_proxy_base_path }}/nginx.conf" | path: "{{ matrix_nginx_proxy_base_path }}/nginx.conf" | ||||
| @@ -0,0 +1,52 @@ | |||||
| server { | |||||
| listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; | |||||
| server_name {{ matrix_nginx_proxy_base_domain_hostname }}; | |||||
| server_tokens off; | |||||
| location /.well-known/acme-challenge { | |||||
| {% if matrix_nginx_proxy_enabled %} | |||||
| {# Use the embedded DNS resolver in Docker containers to discover the service #} | |||||
| resolver 127.0.0.11 valid=5s; | |||||
| set $backend "matrix-certbot:8080"; | |||||
| proxy_pass http://$backend; | |||||
| {% else %} | |||||
| {# Generic configuration for use outside of our container setup #} | |||||
| proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; | |||||
| {% endif %} | |||||
| } | |||||
| location / { | |||||
| return 301 https://$http_host$request_uri; | |||||
| } | |||||
| } | |||||
| server { | |||||
| listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; | |||||
| listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; | |||||
| server_name {{ matrix_nginx_proxy_base_domain_hostname }}; | |||||
| server_tokens off; | |||||
| root /nginx-data/matrix-domain; | |||||
| gzip on; | |||||
| gzip_types text/plain application/json; | |||||
| ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_base_domain_hostname }}/fullchain.pem; | |||||
| ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_base_domain_hostname }}/privkey.pem; | |||||
| ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; | |||||
| ssl_prefer_server_ciphers on; | |||||
| ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; | |||||
| location /.well-known/matrix { | |||||
| root {{ matrix_static_files_base_path }}; | |||||
| {# | |||||
| A somewhat long expires value is used to prevent outages | |||||
| in case this is unreachable due to network failure. | |||||
| #} | |||||
| expires 4h; | |||||
| default_type application/json; | |||||
| add_header Access-Control-Allow-Origin *; | |||||
| } | |||||
| } | |||||