From 93bb117a29a36e4356aac04debb3e6d82875da11 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Thu, 16 Feb 2023 08:24:27 +0200 Subject: [PATCH] Mention Traefik changes causing backward-compatibility break for own-webserver (non-nginx-proxy) users This also updates `docs/configuring-playbook-own-webserver.md`, trying to make it up-to-date with all recent changes. --- CHANGELOG.md | 9 +- docs/configuring-playbook-own-webserver.md | 270 +++++++++++---------- 2 files changed, 142 insertions(+), 137 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b47433d7d..f6b76e109 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,12 +22,13 @@ You need to **update you roles** (`just roles` or `make roles`) regardless of wh # 2023-02-12 -## Reverse-proxy configuration changes and initial Traefik support +## (Backward Compatibility) Reverse-proxy configuration changes and initial Traefik support **TLDR**: - there's a new `matrix_playbook_reverse_proxy_type` variable (see [roles/custom/matrix-base/defaults/main.yml](roles/custom/matrix-base/defaults/main.yml)), which lets you tell the playbook what reverse-proxy setup you'd like to have. This makes it easier for people who want to do reverse-proxying in other ways. -- the default reverse-proxy (`matrix_playbook_reverse_proxy_type`) is still `playbook-managed-nginx` (via `matrix-nginx-proxy`), for now. **Existing users should not observe any changes** and can stay on this for now. +- the default reverse-proxy (`matrix_playbook_reverse_proxy_type`) is still `playbook-managed-nginx` (via `matrix-nginx-proxy`), for now. **Existing `matrix-nginx-proxy` users should not observe any changes** and can stay on this for now. +- **Users who use their [own other webserver](docs/configuring-playbook-own-webserver.md) (e.g. Apache, etc.) need to change** `matrix_playbook_reverse_proxy_type` to something like `other-on-same-host`, `other-on-another-host` or `other-nginx-non-container` - we now have **optional [Traefik](https://traefik.io/) support**, so you could easily host Matrix and other Traefik-native services in containers on the same server. Traefik support is still experimental (albeit, good enough) and will improve over time. It does work, but certain esoteric features may not be there yet. - **Traefik will become the default reverse-proxy in the near future**. `matrix-nginx-proxy` will either remain as an option, or be completely removed to simplify the playbook @@ -81,7 +82,9 @@ Traefik does not lock important functionality we'd like to use into [plus packag `matrix_playbook_reverse_proxy_type` still defaults to a value of `playbook-managed-nginx`. -Unless we have some regression, **existing users should be able to update their Matrix server and not observe any changes**. Their setup should still remain on nginx and everything should still work as expected. +Unless we have some regression, **existing `matrix-nginx-proxy` users should be able to update their Matrix server and not observe any changes**. Their setup should still remain on nginx and everything should still work as expected. + +**Users using [their own webservers](docs/configuring-playbook-own-webserver.md) will need to change `matrix_playbook_reverse_proxy_type`** to something like `other-on-same-host`, `other-on-another-host` or `other-nginx-non-container`. Previously, they could toggle `matrix_nginx_proxy_enabled` to `false`, and that made the playbook automatically expose services locally. Currently, we only do this if you change the reverse-proxy type to `other-on-same-host`, `other-on-another-host` or `other-nginx-non-container`. #### How do I explicitly switch to Traefik right now? diff --git a/docs/configuring-playbook-own-webserver.md b/docs/configuring-playbook-own-webserver.md index 77fa018d0..41b1fd83a 100644 --- a/docs/configuring-playbook-own-webserver.md +++ b/docs/configuring-playbook-own-webserver.md @@ -1,145 +1,21 @@ # Using your own webserver, instead of this playbook's nginx proxy (optional, advanced) -**Note**: the playbook is [in the process of moving to Traefik](../CHANGELOG.md#reverse-proxy-configuration-changes-and-initial-traefik-support). The documentation below should be correct, but things will change soon. +**Note**: the playbook is [in the process of moving to Traefik](../CHANGELOG.md#reverse-proxy-configuration-changes-and-initial-traefik-support). The **documentation below may be incomplete or misleading**. By default, this playbook installs its own nginx webserver (called `matrix-nginx-proxy`, in a Docker container) which listens on ports 80 and 443. If that's alright, you can skip this. -If you don't want this playbook's nginx webserver to take over your server's 80/443 ports like that, -and you'd like to use your own webserver (be it nginx, Apache, Varnish Cache, etc.), you can. +Soon, this default will change and the playbook will install its own [Traefik](https://traefik.io/) reverse-proxy instead. -There are **2 ways you can go about it**, if you'd like to use your own webserver: +## Traefik -- [Method 1: Disabling the integrated nginx reverse-proxy webserver](#method-1-disabling-the-integrated-nginx-reverse-proxy-webserver) +[Traefik](https://traefik.io/) will be the default reverse-proxy for the playbook in the near future. -- [Method 2: Fronting the integrated nginx reverse-proxy webserver with another reverse-proxy](#method-2-fronting-the-integrated-nginx-reverse-proxy-webserver-with-another-reverse-proxy) +There are 2 ways to use Traefik with this playbook, as described below. +### Traefik managed by the playbook -## Method 1: Disabling the integrated nginx reverse-proxy webserver - -This method is about completely disabling the integrated nginx reverse-proxy webserver and replicating its behavior using another webserver. - -If that other webserver is `nginx`, you'd be able to include configuration files generated by the playbook into your `nginx` webserver. - -If you'd like to use another webserver (not `nginx`), you'd need to do things manually. We have examples for other webservers below. - -For an alternative (which keeps `matrix-nginx-proxy` around and connects your other reverse-proxy with it), make sure to check Method #2. - -### Preparation - -No matter which external webserver you decide to go with, you'll need to: - -1) Make sure your web server user (something like `http`, `apache`, `www-data`, `nginx`) is part of the `matrix` group. You should run something like this: `usermod -a -G matrix nginx`. This allows your webserver user to access files owned by the `matrix` group. When using an external nginx webserver, this allows it to read configuration files from `/matrix/nginx-proxy/conf.d`. When using another server, it would make other files, such as `/matrix/static-files/.well-known`, accessible to it. - -2) Edit your configuration file (`inventory/host_vars/matrix./vars.yml`) - - to disable the integrated nginx server: - - ```yaml - matrix_nginx_proxy_enabled: false - ``` - - if using an external server on another host, add the `_http_host_bind_port` or `_http_bind_port` variables for the services that will be exposed by the external server on the other host. The actual name of the variable is listed in the `roles//defaults/vars.yml` file for each service. Most variables follow the `_http_host_bind_port` format. - - These variables will make Docker expose the ports on all network interfaces instead of localhost only. - [Keep in mind that there are some security concerns if you simply proxy everything.](https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.md#synapse-administration-endpoints) - - Here are the variables required for the default configuration (Synapse and Element) - ``` - matrix_synapse_reverse_proxy_companion_container_client_api_host_bind_port: '0.0.0.0:8008' - matrix_synapse_reverse_proxy_companion_container_federation_api_host_bind_port: '0.0.0.0:8048' - matrix_client_element_container_http_host_bind_port: "0.0.0.0:8765" - ``` - -3) **If you'll manage SSL certificates by yourself**, edit your configuration file (`inventory/host_vars/matrix./vars.yml`) to disable SSL certificate retrieval: - -```yaml -matrix_ssl_retrieval_method: none -``` - -**Note**: During [installation](installing.md), unless you've disabled SSL certificate management (`matrix_ssl_retrieval_method: none`), the playbook would need 80 to be available, in order to retrieve SSL certificates. **Please manually stop your other webserver while installing**. You can start it back up afterwards. - -### Using your own external nginx webserver - -Once you've followed the [Preparation](#preparation) guide above, it's time to set up your external nginx server. - -Even with `matrix_nginx_proxy_enabled: false`, the playbook still generates some helpful files for you in `/matrix/nginx-proxy/conf.d`. -Those configuration files are adapted for use with an external web server (one not running in the container network). - -You can most likely directly use the config files installed by this playbook at: `/matrix/nginx-proxy/conf.d`. Just include them in your own `nginx.conf` like this: `include /matrix/nginx-proxy/conf.d/*.conf;` - -Note that if your nginx version is old, it might not like our default choice of SSL protocols (particularly the fact that the brand new `TLSv1.3` protocol is enabled). You can override the protocol list by redefining the `matrix_nginx_proxy_ssl_protocols` variable. Example: - -```yaml -# Custom protocol list (removing `TLSv1.3`) to suit your nginx version. -matrix_nginx_proxy_ssl_protocols: "TLSv1.2" -``` - -If you are experiencing issues, try updating to a newer version of Nginx. As a data point in May 2021 a user reported that Nginx 1.14.2 was not working for them. They were getting errors about socket leaks. Updating to Nginx 1.19 fixed their issue. - -### Using your own external Apache webserver - -Once you've followed the [Preparation](#preparation) guide above, you can take a look at the [examples/apache](../examples/apache) directory for a sample configuration. - -### Using your own external caddy webserver - -After following the [Preparation](#preparation) guide above, you can take a look at the [examples/caddy](../examples/caddy) directory and [examples/caddy2](../examples/caddy2) directory for a sample configuration for Caddy v1 and v2, respectively. - -### Using your own HAproxy reverse proxy -After following the [Preparation](#preparation) guide above, you can take a look at the [examples/haproxy](../examples/haproxy) directory for a sample configuration. In this case HAproxy is used as a reverse proxy and a simple Nginx container is used to serve statically `.well-known` files. - -### Using another external webserver - -Feel free to look at the [examples/apache](../examples/apache) directory, or the [template files in the matrix-nginx-proxy role](../roles/custom/matrix-nginx-proxy/templates/nginx/conf.d/). - - -## Method 2: Fronting the integrated nginx reverse-proxy webserver with another reverse-proxy - -This method is about leaving the integrated nginx reverse-proxy webserver be, but making it not get in the way (using up important ports, trying to retrieve SSL certificates, etc.). - -If you wish to use another webserver, the integrated nginx reverse-proxy webserver usually gets in the way because it attempts to fetch SSL certificates and binds to ports 80, 443 and 8448 (if Matrix Federation is enabled). - -You can disable such behavior and make the integrated nginx reverse-proxy webserver only serve traffic locally (or over a local network). - -You would need some configuration like this: - -```yaml -matrix_playbook_reverse_proxy_type: other-on-same-host - -# Do not listen for HTTP on port 80 globally (default), listen on the loopback interface. -# If you'd like, you can make it use the local network as well and reverse-proxy from another local machine. -matrix_nginx_proxy_container_http_host_bind_port: '127.0.0.1:81' - -# Likewise, expose the Matrix Federation port on the loopback interface. -# Since `matrix_nginx_proxy_https_enabled` is set to `false`, this federation port will serve HTTP traffic. -# If you'd like, you can make it use the local network as well and reverse-proxy from another local machine. -# -# You'd most likely need to expose it publicly on port 8448 (8449 was chosen for the local port to prevent overlap). -matrix_nginx_proxy_container_federation_host_bind_port: '127.0.0.1:8449' - -# Coturn relies on SSL certificates that have already been obtained. -# Since we don't obtain any certificates in this `other-on-same-host` mode, it won't work by default. -# An alternative is to tweak some of: `matrix_coturn_tls_enabled`, `matrix_coturn_tls_cert_path` and `matrix_coturn_tls_key_path`. -matrix_coturn_enabled: false -``` - -With this, nginx would still be in use, but it would not bother with anything SSL related or with taking up public ports. - -All services would be served locally on `127.0.0.1:81` and `127.0.0.1:8449` (as per the example configuration above). - -You can then set up another reverse-proxy server on ports 80/443/8448 for all of the expected domains and make traffic go to these local ports. -The expected domains vary depending on the services you have enabled (`matrix.DOMAIN` for sure; `element.DOMAIN`, `dimension.DOMAIN` and `jitsi.DOMAIN` are optional). - -### Sample configuration for running behind Traefik 2.0 - -To run behind Traefik, you can: - -- use a [Playbook-managed Traefik installation](#playbook-managed-traefik-installation) -- or, use [Your own Traefik server (not managed by the playbook)](#your-own-traefik-server-not-managed-by-the-playbook) - -#### Playbook-managed Traefik installation - -The playbook can install and manage Traefik for you using the [com.devture.ansible.role.traefik](https://github.com/devture/com.devture.ansible.role.traefik) role. - -It's simplest if you go with this method. You will need the following configuration: +To switch to Traefik now, use configuration like this: ```yaml matrix_playbook_reverse_proxy_type: playbook-managed-traefik @@ -147,9 +23,11 @@ matrix_playbook_reverse_proxy_type: playbook-managed-traefik devture_traefik_ssl_email_address: YOUR_EMAIL_ADDRESS ``` -#### Your own Traefik server (not managed by the playbook) +This will install Traefik in the place of `matrix-nginx-proxy`. Traefik will manage SSL certificates for all services seamlessly. -If you'd like to run Traefik yourself, you can use configuration like this: +**Note**: during the transition period, `matrix-nginx-proxy` will still be installed in local-only mode. Do not be alarmed to see `matrix-nginx-proxy` running even when you've chosen Traefik as your reverse-proxy. In the future, we'll be able to run without nginx, but we're not there yet. + +### Traefik managed by you ```yaml matrix_playbook_reverse_proxy_type: other-traefik-container @@ -161,7 +39,9 @@ In this mode all roles will still have Traefik labels attached. You will, howeve By default, the playbook congiures services use a `web-secure` (443) and `matrix-federation` (8448) entrypoints, as well as a `default` certificate resolver. -Below is some configuration for running Traefik yourself (although we recommend using a [playbook-managed Traefik installation](#playbook-managed-traefik-installation)). +You need to configure 3 entrypoints for your Traefik server: `web` (TCP port `80`), `web-secure` (TCP port `443`) and `matrix-federation` (TCP port `8448`). + +Below is some configuration for running Traefik yourself, although we recommend using [Traefik managed by the playbook](#traefik-managed-by-the-playbook). Note that this configuration on its own does **not** redirect traffic on port 80 (plain HTTP) to port 443 for HTTPS, which may cause some issues, since the built-in Nginx proxy usually does this. If you are not already doing this in Traefik, it can be added to Traefik in a [file provider](https://docs.traefik.io/v2.0/providers/file/) as follows: @@ -217,3 +97,125 @@ networks: traefik: external: true ``` + +## Another webserver + +If you don't wish to use Traefik or `matrix-nginx-proxy`, you can also use your own webserver. + +Doing this is possible, but requires manual work. + +There are 2 ways to go about it: + +- (recommended) [Fronting the integrated reverse-proxy webserver with another reverse-proxy](#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy) - using a playbook-managed reverse-proxy (either `matrix-nginx-proxy` or Traefik), disabling SSL termination for it, exposing this reverse-proxy on a few local ports (e.g. `127.0.0.1:81`, etc.) and forwarding traffic from your own webserver to those few ports + +- (difficult) [Using no reverse-proxy on the Matrix side at all](#using-no-reverse-proxy-on-the-matrix-side-at-all) disabling all playbook-managed reverse-proxies (no `matrix-nginx-proxy`, no Traefik) + + +### Fronting the integrated reverse-proxy webserver with another reverse-proxy + +This method is about leaving the integrated reverse-proxy webserver be, but making it not get in the way (using up important ports, trying to retrieve SSL certificates, etc.). + +If you wish to use another webserver, the integrated nginx reverse-proxy webserver usually gets in the way because it attempts to fetch SSL certificates and binds to ports 80, 443 and 8448 (if Matrix Federation is enabled). + +You can disable such behavior and make the integrated reverse-proxy webserver only serve traffic locally (or over a local network). + +This is the recommended way for using another reverse-proxy, because the integrated one would act as a black box and wire all Matrix services correctly. You would only need to reverse-proxy a few individual domains and ports over to it. + +**For `matrix-nginx-proxy`** fronted by another reverse-proxy, you would need some configuration like this: + +```yaml +# playbook-managed-proxy is the default right now, so we can keep this commented out. +# matrix_playbook_reverse_proxy_type: playbook-managed-nginx + +# Disable SSL certificate retrieval +matrix_ssl_retrieval_method: none + +# Given that we won't be obtaining SSL certificates here, disable HTTPS +matrix_nginx_proxy_https_enabled: false + +# Do not listen for HTTP on port 80 globally (default), listen on the loopback interface. +# If you'd like, you can make it use the local network as well and reverse-proxy from another local machine. +matrix_nginx_proxy_container_http_host_bind_port: '127.0.0.1:81' + +# Likewise, expose the Matrix Federation port on the loopback interface. +# Since `matrix_nginx_proxy_https_enabled` is set to `false`, this federation port will serve HTTP traffic. +# If you'd like, you can make it use the local network as well and reverse-proxy from another local machine. +# +# You'd most likely need to expose it publicly on port 8448 (8449 was chosen for the local port to prevent overlap). +matrix_nginx_proxy_container_federation_host_bind_port: '127.0.0.1:8449' +``` + +**For Traefik** fronted by another reverse-proxy, you would need some configuration like this: + +```yaml +# playbook-managed-proxy is the default right now, so we can keep this commented out. +matrix_playbook_reverse_proxy_type: playbook-managed-traefik + +# Disable the web-secure (port 443) endpoint, which also disables SSL certificate retrieval +devture_traefik_config_entrypoint_web_secure_enabled: false + +devture_traefik_container_web_host_bind_port: '127.0.0.1:81' + +devture_traefik_additional_entrypoints_auto: + - name: matrix-federation + port: "{{ matrix_federation_public_port }}" + host_bind_port: "127.0.0.1:{{ matrix_federation_public_port }}" + config: {} +``` + +If you'll be fronting with a reverse-proxy that lives on another machine (not on the same one as Matrix), you need to replace `127.0.0.1` in the above configurations with `0.0.0.0` or another network interface. + +### Using no reverse-proxy on the Matrix side at all + +Instead of [Fronting the integrated reverse-proxy webserver with another reverse-proxy](#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy), you can also go another way -- completely disabling the playbook-managed reverse-proxy. You would then need to reverse-proxy from your own webserver directly to Matrix services. + +This is more difficult, as you would need to handle the configuration for each service manually. Enabling additional services would come with extra manual work you need to do. + +If your webserver is on the same machine, sure your web server user (something like `http`, `apache`, `www-data`, `nginx`) is part of the `matrix` group. You should run something like this: `usermod -a -G matrix nginx`. This allows your webserver user to access files owned by the `matrix` group. When using an external nginx webserver, this allows it to read configuration files from `/matrix/nginx-proxy/conf.d`. When using another server, it would make other files, such as `/matrix/static-files/.well-known`, accessible to it. + +#### Using your own nginx reverse-proxy running on the same machine + +If you'll be using `nginx` running on the same machine (not in a container), you can make the playbook help you generate configuration for `nginx` with this configuration: + +```yaml +matrix_playbook_reverse_proxy_type: other-nginx-non-container + +# If you will manage SSL certificates yourself, uncomment the line below +# matrix_ssl_retrieval_method: none + +# If you're using an old nginx version, consider using a custom protocol list +# (removing `TLSv1.3` that is enabled by default) to suit your nginx version. +# matrix_nginx_proxy_ssl_protocols: "TLSv1.2" +``` + +You can most likely directly use the config files installed by this playbook at: `/matrix/nginx-proxy/conf.d`. Just include them in your own `nginx.conf` like this: `include /matrix/nginx-proxy/conf.d/*.conf;` + +#### Using your own reverse-proxy running on the same machine or elsewhere + +To reverse-proxy manually for each service, use configuration like this: + +```yaml +# If your reverse-proxy runs on the same machine: +matrix_playbook_reverse_proxy_type: other-on-same-host + +# Or, if it runs on another machine: +# matrix_playbook_reverse_proxy_type: other-on-another-host + +# Or, optionally customize the network interface prefix (note the trailing `:` character). +# For other-on-same-host, the interface defaults to `127.0.0.1:`. +# For other-on-another-host, the interface defaults to `0.0.0.0:`. +# matrix_playbook_service_host_bind_interface_prefix: '192.168.30.4:' +``` + +With this configuration, each service will be exposed on a custom port. Example: + +- Synapse will be exposed on port `8008` +- [Grafana](configuring-playbook-prometheus-grafana.md) will be exposed on port `3000` +- [synapse-admin](configuring-playbook-synapse-admin.md) will be exposed on port `8766` + +You can capture traffic for these services and forward it to their port. +Some of these services are configured with certain default expecations with regard to hostname, path, etc., so it's not completely arbitrary where you can host them (unless you change the defaults). + +For each new playbook service that you enable, you'll need special handling. + +The [`examples/`](../examples/) directory contains examples for various servers: Caddy, Apache, HAproxy, etc.