| @@ -1,5 +1,13 @@ | |||
| # 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 | |||
| `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 | |||
| - [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 | |||
| @@ -64,6 +64,7 @@ By default, it obtains certificates for: | |||
| - `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 `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. | |||
| 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` | |||
| 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. | |||
| @@ -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) | |||
| - [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) | |||
| - [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 | |||
| 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. | |||
| @@ -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. | |||
| - 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)) | |||
| @@ -246,6 +246,8 @@ matrix_ssl_domains_to_obtain_certificates_for: | | |||
| ([matrix_server_fqn_riot] if matrix_riot_web_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|.."} | |||
| 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. | |||
| matrix_nginx_proxy_proxy_riot_enabled: false | |||
| matrix_nginx_proxy_proxy_riot_hostname: "{{ matrix_server_fqn_riot }}" | |||
| @@ -66,6 +66,31 @@ | |||
| mode: 0644 | |||
| 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 | |||
| # | |||
| @@ -145,6 +170,18 @@ | |||
| state: absent | |||
| 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 | |||
| file: | |||
| 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 *; | |||
| } | |||
| } | |||